diff --git a/app/src/main/java/com/github/droidworksstudio/common/FragmentExtensions.kt b/app/src/main/java/com/github/droidworksstudio/common/FragmentExtensions.kt index 5814d44..7815b32 100644 --- a/app/src/main/java/com/github/droidworksstudio/common/FragmentExtensions.kt +++ b/app/src/main/java/com/github/droidworksstudio/common/FragmentExtensions.kt @@ -28,10 +28,4 @@ fun Fragment.showLongToast(message: String) { fun Fragment.showShortToast(message: String) { Toast.makeText(requireContext(), message, Toast.LENGTH_SHORT).show() -} - -fun Fragment.restartApp() { - val intent = Intent(requireContext(), MainActivity::class.java) - intent.addFlags(Intent.FLAG_ACTIVITY_CLEAR_TOP or Intent.FLAG_ACTIVITY_NEW_TASK) - requireContext().startActivity(intent) } \ No newline at end of file diff --git a/app/src/main/java/com/github/droidworksstudio/launcher/Application.kt b/app/src/main/java/com/github/droidworksstudio/launcher/Application.kt index a52cd8c..eac1927 100644 --- a/app/src/main/java/com/github/droidworksstudio/launcher/Application.kt +++ b/app/src/main/java/com/github/droidworksstudio/launcher/Application.kt @@ -1,6 +1,11 @@ package com.github.droidworksstudio.launcher import android.app.Application +import android.content.Context +import android.graphics.Typeface +import android.os.Build +import androidx.annotation.RequiresApi +import com.github.droidworksstudio.launcher.helper.PreferenceHelper import dagger.hilt.android.HiltAndroidApp import org.acra.ACRA import org.acra.ReportField @@ -8,13 +13,21 @@ import org.acra.config.dialog import org.acra.config.mailSender import org.acra.data.StringFormat import org.acra.ktx.initAcra +import javax.inject.Inject @HiltAndroidApp class Application : Application() { + + @Inject + lateinit var preferenceHelper: PreferenceHelper + + @RequiresApi(Build.VERSION_CODES.O) override fun onCreate() { super.onCreate() + setCustomFont(applicationContext) + val pkgName = getString(R.string.app_name) val pkgVersion = this.packageManager.getPackageInfo( this.packageName, @@ -64,4 +77,31 @@ class Application : Application() { } } } + + @RequiresApi(Build.VERSION_CODES.O) + private fun setCustomFont(context: Context) { + // Load the custom font from resources + val customFont = preferenceHelper.launcherFont.getFont(context) + + // Apply the custom font to different font families + if (customFont != null) { + TypefaceUtil.setDefaultFont("DEFAULT", customFont) + TypefaceUtil.setDefaultFont("MONOSPACE", customFont) + TypefaceUtil.setDefaultFont("SERIF", customFont) + TypefaceUtil.setDefaultFont("SANS_SERIF", customFont) + } + } +} + +object TypefaceUtil { + + fun setDefaultFont(staticTypefaceFieldName: String, fontAssetName: Typeface) { + try { + val staticField = Typeface::class.java.getDeclaredField(staticTypefaceFieldName) + staticField.isAccessible = true + staticField.set(null, fontAssetName) + } catch (e: Exception) { + e.printStackTrace() + } + } } \ No newline at end of file diff --git a/app/src/main/java/com/github/droidworksstudio/launcher/adapter/font/FontAdapter.kt b/app/src/main/java/com/github/droidworksstudio/launcher/adapter/font/FontAdapter.kt new file mode 100644 index 0000000..b315610 --- /dev/null +++ b/app/src/main/java/com/github/droidworksstudio/launcher/adapter/font/FontAdapter.kt @@ -0,0 +1,48 @@ +package com.github.droidworksstudio.launcher.adapter.font + +import android.content.Context +import android.graphics.Typeface +import android.view.LayoutInflater +import android.view.View +import android.view.ViewGroup +import android.widget.ArrayAdapter +import android.widget.TextView +import androidx.core.content.res.ResourcesCompat +import com.github.droidworksstudio.launcher.R +import com.github.droidworksstudio.launcher.utils.Constants + +class FontAdapter( + context: Context, + private val items: Array, + private val itemStrings: Array +) : ArrayAdapter(context, android.R.layout.simple_list_item_1, itemStrings) { + + override fun getView(position: Int, convertView: View?, parent: ViewGroup): View { + val view = convertView ?: LayoutInflater.from(context).inflate(android.R.layout.simple_list_item_1, parent, false) + val textView = view.findViewById(android.R.id.text1) + + textView.text = itemStrings[position] + + // Set custom font based on the item + val typeface = getCustomTypefaceForItem(context, items[position]) + textView.typeface = typeface + + return view + } + + private fun getCustomTypefaceForItem(context: Context, item: Constants.Fonts): Typeface? { + return when (item) { + Constants.Fonts.Roboto -> ResourcesCompat.getFont(context, R.font.roboto) + Constants.Fonts.OpenSans -> ResourcesCompat.getFont(context, R.font.open_sans) + Constants.Fonts.Lato -> ResourcesCompat.getFont(context, R.font.lato) + Constants.Fonts.Montserrat -> ResourcesCompat.getFont(context, R.font.montserrat) + Constants.Fonts.Merriweather -> ResourcesCompat.getFont(context, R.font.montserrat) + Constants.Fonts.DroidSans -> ResourcesCompat.getFont(context, R.font.droid_sans) + Constants.Fonts.Raleway -> ResourcesCompat.getFont(context, R.font.open_sans) + Constants.Fonts.SourceCodePro -> ResourcesCompat.getFont(context, R.font.open_sans) + Constants.Fonts.Quicksand -> ResourcesCompat.getFont(context, R.font.quicksand) + // Add other fonts as needed + else -> Typeface.DEFAULT + } + } +} diff --git a/app/src/main/java/com/github/droidworksstudio/launcher/helper/AppReloader.kt b/app/src/main/java/com/github/droidworksstudio/launcher/helper/AppReloader.kt new file mode 100644 index 0000000..56d6b04 --- /dev/null +++ b/app/src/main/java/com/github/droidworksstudio/launcher/helper/AppReloader.kt @@ -0,0 +1,21 @@ +package com.github.droidworksstudio.launcher.helper + +import android.content.Context +import android.content.Intent +import android.os.Handler +import android.os.Looper + +object AppReloader { + fun restartApp(context: Context) { + val packageManager = context.packageManager + val intent = packageManager.getLaunchIntentForPackage(context.packageName) + val componentName = intent?.component + val mainIntent = Intent.makeRestartActivityTask(componentName) + + // Delay the restart slightly to ensure all current activities are finished + Handler(Looper.getMainLooper()).post { + context.startActivity(mainIntent) + Runtime.getRuntime().exit(0) + } + } +} \ No newline at end of file diff --git a/app/src/main/java/com/github/droidworksstudio/launcher/helper/PreferenceHelper.kt b/app/src/main/java/com/github/droidworksstudio/launcher/helper/PreferenceHelper.kt index c9a8d59..efd75cf 100644 --- a/app/src/main/java/com/github/droidworksstudio/launcher/helper/PreferenceHelper.kt +++ b/app/src/main/java/com/github/droidworksstudio/launcher/helper/PreferenceHelper.kt @@ -153,6 +153,21 @@ class PreferenceHelper @Inject constructor(@ApplicationContext context: Context) } set(value) = prefs.edit().putString(Constants.SEARCH_ENGINE, value.name).apply() + var launcherFont: Constants.Fonts + get() { + return try { + Constants.Fonts.valueOf( + prefs.getString( + Constants.LAUNCHER_FONT, + Constants.Fonts.System.name + ).toString() + ) + } catch (_: Exception) { + Constants.Fonts.System + } + } + set(value) = prefs.edit().putString(Constants.LAUNCHER_FONT, value.name).apply() + var swipeUpAction: Constants.Action get() = loadAction(Constants.SWIPE_UP_ACTION, Constants.Action.ShowRecents) set(value) = storeAction(Constants.SWIPE_UP_ACTION, value) diff --git a/app/src/main/java/com/github/droidworksstudio/launcher/ui/settings/SettingsFragment.kt b/app/src/main/java/com/github/droidworksstudio/launcher/ui/settings/SettingsFragment.kt index 14b1924..98f7162 100644 --- a/app/src/main/java/com/github/droidworksstudio/launcher/ui/settings/SettingsFragment.kt +++ b/app/src/main/java/com/github/droidworksstudio/launcher/ui/settings/SettingsFragment.kt @@ -4,19 +4,23 @@ import android.annotation.SuppressLint import android.content.Context import android.content.Intent import android.os.Bundle +import android.os.Handler +import android.os.Looper import android.view.LayoutInflater import android.view.View import android.view.ViewGroup +import androidx.appcompat.app.AlertDialog import androidx.fragment.app.Fragment import androidx.fragment.app.viewModels import androidx.navigation.NavController import androidx.navigation.fragment.findNavController import com.github.droidworksstudio.common.resetDefaultLauncher -import com.github.droidworksstudio.common.restartApp import com.github.droidworksstudio.launcher.utils.Constants import com.github.droidworksstudio.launcher.R +import com.github.droidworksstudio.launcher.adapter.font.FontAdapter import com.github.droidworksstudio.launcher.databinding.FragmentSettingsBinding import com.github.droidworksstudio.launcher.helper.AppHelper +import com.github.droidworksstudio.launcher.helper.AppReloader import com.github.droidworksstudio.launcher.helper.PreferenceHelper import com.github.droidworksstudio.launcher.listener.OnSwipeTouchListener import com.github.droidworksstudio.launcher.listener.ScrollEventListener @@ -80,6 +84,7 @@ class SettingsFragment : Fragment(), ) binding.miscellaneousSearchEngineControl.text = preferenceHelper.searchEngines.getString(context) + binding.miscellaneousLauncherFontsControl.text = preferenceHelper.launcherFont.getString(context) binding.gesturesDoubleTapControl.text = preferenceHelper.doubleTapAction.getString(context) binding.gesturesSwipeUpControl.text = preferenceHelper.swipeUpAction.getString(context) @@ -164,7 +169,7 @@ class SettingsFragment : Fragment(), binding.restoreView.setOnClickListener { appHelper.restoreSharedPreferences(requireContext()) - restartApp() + AppReloader.restartApp(context) } } @@ -215,6 +220,10 @@ class SettingsFragment : Fragment(), showSearchEngineDialog() } + binding.miscellaneousLauncherFontsControl.setOnClickListener { + showLauncherFontDialog() + } + binding.gesturesDoubleTapControl.setOnClickListener { swipeActionClickEvent(Constants.Swipe.DoubleTap) } @@ -251,24 +260,67 @@ class SettingsFragment : Fragment(), } } + private var searchEngineDialog: AlertDialog? = null + private fun showSearchEngineDialog() { + // Dismiss any existing dialog to prevent multiple dialogs open simultaneously + searchEngineDialog?.dismiss() // Get the array of SearchEngines enum values val items = Constants.SearchEngines.entries.toTypedArray() // Map the enum values to their string representations val itemStrings = items.map { it.getString(context) }.toTypedArray() - val dialog = MaterialAlertDialogBuilder(context) + val dialogBuilder = MaterialAlertDialogBuilder(context) - dialog.setTitle("Select a Search Engine") - dialog.setItems(itemStrings) { _, which -> + dialogBuilder.setTitle(getString(R.string.settings_select_search_engine)) + dialogBuilder.setItems(itemStrings) { _, which -> val selectedItem = items[which] preferenceViewModel.setSearchEngine(selectedItem) binding.miscellaneousSearchEngineControl.text = preferenceHelper.searchEngines.name } - dialog.show() + // Assign the created dialog to launcherFontDialog + searchEngineDialog = dialogBuilder.create() + searchEngineDialog?.show() } + private var launcherFontDialog: AlertDialog? = null + + private fun showLauncherFontDialog() { + // Dismiss any existing dialog to prevent multiple dialogs open simultaneously + launcherFontDialog?.dismiss() + + // Get the array of SearchEngines enum values + val items = Constants.Fonts.entries.toTypedArray() + + // Map the enum values to their string representations + val itemStrings = items.map { it.getString(context) }.toTypedArray() + + val dialogBuilder = MaterialAlertDialogBuilder(context) + dialogBuilder.setTitle(getString(R.string.settings_select_launcher_font)) + dialogBuilder.setAdapter(FontAdapter(context, items, itemStrings)) { _, which -> + val selectedItem = items[which] + preferenceViewModel.setLauncherFont(selectedItem) + binding.miscellaneousLauncherFontsControl.text = preferenceHelper.launcherFont.name + + // Delay the restart slightly to ensure preferences are saved + Handler(Looper.getMainLooper()).postDelayed({ + AppReloader.restartApp(context) + }, 500) // Delay in milliseconds (e.g., 500ms) + } + + // Assign the created dialog to launcherFontDialog + launcherFontDialog = dialogBuilder.create() + launcherFontDialog?.show() + } + + // Add this function to dismiss the dialog if it's showing + private fun dismissDialogs() { + launcherFontDialog?.dismiss() + searchEngineDialog?.dismiss() + } + + private fun swipeActionClickEvent(swipe: Constants.Swipe) { // Get the array of Action enum values val actions = Constants.Action.entries.toTypedArray() @@ -319,4 +371,10 @@ class SettingsFragment : Fragment(), } dialog.show() } + + override fun onStop() { + super.onStop() + dismissDialogs() + } + } \ No newline at end of file diff --git a/app/src/main/java/com/github/droidworksstudio/launcher/utils/Constants.kt b/app/src/main/java/com/github/droidworksstudio/launcher/utils/Constants.kt index 01af408..042c53c 100644 --- a/app/src/main/java/com/github/droidworksstudio/launcher/utils/Constants.kt +++ b/app/src/main/java/com/github/droidworksstudio/launcher/utils/Constants.kt @@ -1,6 +1,8 @@ package com.github.droidworksstudio.launcher.utils import android.content.Context +import android.graphics.Typeface +import androidx.core.content.res.ResourcesCompat import com.github.droidworksstudio.launcher.R object Constants { @@ -75,6 +77,8 @@ object Constants { const val URL_GOOGLE_PLAY_STORE = "https://play.google.com/store/search?c=apps&q" const val APP_GOOGLE_PLAY_STORE = "market://search?c=apps&q" + const val LAUNCHER_FONT = "LAUNCHER_FONT" + const val REQUEST_INSTALL_PERMISSION = 123 const val REQUEST_LOCATION_PERMISSION_CODE = 246 @@ -158,4 +162,47 @@ object Constants { } } } + + enum class Fonts { + System, + Roboto, + OpenSans, + Lato, + Montserrat, + Merriweather, + DroidSans, + Raleway, + SourceCodePro, + Quicksand; + + fun getFont(context: Context): Typeface? { + return when (this) { + System -> Typeface.DEFAULT + Roboto -> ResourcesCompat.getFont(context, R.font.roboto) + OpenSans -> ResourcesCompat.getFont(context, R.font.open_sans) + Lato -> ResourcesCompat.getFont(context, R.font.lato) + Montserrat -> ResourcesCompat.getFont(context, R.font.montserrat) + Merriweather -> ResourcesCompat.getFont(context, R.font.merriweather) + DroidSans -> ResourcesCompat.getFont(context, R.font.open_sans) + Raleway -> ResourcesCompat.getFont(context, R.font.raleway) + SourceCodePro -> ResourcesCompat.getFont(context, R.font.source_code_pro) + Quicksand -> ResourcesCompat.getFont(context, R.font.quicksand) + } + } + + fun getString(context: Context): String { + return when (this) { + System -> context.getString(R.string.settings_font_system) + Roboto -> context.getString(R.string.settings_font_roboto) + OpenSans -> context.getString(R.string.settings_font_opensans) + Lato -> context.getString(R.string.settings_font_lato) + Montserrat -> context.getString(R.string.settings_font_montserrat) + Merriweather -> context.getString(R.string.settings_font_merriweather) + DroidSans -> context.getString(R.string.settings_font_droidsans) + Raleway -> context.getString(R.string.settings_font_raleway) + SourceCodePro -> context.getString(R.string.settings_font_sourcecodepro) + Quicksand -> context.getString(R.string.settings_font_quicksand) + } + } + } } \ No newline at end of file diff --git a/app/src/main/java/com/github/droidworksstudio/launcher/viewmodel/PreferenceViewModel.kt b/app/src/main/java/com/github/droidworksstudio/launcher/viewmodel/PreferenceViewModel.kt index 4f47d33..b0fa4ca 100644 --- a/app/src/main/java/com/github/droidworksstudio/launcher/viewmodel/PreferenceViewModel.kt +++ b/app/src/main/java/com/github/droidworksstudio/launcher/viewmodel/PreferenceViewModel.kt @@ -46,6 +46,7 @@ class PreferenceViewModel @Inject constructor( private val batteryOrderNumberLiveData: MutableLiveData = MutableLiveData() private val searchEngineLiveData: MutableLiveData = MutableLiveData() + private val launcherFontLiveData: MutableLiveData = MutableLiveData() private val doubleTapActionLiveData: MutableLiveData = MutableLiveData() private val swipeUpActionLiveData: MutableLiveData = MutableLiveData() private val swipeDownActionLiveData: MutableLiveData = MutableLiveData() @@ -236,4 +237,9 @@ class PreferenceViewModel @Inject constructor( preferenceHelper.searchEngines = searchEngine searchEngineLiveData.postValue((preferenceHelper.searchEngines)) } + + fun setLauncherFont(launcherFont: Constants.Fonts) { + preferenceHelper.launcherFont = launcherFont + launcherFontLiveData.postValue((preferenceHelper.launcherFont)) + } } \ No newline at end of file diff --git a/app/src/main/res/font/droid_sans.ttf b/app/src/main/res/font/droid_sans.ttf new file mode 100644 index 0000000..ad1efca Binary files /dev/null and b/app/src/main/res/font/droid_sans.ttf differ diff --git a/app/src/main/res/font/lato.ttf b/app/src/main/res/font/lato.ttf new file mode 100644 index 0000000..bb2e887 Binary files /dev/null and b/app/src/main/res/font/lato.ttf differ diff --git a/app/src/main/res/font/merriweather.ttf b/app/src/main/res/font/merriweather.ttf new file mode 100644 index 0000000..3e10e02 Binary files /dev/null and b/app/src/main/res/font/merriweather.ttf differ diff --git a/app/src/main/res/font/montserrat.ttf b/app/src/main/res/font/montserrat.ttf new file mode 100644 index 0000000..f4a266d Binary files /dev/null and b/app/src/main/res/font/montserrat.ttf differ diff --git a/app/src/main/res/font/open_sans.ttf b/app/src/main/res/font/open_sans.ttf new file mode 100644 index 0000000..ac587b4 Binary files /dev/null and b/app/src/main/res/font/open_sans.ttf differ diff --git a/app/src/main/res/font/quicksand.ttf b/app/src/main/res/font/quicksand.ttf new file mode 100644 index 0000000..60323ed Binary files /dev/null and b/app/src/main/res/font/quicksand.ttf differ diff --git a/app/src/main/res/font/raleway.ttf b/app/src/main/res/font/raleway.ttf new file mode 100644 index 0000000..774b382 Binary files /dev/null and b/app/src/main/res/font/raleway.ttf differ diff --git a/app/src/main/res/font/roboto.ttf b/app/src/main/res/font/roboto.ttf new file mode 100644 index 0000000..ddf4bfa Binary files /dev/null and b/app/src/main/res/font/roboto.ttf differ diff --git a/app/src/main/res/font/source_code_pro.ttf b/app/src/main/res/font/source_code_pro.ttf new file mode 100644 index 0000000..b1fa336 Binary files /dev/null and b/app/src/main/res/font/source_code_pro.ttf differ diff --git a/app/src/main/res/layout/fragment_settings.xml b/app/src/main/res/layout/fragment_settings.xml index 54c27ff..e6500de 100644 --- a/app/src/main/res/layout/fragment_settings.xml +++ b/app/src/main/res/layout/fragment_settings.xml @@ -566,6 +566,39 @@ tools:ignore="RtlHardcoded" /> + + + + + + + + @@ -71,6 +79,8 @@ \ No newline at end of file diff --git a/app/src/main/res/values/nontranslatable.xml b/app/src/main/res/values/nontranslatable.xml index 88b1a1a..43dd694 100644 --- a/app/src/main/res/values/nontranslatable.xml +++ b/app/src/main/res/values/nontranslatable.xml @@ -24,4 +24,14 @@ Pressure : %d hPa droidworksstudio@063240.xyz + + Roboto + Open Sans + Lato + Montserrat + Merriweather + Droid Sans + Raleway + SourceCodePro + Quicksand \ No newline at end of file diff --git a/app/src/main/res/values/strings.xml b/app/src/main/res/values/strings.xml index 5772a13..2ef854f 100644 --- a/app/src/main/res/values/strings.xml +++ b/app/src/main/res/values/strings.xml @@ -85,8 +85,12 @@ Swipe Left Swipe Right + Select a Search Engine Search Engine + Select a Font Family + Font Family + Share Feedback Github @@ -113,6 +117,8 @@ Metric Imperial + System + Authentication Log in using your biometric credentials. Authentication Cancel diff --git a/app/src/main/res/values/styles.xml b/app/src/main/res/values/styles.xml index 9b3210d..8971ffb 100644 --- a/app/src/main/res/values/styles.xml +++ b/app/src/main/res/values/styles.xml @@ -2,6 +2,8 @@ @@ -71,6 +79,8 @@ \ No newline at end of file