Skip to content
Open
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
Original file line number Diff line number Diff line change
@@ -0,0 +1,79 @@
package be.robinj.distrohopper.preferences

import android.content.DialogInterface
import android.graphics.Typeface
import android.os.Bundle
import android.view.View
import android.view.ViewGroup
import android.widget.ArrayAdapter
import android.widget.TextView
import androidx.appcompat.app.AlertDialog
import androidx.preference.ListPreference

/**
* The Appearance font picker. Behaves like the framework's list-preference dialog
* (single-choice, tap-to-select-and-dismiss) but renders each option in the font
* it names — the "Ubuntu" row is drawn in Ubuntu, "Oxygen" in Oxygen, and so on —
* so the user previews each font while choosing it. "System default" keeps the
* device font.
*
* We can't just let the base class build the list because it wires up a private
* clicked-index field we can't reach, so this replicates its select-and-persist
* flow with a custom adapter (see [onPrepareDialogBuilder] / [onDialogClosed]).
* Extends the frosted variant so the legibility fallback is preserved.
*/
class FontListPreferenceDialogFragment :
PreferencesActivity.FrostedListPreferenceDialogFragment() {

private var clickedIndex = -1

override fun onPrepareDialogBuilder(builder: AlertDialog.Builder) {
val listPreference = this.preference as ListPreference
val entries = listPreference.entries
val entryValues = listPreference.entryValues
this.clickedIndex = listPreference.findIndexOfValue(listPreference.value)

val adapter = object : ArrayAdapter<CharSequence>(
this.requireContext(),
android.R.layout.select_dialog_singlechoice,
android.R.id.text1,
entries,
) {
override fun getView(position: Int, convertView: View?, parent: ViewGroup): View {
val view = super.getView(position, convertView, parent)
val textView = view.findViewById<TextView>(android.R.id.text1)
textView.typeface =
FontPreference.typefaceFor(this.context, entryValues[position]?.toString())
?: Typeface.DEFAULT
return view
}
}

// Mirror ListPreferenceDialogFragmentCompat: tapping a row selects it and
// immediately closes with a positive result (no separate OK button). //
builder.setSingleChoiceItems(adapter, this.clickedIndex) { dialog, which ->
this.clickedIndex = which
this.onClick(dialog, DialogInterface.BUTTON_POSITIVE)
dialog.dismiss()
}
builder.setPositiveButton(null, null)
}

override fun onDialogClosed(positiveResult: Boolean) {
if (positiveResult && this.clickedIndex >= 0) {
val listPreference = this.preference as ListPreference
val value = listPreference.entryValues[this.clickedIndex].toString()
if (listPreference.callChangeListener(value)) {
listPreference.value = value
}
}
}

companion object {
fun newInstance(key: String): FontListPreferenceDialogFragment {
val fragment = FontListPreferenceDialogFragment()
fragment.arguments = Bundle(1).apply { this.putString("key", key) }
return fragment
}
}
}
Original file line number Diff line number Diff line change
Expand Up @@ -42,6 +42,17 @@ object FontPreference {
return ResourcesCompat.getFont(context, fontRes)
}

/**
* The [Typeface] for a given font preference [value], or null when [value] is
* System / unknown (i.e. the system font should be used). Unlike [typeface]
* this ignores the stored preference and resolves whatever value is passed,
* so the picker can render each option in its own font.
*/
fun typefaceFor(context: Context, value: String?): Typeface? {
val fontRes = this.fontResFor(value) ?: return null
return ResourcesCompat.getFont(context, fontRes)
}

private fun current(context: Context): String =
Preferences.getSharedPreferences(context)
.getString(Preference.FONT.getName(), SYSTEM) ?: SYSTEM
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -322,8 +322,13 @@ public void onDisplayPreferenceDialog (final Preference preference)

if (preference instanceof ListPreference)
{
// The font picker previews each option in its own font; every other
// list preference uses the plain frosted dialog. //
final DialogFragment fragment =
FrostedListPreferenceDialogFragment.newInstance (preference.getKey ());
be.robinj.distrohopper.preferences.Preference.FONT.getName ()
.equals (preference.getKey ())
? FontListPreferenceDialogFragment.newInstance (preference.getKey ())
: FrostedListPreferenceDialogFragment.newInstance (preference.getKey ());
fragment.setTargetFragment (this, 0);
fragment.show (this.getParentFragmentManager (), DIALOG_FRAGMENT_TAG);
}
Expand Down
Loading