allow setting background image for landscape and portrait separately

fixes #798
This commit is contained in:
Helium314 2025-01-17 20:10:16 +01:00
parent 71d17f6792
commit c581e9601b
5 changed files with 58 additions and 33 deletions

View file

@ -163,12 +163,12 @@ private fun upgradesWhenComingFromOldAppName(context: Context) {
try { try {
val bgDay = File(context.filesDir, "custom_background_image") val bgDay = File(context.filesDir, "custom_background_image")
if (bgDay.isFile) { if (bgDay.isFile) {
bgDay.copyTo(Settings.getCustomBackgroundFile(context, false), true) bgDay.copyTo(Settings.getCustomBackgroundFile(context, false, false), true)
bgDay.delete() bgDay.delete()
} }
val bgNight = File(context.filesDir, "custom_background_image_night") val bgNight = File(context.filesDir, "custom_background_image_night")
if (bgNight.isFile) { if (bgNight.isFile) {
bgNight.copyTo(Settings.getCustomBackgroundFile(context, true), true) bgNight.copyTo(Settings.getCustomBackgroundFile(context, true, false), true)
bgNight.delete() bgNight.delete()
} }
} catch (_: Exception) {} } catch (_: Exception) {}

View file

@ -65,13 +65,25 @@ class AppearanceSettingsFragment : SubScreenFragment() {
private val dayImageFilePicker = registerForActivityResult(ActivityResultContracts.StartActivityForResult()) { private val dayImageFilePicker = registerForActivityResult(ActivityResultContracts.StartActivityForResult()) {
if (it.resultCode != Activity.RESULT_OK) return@registerForActivityResult if (it.resultCode != Activity.RESULT_OK) return@registerForActivityResult
val uri = it.data?.data ?: return@registerForActivityResult val uri = it.data?.data ?: return@registerForActivityResult
loadImage(uri, false) loadImage(uri, false, false)
} }
private val nightImageFilePicker = registerForActivityResult(ActivityResultContracts.StartActivityForResult()) { private val nightImageFilePicker = registerForActivityResult(ActivityResultContracts.StartActivityForResult()) {
if (it.resultCode != Activity.RESULT_OK) return@registerForActivityResult if (it.resultCode != Activity.RESULT_OK) return@registerForActivityResult
val uri = it.data?.data ?: return@registerForActivityResult val uri = it.data?.data ?: return@registerForActivityResult
loadImage(uri, true) loadImage(uri, true, false)
}
private val dayImageFilePickerLandscape = registerForActivityResult(ActivityResultContracts.StartActivityForResult()) {
if (it.resultCode != Activity.RESULT_OK) return@registerForActivityResult
val uri = it.data?.data ?: return@registerForActivityResult
loadImage(uri, false, true)
}
private val nightImageFilePickerLandscape = registerForActivityResult(ActivityResultContracts.StartActivityForResult()) {
if (it.resultCode != Activity.RESULT_OK) return@registerForActivityResult
val uri = it.data?.data ?: return@registerForActivityResult
loadImage(uri, true, true)
} }
override fun onCreate(savedInstanceState: Bundle?) { override fun onCreate(savedInstanceState: Bundle?) {
@ -92,7 +104,8 @@ class AppearanceSettingsFragment : SubScreenFragment() {
true true
} }
} }
findPreference<Preference>("custom_background_image")?.setOnPreferenceClickListener { onClickLoadImage() } findPreference<Preference>("custom_background_image")?.setOnPreferenceClickListener { onClickLoadImage(false) }
findPreference<Preference>("custom_background_image_landscape")?.setOnPreferenceClickListener { onClickLoadImage(true) }
findPreference<Preference>(Settings.PREF_CUSTOM_ICON_NAMES)?.setOnPreferenceClickListener { findPreference<Preference>(Settings.PREF_CUSTOM_ICON_NAMES)?.setOnPreferenceClickListener {
if (needsReload) if (needsReload)
KeyboardSwitcher.getInstance().forceUpdateKeyboardTheme(requireContext()) KeyboardSwitcher.getInstance().forceUpdateKeyboardTheme(requireContext())
@ -322,30 +335,35 @@ class AppearanceSettingsFragment : SubScreenFragment() {
builder.show() builder.show()
} }
private fun onClickLoadImage(): Boolean { private fun onClickLoadImage(landscape: Boolean): Boolean {
if (Settings.readDayNightPref(sharedPreferences, resources)) { if (Settings.readDayNightPref(sharedPreferences, resources)) {
AlertDialog.Builder(requireContext()) AlertDialog.Builder(requireContext())
.setMessage(R.string.day_or_night_image) .setTitle(R.string.day_or_night_image)
.setPositiveButton(R.string.day_or_night_day) { _, _ -> customImageDialog(false) } .setPositiveButton(R.string.day_or_night_day) { _, _ -> customImageDialog(false, landscape) }
.setNegativeButton(R.string.day_or_night_night) { _, _ -> customImageDialog(true) } .setNegativeButton(R.string.day_or_night_night) { _, _ -> customImageDialog(true, landscape) }
.setNeutralButton(android.R.string.cancel, null) .setNeutralButton(android.R.string.cancel, null)
.show() .show()
} else { } else {
customImageDialog(false) customImageDialog(false, landscape)
} }
return true return true
} }
private fun customImageDialog(night: Boolean) { private fun customImageDialog(night: Boolean, landscape: Boolean) {
val imageFile = Settings.getCustomBackgroundFile(requireContext(), night) val imageFile = Settings.getCustomBackgroundFile(requireContext(), night, landscape)
val builder = AlertDialog.Builder(requireContext()) val builder = AlertDialog.Builder(requireContext())
.setMessage(R.string.customize_background_image) .setMessage(if (landscape) R.string.customize_background_image_landscape else R.string.customize_background_image)
.setPositiveButton(R.string.button_load_custom) { _, _ -> .setPositiveButton(R.string.button_load_custom) { _, _ ->
val intent = Intent(Intent.ACTION_OPEN_DOCUMENT) val intent = Intent(Intent.ACTION_OPEN_DOCUMENT)
.addCategory(Intent.CATEGORY_OPENABLE) .addCategory(Intent.CATEGORY_OPENABLE)
.setType("image/*") .setType("image/*")
if (night) nightImageFilePicker.launch(intent) if (landscape) {
else dayImageFilePicker.launch(intent) if (night) nightImageFilePickerLandscape.launch(intent)
else dayImageFilePickerLandscape.launch(intent)
} else {
if (night) nightImageFilePicker.launch(intent)
else dayImageFilePicker.launch(intent)
}
} }
.setNegativeButton(android.R.string.cancel, null) .setNegativeButton(android.R.string.cancel, null)
if (imageFile.exists()) { if (imageFile.exists()) {
@ -358,8 +376,8 @@ class AppearanceSettingsFragment : SubScreenFragment() {
builder.show() builder.show()
} }
private fun loadImage(uri: Uri, night: Boolean) { private fun loadImage(uri: Uri, night: Boolean, landscape: Boolean) {
val imageFile = Settings.getCustomBackgroundFile(requireContext(), night) val imageFile = Settings.getCustomBackgroundFile(requireContext(), night, landscape)
FileUtils.copyContentUriToNewFile(uri, requireContext(), imageFile) FileUtils.copyContentUriToNewFile(uri, requireContext(), imageFile)
try { try {
BitmapFactory.decodeFile(imageFile.absolutePath) BitmapFactory.decodeFile(imageFile.absolutePath)

View file

@ -49,6 +49,7 @@ import helium314.keyboard.latin.utils.ToolbarUtilsKt;
import java.io.File; import java.io.File;
import java.util.ArrayList; import java.util.ArrayList;
import java.util.Arrays;
import java.util.HashSet; import java.util.HashSet;
import java.util.List; import java.util.List;
import java.util.Locale; import java.util.Locale;
@ -194,8 +195,7 @@ public final class Settings implements SharedPreferences.OnSharedPreferenceChang
private final ReentrantLock mSettingsValuesLock = new ReentrantLock(); private final ReentrantLock mSettingsValuesLock = new ReentrantLock();
// static cache for background images to avoid potentially slow reload on every settings reload // static cache for background images to avoid potentially slow reload on every settings reload
private static Drawable sCachedBackgroundDay; private final static Drawable[] sCachedBackgroundImages = new Drawable[4];
private static Drawable sCachedBackgroundNight;
private Map<String, Integer> mCustomToolbarKeyCodes = null; private Map<String, Integer> mCustomToolbarKeyCodes = null;
private Map<String, Integer> mCustomToolbarLongpressCodes = null; private Map<String, Integer> mCustomToolbarLongpressCodes = null;
@ -562,25 +562,24 @@ public final class Settings implements SharedPreferences.OnSharedPreferenceChang
} }
@Nullable public static Drawable readUserBackgroundImage(final Context context, final boolean night) { @Nullable public static Drawable readUserBackgroundImage(final Context context, final boolean night) {
if (night && sCachedBackgroundNight != null) return sCachedBackgroundNight; final boolean landscape = context.getResources().getConfiguration().orientation == Configuration.ORIENTATION_LANDSCAPE;
if (!night && sCachedBackgroundDay != null) return sCachedBackgroundDay; final int index = (night ? 1 : 0) + (landscape ? 2 : 0);
final File image = getCustomBackgroundFile(context, night); if (sCachedBackgroundImages[index] != null) return sCachedBackgroundImages[index];
File image = getCustomBackgroundFile(context, night, landscape);
if (!image.isFile() && landscape)
image = getCustomBackgroundFile(context, night, false); // fall back to portrait image for historic reasons
if (!image.isFile()) return null; if (!image.isFile()) return null;
try { try {
if (night) { sCachedBackgroundImages[index] = new BitmapDrawable(context.getResources(), BitmapFactory.decodeFile(image.getAbsolutePath()));
sCachedBackgroundNight = new BitmapDrawable(context.getResources(), BitmapFactory.decodeFile(image.getAbsolutePath())); return sCachedBackgroundImages[index];
return sCachedBackgroundNight;
} else {
sCachedBackgroundDay = new BitmapDrawable(context.getResources(), BitmapFactory.decodeFile(image.getAbsolutePath()));
return sCachedBackgroundDay;
}
} catch (Exception e) { } catch (Exception e) {
return null; return null;
} }
} }
public static File getCustomBackgroundFile(final Context context, final boolean night) { public static File getCustomBackgroundFile(final Context context, final boolean night, final boolean landscape) {
return new File(DeviceProtectedUtils.getFilesDir(context), "custom_background_image" + (night ? "_night" : "")); return new File(DeviceProtectedUtils.getFilesDir(context), "custom_background_image" + (landscape ? "_landscape" : "") + (night ? "_night" : ""));
} }
public static boolean readDayNightPref(final SharedPreferences prefs, final Resources res) { public static boolean readDayNightPref(final SharedPreferences prefs, final Resources res) {
@ -588,8 +587,7 @@ public final class Settings implements SharedPreferences.OnSharedPreferenceChang
} }
public static void clearCachedBackgroundImages() { public static void clearCachedBackgroundImages() {
sCachedBackgroundDay = null; Arrays.fill(sCachedBackgroundImages, null);
sCachedBackgroundNight = null;
} }
public static List<Locale> getSecondaryLocales(final SharedPreferences prefs, final Locale mainLocale) { public static List<Locale> getSecondaryLocales(final SharedPreferences prefs, final Locale mainLocale) {

View file

@ -550,6 +550,10 @@ disposition rather than other common dispositions for Latin languages. [CHAR LIM
<string name="layout_clip_bottom_row" tools:keep="@string/layout_clip_bottom_row">Clipboard bottom row</string> <string name="layout_clip_bottom_row" tools:keep="@string/layout_clip_bottom_row">Clipboard bottom row</string>
<!-- Title for customizing background image --> <!-- Title for customizing background image -->
<string name="customize_background_image">Set background image</string> <string name="customize_background_image">Set background image</string>
<!-- Title for customizing background image in landscape mode -->
<string name="customize_background_image_landscape">Set background image (landscape)</string>
<!-- Description for customize_background_image_landscape -->
<string name="summary_customize_background_image_landscape">If not set, portrait image will be used</string>
<!-- Title for customizing currencies --> <!-- Title for customizing currencies -->
<string name="customize_currencies">Customize currencies</string> <string name="customize_currencies">Customize currencies</string>
<!-- Info for customizing currencies --> <!-- Info for customizing currencies -->

View file

@ -71,6 +71,11 @@
android:key="custom_background_image" android:key="custom_background_image"
android:title="@string/customize_background_image" /> android:title="@string/customize_background_image" />
<Preference
android:key="custom_background_image_landscape"
android:title="@string/customize_background_image_landscape"
android:summary="@string/summary_customize_background_image_landscape"/>
</PreferenceCategory> </PreferenceCategory>
<PreferenceCategory <PreferenceCategory