From 78cf59c90cf59c64da01be089f22cd07aae7d1be Mon Sep 17 00:00:00 2001 From: OMGeeky Date: Mon, 28 Jul 2025 18:00:54 +0200 Subject: [PATCH 01/21] Updated full screen flag for API 30+ --- .../AndorsTrail/AndorsTrailApplication.java | 21 ++++++++++++++++--- 1 file changed, 18 insertions(+), 3 deletions(-) diff --git a/AndorsTrail/app/src/main/java/com/gpl/rpg/AndorsTrail/AndorsTrailApplication.java b/AndorsTrail/app/src/main/java/com/gpl/rpg/AndorsTrail/AndorsTrailApplication.java index 287b694f8..9ba84b366 100644 --- a/AndorsTrail/app/src/main/java/com/gpl/rpg/AndorsTrail/AndorsTrailApplication.java +++ b/AndorsTrail/app/src/main/java/com/gpl/rpg/AndorsTrail/AndorsTrailApplication.java @@ -15,8 +15,11 @@ import android.app.Application; import android.content.Context; import android.content.res.Configuration; import android.content.res.Resources; +import android.os.Build; import android.os.Environment; import android.view.Window; +import android.view.WindowInsets; +import android.view.WindowInsetsController; import android.view.WindowManager; public final class AndorsTrailApplication extends Application { @@ -57,10 +60,22 @@ public final class AndorsTrailApplication extends Application { public void setWindowParameters(Activity activity) { activity.requestWindowFeature(Window.FEATURE_NO_TITLE); - if (preferences.fullscreen) { - activity.getWindow().setFlags(WindowManager.LayoutParams.FLAG_FULLSCREEN, WindowManager.LayoutParams.FLAG_FULLSCREEN); + if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.R) { + final WindowInsetsController insetsController = activity.getWindow().getInsetsController(); + if (insetsController != null) { + if (preferences.fullscreen) { + insetsController.hide(WindowInsets.Type.statusBars()); + } else { + insetsController.show(WindowInsets.Type.statusBars()); + } + } } else { - activity.getWindow().setFlags(0, WindowManager.LayoutParams.FLAG_FULLSCREEN); + if (preferences.fullscreen) { + activity.getWindow().setFlags(WindowManager.LayoutParams.FLAG_FULLSCREEN, WindowManager.LayoutParams.FLAG_FULLSCREEN); + + } else { + activity.getWindow().setFlags(0, WindowManager.LayoutParams.FLAG_FULLSCREEN); + } } } From 57f7a0dc91653301bc8198bd251cc211472bd0a2 Mon Sep 17 00:00:00 2001 From: OMGeeky Date: Mon, 28 Jul 2025 18:06:43 +0200 Subject: [PATCH 02/21] Refactor fullscreen mode setting Move fullscreen mode setting logic into a static method in AndorsTrailApplication and use it in Preferences and CustomDialogFactory. --- .../rpg/AndorsTrail/AndorsTrailApplication.java | 14 +++++++++----- .../gpl/rpg/AndorsTrail/activity/Preferences.java | 7 ++----- .../rpg/AndorsTrail/view/CustomDialogFactory.java | 6 +----- 3 files changed, 12 insertions(+), 15 deletions(-) diff --git a/AndorsTrail/app/src/main/java/com/gpl/rpg/AndorsTrail/AndorsTrailApplication.java b/AndorsTrail/app/src/main/java/com/gpl/rpg/AndorsTrail/AndorsTrailApplication.java index 9ba84b366..eedfce2c8 100644 --- a/AndorsTrail/app/src/main/java/com/gpl/rpg/AndorsTrail/AndorsTrailApplication.java +++ b/AndorsTrail/app/src/main/java/com/gpl/rpg/AndorsTrail/AndorsTrailApplication.java @@ -60,21 +60,25 @@ public final class AndorsTrailApplication extends Application { public void setWindowParameters(Activity activity) { activity.requestWindowFeature(Window.FEATURE_NO_TITLE); + setFullscreenMode(preferences.fullscreen, activity.getWindow()); + } + + public static void setFullscreenMode(boolean fullscreen, Window window) { if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.R) { - final WindowInsetsController insetsController = activity.getWindow().getInsetsController(); + final WindowInsetsController insetsController = window.getInsetsController(); if (insetsController != null) { - if (preferences.fullscreen) { + if (fullscreen) { insetsController.hide(WindowInsets.Type.statusBars()); } else { insetsController.show(WindowInsets.Type.statusBars()); } } } else { - if (preferences.fullscreen) { - activity.getWindow().setFlags(WindowManager.LayoutParams.FLAG_FULLSCREEN, WindowManager.LayoutParams.FLAG_FULLSCREEN); + if (fullscreen) { + window.setFlags(WindowManager.LayoutParams.FLAG_FULLSCREEN, WindowManager.LayoutParams.FLAG_FULLSCREEN); } else { - activity.getWindow().setFlags(0, WindowManager.LayoutParams.FLAG_FULLSCREEN); + window.setFlags(0, WindowManager.LayoutParams.FLAG_FULLSCREEN); } } } diff --git a/AndorsTrail/app/src/main/java/com/gpl/rpg/AndorsTrail/activity/Preferences.java b/AndorsTrail/app/src/main/java/com/gpl/rpg/AndorsTrail/activity/Preferences.java index c524089cd..83957feaf 100644 --- a/AndorsTrail/app/src/main/java/com/gpl/rpg/AndorsTrail/activity/Preferences.java +++ b/AndorsTrail/app/src/main/java/com/gpl/rpg/AndorsTrail/activity/Preferences.java @@ -16,11 +16,8 @@ public final class Preferences extends PreferenceActivity { requestWindowFeature(Window.FEATURE_NO_TITLE); super.onCreate(savedInstanceState); AndorsTrailApplication app = AndorsTrailApplication.getApplicationFromActivity(this); - if (app.getPreferences().fullscreen) { - getWindow().setFlags(WindowManager.LayoutParams.FLAG_FULLSCREEN, WindowManager.LayoutParams.FLAG_FULLSCREEN); - } else { - getWindow().setFlags(0, WindowManager.LayoutParams.FLAG_FULLSCREEN); - } + AndorsTrailApplication.setFullscreenMode(app.getPreferences().fullscreen, getWindow()); + app.setLocale(this); addPreferencesFromResource(R.xml.preferences); diff --git a/AndorsTrail/app/src/main/java/com/gpl/rpg/AndorsTrail/view/CustomDialogFactory.java b/AndorsTrail/app/src/main/java/com/gpl/rpg/AndorsTrail/view/CustomDialogFactory.java index fb1de0977..942258691 100644 --- a/AndorsTrail/app/src/main/java/com/gpl/rpg/AndorsTrail/view/CustomDialogFactory.java +++ b/AndorsTrail/app/src/main/java/com/gpl/rpg/AndorsTrail/view/CustomDialogFactory.java @@ -76,11 +76,7 @@ public class CustomDialogFactory { dialog.requestWindowFeature(Window.FEATURE_NO_TITLE); dialog.setContentView(R.layout.custom_dialog_title_icon); dialog.getWindow().setBackgroundDrawableResource(android.R.color.transparent); - if (((AndorsTrailApplication)context.getApplicationContext()).getPreferences().fullscreen) { - dialog.getWindow().setFlags(WindowManager.LayoutParams.FLAG_FULLSCREEN, WindowManager.LayoutParams.FLAG_FULLSCREEN); - } else { - dialog.getWindow().setFlags(0, WindowManager.LayoutParams.FLAG_FULLSCREEN); - } + AndorsTrailApplication.setFullscreenMode(((AndorsTrailApplication)context.getApplicationContext()).getPreferences().fullscreen, dialog.getWindow()); setTitle(dialog, title, icon); From 8a74ffd2ef88ea7626d6395acf2d515a620ccb35 Mon Sep 17 00:00:00 2001 From: OMGeeky Date: Mon, 28 Jul 2025 21:01:11 +0200 Subject: [PATCH 03/21] Add Python script to check format specifier consistency in Android strings This script, `check_format_specifiers.py`, helps ensure that format specifiers (like `%s`, `%d`, `%1$s`) are used consistently across different language versions of a string resource in an Android project. --- AndorsTrail/tools/check_format_specifiers.py | 183 +++++++++++++++++++ 1 file changed, 183 insertions(+) create mode 100644 AndorsTrail/tools/check_format_specifiers.py diff --git a/AndorsTrail/tools/check_format_specifiers.py b/AndorsTrail/tools/check_format_specifiers.py new file mode 100644 index 000000000..f4e90382e --- /dev/null +++ b/AndorsTrail/tools/check_format_specifiers.py @@ -0,0 +1,183 @@ +import re +import os +import argparse +from xml.etree import ElementTree as ET + +def get_string_value_and_specifiers(filepath, key_name): + """ + Parses an XML strings file to find a specific key and its format specifiers. + + Args: + filepath (str): Path to the strings.xml file. + key_name (str): The name of the string resource to find. + + Returns: + tuple: (string_value, set_of_specifiers) or (None, None) if key not found. + Specifiers are returned as a set, e.g., {"%1$s", "%2$d"}. + """ + try: + tree = ET.parse(filepath) + root = tree.getroot() + for string_tag in root.findall('string'): + if string_tag.get('name') == key_name: + value = string_tag.text if string_tag.text else "" + # Regex to find format specifiers like %s, %d, %1$s, %2$d, etc. + # It handles optional positional arguments (e.g., 1$) and type characters. + specifiers = set(re.findall(r'%(?:(?:\d+\$)?(?:[sdfeoxXgGaAbhHc]))', value)) + return value, specifiers + except ET.ParseError: + print(f"Warning: Could not parse XML file: {filepath}") + except FileNotFoundError: + print(f"Warning: File not found: {filepath}") + return None, None + +def find_res_directories(project_root): + """ + Finds all 'res' directories within a project, typically in module roots. + """ + res_dirs = [] + for root_dir, dirs, _ in os.walk(project_root): + if 'res' in dirs: + res_dirs.append(os.path.join(root_dir, 'res')) + if not res_dirs and os.path.basename(project_root) == 'res': # If project_root itself is a res dir + res_dirs.append(project_root) + return res_dirs + + +def find_strings_files(res_dir_path, base_filename="strings.xml"): + """ + Finds all strings.xml files (or variants like strings-es.xml) + within a given 'res' directory. + """ + strings_files = {} # lang_code -> filepath + for dirpath, _, filenames in os.walk(res_dir_path): + if "values" in os.path.basename(dirpath).lower(): # e.g., values, values-es, values-en-rGB + for filename in filenames: + if filename.startswith(os.path.splitext(base_filename)[0]) and filename.endswith(".xml"): + full_path = os.path.join(dirpath, filename) + # Determine language code from directory name (e.g., "values-es" -> "es") + # or default if it's just "values" + dir_name_parts = os.path.basename(dirpath).split('-') + lang_code = "default" # For the base "values" folder + if len(dir_name_parts) > 1: + lang_code = "-".join(dir_name_parts[1:]) # Handles values-en-rUS correctly + strings_files[lang_code] = full_path + return strings_files + + +def main(): + parser = argparse.ArgumentParser( + description="Check format specifier consistency across language files for a given string key." + ) + parser.add_argument( + "project_root", + help="Path to the Android project's root directory (or a specific module's root, or a 'res' directory)." + ) + parser.add_argument( + "key_name", + help="The name of the string resource to check (e.g., 'skill_longdescription_evasion')." + ) + parser.add_argument( + "--base_lang", + default="default", + help="The language code for the base/reference strings file (e.g., 'en', 'default' for values/strings.xml). Default is 'default'." + ) + parser.add_argument( + "--strings_filename", + default="strings.xml", + help="The base name of your strings files (default: strings.xml)." + ) + + args = parser.parse_args() + + print(f"Searching for string key: '{args.key_name}'") + print(f"Using base language: '{args.base_lang}' from file '{args.strings_filename}'") + print(f"Project root/res path: {args.project_root}\n") + + res_directories = find_res_directories(args.project_root) + if not res_directories: + print(f"Error: No 'res' directory found under {args.project_root}") + return + + all_strings_files = {} + for res_dir in res_directories: + # print(f"Scanning res directory: {res_dir}") + all_strings_files.update(find_strings_files(res_dir, args.strings_filename)) + + if not all_strings_files: + print(f"Error: No '{args.strings_filename}' files found in any 'res/values-*' directories under {args.project_root}.") + return + + base_file_path = all_strings_files.get(args.base_lang) + + if not base_file_path: + # Try to find a default if 'en' or other specific base_lang isn't explicitly there + # but a 'values/strings.xml' (mapped to 'default') exists. + if args.base_lang != "default" and all_strings_files.get("default"): + print(f"Warning: Base language '{args.base_lang}' not found. Using 'default' (values/{args.strings_filename}) as base.") + base_file_path = all_strings_files.get("default") + args.base_lang = "default" # Update for consistency in messages + else: + print(f"Error: Base strings file for language '{args.base_lang}' (expected at e.g., values-{args.base_lang}/{args.strings_filename} or values/{args.strings_filename}) not found.") + print(f"Available language files found: {list(all_strings_files.keys())}") + return + + base_value, base_specifiers = get_string_value_and_specifiers(base_file_path, args.key_name) + + if base_specifiers is None: + print(f"Error: Key '{args.key_name}' not found in the base language file: {base_file_path}") + return + + print(f"--- Base ({args.base_lang}) ---") + print(f"File: {base_file_path}") + print(f"Value: \"{base_value}\"") + print(f"Specifiers: {sorted(list(base_specifiers)) if base_specifiers else 'None'}\n") + + issues_found = 0 + + for lang_code, file_path in all_strings_files.items(): + if lang_code == args.base_lang: + continue # Skip the base language itself + + current_value, current_specifiers = get_string_value_and_specifiers(file_path, args.key_name) + + if current_specifiers is None: + # Only warn if the key is expected to be translated but is missing + # (Some keys might not be translated by design, but for specifier check, we assume it should exist if base does) +# print(f"--- Language: {lang_code} ---") +# print(f"File: {file_path}") +# print(f"Warning: Key '{args.key_name}' not found in this language file.") +# print("-" * 20) + continue + + if current_specifiers != base_specifiers: + issues_found += 1 + print(f"--- Language: {lang_code} (ISSUE FOUND) ---") + print(f"File: {file_path}") + print(f"Value: \"{current_value}\"") + print(f"Specifiers: {sorted(list(current_specifiers)) if current_specifiers else 'None'}") + print(f"Expected specifiers (from base): {sorted(list(base_specifiers)) if base_specifiers else 'None'}") + + missing_in_current = base_specifiers - current_specifiers + extra_in_current = current_specifiers - base_specifiers + + if missing_in_current: + print(f" MISSING in '{lang_code}': {sorted(list(missing_in_current))}") + if extra_in_current: + print(f" EXTRA in '{lang_code}': {sorted(list(extra_in_current))}") + print("-" * 20) + # Optional: Print info for consistent files too + # else: + # print(f"--- Language: {lang_code} (OK) ---") + # print(f"File: {file_path}") + # print(f"Specifiers: {current_specifiers}") + # print("-" * 20) + + + if issues_found == 0: + print(f"\nNo specifier mismatches found for key '{args.key_name}' compared to the base language.") + else: + print(f"\nFound {issues_found} potential specifier mismatch(es) for key '{args.key_name}'.") + +if __name__ == "__main__": + main() From c244ba13908df71eed1275c2a31a661012bc2fe8 Mon Sep 17 00:00:00 2001 From: OMGeeky Date: Mon, 28 Jul 2025 21:12:23 +0200 Subject: [PATCH 04/21] Added checks for unescaped percent signs --- AndorsTrail/tools/check_format_specifiers.py | 26 ++++++++++++++++++++ 1 file changed, 26 insertions(+) diff --git a/AndorsTrail/tools/check_format_specifiers.py b/AndorsTrail/tools/check_format_specifiers.py index f4e90382e..669ce9eee 100644 --- a/AndorsTrail/tools/check_format_specifiers.py +++ b/AndorsTrail/tools/check_format_specifiers.py @@ -64,6 +64,22 @@ def find_strings_files(res_dir_path, base_filename="strings.xml"): strings_files[lang_code] = full_path return strings_files +def find_non_escaped_percent(value): + """ + Finds non-escaped % characters in a string (not part of %% or a valid format specifier). + Returns a list of indices where such % occur. + """ + # Find all % positions + percent_indices = [m.start() for m in re.finditer(r'%', value)] + # Find all valid format specifiers and %% positions + valid_specifier_pattern = r'%(?:%|(?:\d+\$)?[sdfeoxXgGaAbhHc])' + valid_matches = [m.span() for m in re.finditer(valid_specifier_pattern, value)] + # Mark all indices covered by valid specifiers or %% + covered_indices = set() + for start, end in valid_matches: + covered_indices.update(range(start, end)) + # Only report % indices not covered by valid specifiers or %% + return [idx for idx in percent_indices if idx not in covered_indices] def main(): parser = argparse.ArgumentParser( @@ -150,6 +166,16 @@ def main(): # print("-" * 20) continue + # Check for non-escaped % in the current value + non_escaped_percent_indices = find_non_escaped_percent(current_value) + if non_escaped_percent_indices: + issues_found += 1 + print(f"--- Language: {lang_code} (NON-ESCAPED % FOUND) ---") + print(f"File: {file_path}") + print(f"Value: \"{current_value}\"") + print(f"Non-escaped % at positions: {non_escaped_percent_indices}") + print("-" * 20) + if current_specifiers != base_specifiers: issues_found += 1 print(f"--- Language: {lang_code} (ISSUE FOUND) ---") From 80997ddc3645ec4cf2570f0045a87bcc03af1903 Mon Sep 17 00:00:00 2001 From: OMGeeky Date: Mon, 28 Jul 2025 21:20:17 +0200 Subject: [PATCH 05/21] Exit with error code on specifier mismatches in format checker --- AndorsTrail/tools/check_format_specifiers.py | 1 + 1 file changed, 1 insertion(+) diff --git a/AndorsTrail/tools/check_format_specifiers.py b/AndorsTrail/tools/check_format_specifiers.py index 669ce9eee..a259424b2 100644 --- a/AndorsTrail/tools/check_format_specifiers.py +++ b/AndorsTrail/tools/check_format_specifiers.py @@ -204,6 +204,7 @@ def main(): print(f"\nNo specifier mismatches found for key '{args.key_name}' compared to the base language.") else: print(f"\nFound {issues_found} potential specifier mismatch(es) for key '{args.key_name}'.") + exit(1) if __name__ == "__main__": main() From 2cc12b3530cc9e978cf5b6a10a8f9ec4338a8982 Mon Sep 17 00:00:00 2001 From: OMGeeky Date: Mon, 28 Jul 2025 21:25:28 +0200 Subject: [PATCH 06/21] Improve `check_format_specifiers.py` to check all keys if none specified --- AndorsTrail/tools/check_format_specifiers.py | 131 ++++++++++--------- 1 file changed, 66 insertions(+), 65 deletions(-) diff --git a/AndorsTrail/tools/check_format_specifiers.py b/AndorsTrail/tools/check_format_specifiers.py index a259424b2..56b7d8863 100644 --- a/AndorsTrail/tools/check_format_specifiers.py +++ b/AndorsTrail/tools/check_format_specifiers.py @@ -81,6 +81,17 @@ def find_non_escaped_percent(value): # Only report % indices not covered by valid specifiers or %% return [idx for idx in percent_indices if idx not in covered_indices] +def get_all_keys(filepath): + """ + Returns a list of all string resource keys in the given XML file. + """ + try: + tree = ET.parse(filepath) + root = tree.getroot() + return [string_tag.get('name') for string_tag in root.findall('string') if string_tag.get('name')] + except Exception: + return [] + def main(): parser = argparse.ArgumentParser( description="Check format specifier consistency across language files for a given string key." @@ -91,7 +102,9 @@ def main(): ) parser.add_argument( "key_name", - help="The name of the string resource to check (e.g., 'skill_longdescription_evasion')." + nargs="?", + default=None, + help="The name of the string resource to check (e.g., 'skill_longdescription_evasion'). If omitted, checks all keys in the base language file." ) parser.add_argument( "--base_lang", @@ -106,7 +119,6 @@ def main(): args = parser.parse_args() - print(f"Searching for string key: '{args.key_name}'") print(f"Using base language: '{args.base_lang}' from file '{args.strings_filename}'") print(f"Project root/res path: {args.project_root}\n") @@ -117,7 +129,6 @@ def main(): all_strings_files = {} for res_dir in res_directories: - # print(f"Scanning res directory: {res_dir}") all_strings_files.update(find_strings_files(res_dir, args.strings_filename)) if not all_strings_files: @@ -125,85 +136,75 @@ def main(): return base_file_path = all_strings_files.get(args.base_lang) - if not base_file_path: - # Try to find a default if 'en' or other specific base_lang isn't explicitly there - # but a 'values/strings.xml' (mapped to 'default') exists. if args.base_lang != "default" and all_strings_files.get("default"): print(f"Warning: Base language '{args.base_lang}' not found. Using 'default' (values/{args.strings_filename}) as base.") base_file_path = all_strings_files.get("default") - args.base_lang = "default" # Update for consistency in messages + args.base_lang = "default" else: - print(f"Error: Base strings file for language '{args.base_lang}' (expected at e.g., values-{args.base_lang}/{args.strings_filename} or values/{args.strings_filename}) not found.") + print(f"Error: Base strings file for language '{args.base_lang}' not found.") print(f"Available language files found: {list(all_strings_files.keys())}") return - base_value, base_specifiers = get_string_value_and_specifiers(base_file_path, args.key_name) + # If no key_name is provided, check all keys in the base file + if args.key_name is None: + keys_to_check = get_all_keys(base_file_path) + if not keys_to_check: + print(f"Error: No string keys found in base file: {base_file_path}") + return + print(f"Checking all {len(keys_to_check)} keys in base file: {base_file_path}\n") + else: + keys_to_check = [args.key_name] + print(f"Searching for string key: '{args.key_name}'\n") - if base_specifiers is None: - print(f"Error: Key '{args.key_name}' not found in the base language file: {base_file_path}") - return + total_issues_found = 0 - print(f"--- Base ({args.base_lang}) ---") - print(f"File: {base_file_path}") - print(f"Value: \"{base_value}\"") - print(f"Specifiers: {sorted(list(base_specifiers)) if base_specifiers else 'None'}\n") - - issues_found = 0 - - for lang_code, file_path in all_strings_files.items(): - if lang_code == args.base_lang: - continue # Skip the base language itself - - current_value, current_specifiers = get_string_value_and_specifiers(file_path, args.key_name) - - if current_specifiers is None: - # Only warn if the key is expected to be translated but is missing - # (Some keys might not be translated by design, but for specifier check, we assume it should exist if base does) -# print(f"--- Language: {lang_code} ---") -# print(f"File: {file_path}") -# print(f"Warning: Key '{args.key_name}' not found in this language file.") -# print("-" * 20) + for key_name in keys_to_check: + base_value, base_specifiers = get_string_value_and_specifiers(base_file_path, key_name) + if base_specifiers is None: continue - # Check for non-escaped % in the current value - non_escaped_percent_indices = find_non_escaped_percent(current_value) - if non_escaped_percent_indices: - issues_found += 1 - print(f"--- Language: {lang_code} (NON-ESCAPED % FOUND) ---") - print(f"File: {file_path}") - print(f"Value: \"{current_value}\"") - print(f"Non-escaped % at positions: {non_escaped_percent_indices}") - print("-" * 20) + issues_found = 0 - if current_specifiers != base_specifiers: - issues_found += 1 - print(f"--- Language: {lang_code} (ISSUE FOUND) ---") - print(f"File: {file_path}") - print(f"Value: \"{current_value}\"") - print(f"Specifiers: {sorted(list(current_specifiers)) if current_specifiers else 'None'}") - print(f"Expected specifiers (from base): {sorted(list(base_specifiers)) if base_specifiers else 'None'}") + for lang_code, file_path in all_strings_files.items(): + if lang_code == args.base_lang: + continue - missing_in_current = base_specifiers - current_specifiers - extra_in_current = current_specifiers - base_specifiers + current_value, current_specifiers = get_string_value_and_specifiers(file_path, key_name) + if current_specifiers is None: + continue - if missing_in_current: - print(f" MISSING in '{lang_code}': {sorted(list(missing_in_current))}") - if extra_in_current: - print(f" EXTRA in '{lang_code}': {sorted(list(extra_in_current))}") - print("-" * 20) - # Optional: Print info for consistent files too - # else: - # print(f"--- Language: {lang_code} (OK) ---") - # print(f"File: {file_path}") - # print(f"Specifiers: {current_specifiers}") - # print("-" * 20) + non_escaped_percent_indices = find_non_escaped_percent(current_value) + if non_escaped_percent_indices: + issues_found += 1 + print(f"--- Language: {lang_code} (NON-ESCAPED % FOUND) ---") + print(f"Key: {key_name}") + print(f"File: {file_path}") + print(f"Value: \"{current_value}\"") + print(f"Non-escaped % at positions: {non_escaped_percent_indices}") + print("-" * 20) + if current_specifiers != base_specifiers: + issues_found += 1 + print(f"--- Language: {lang_code} (ISSUE FOUND) ---") + print(f"Key: {key_name}") + print(f"File: {file_path}") + print(f"Value: \"{current_value}\"") + print(f"Specifiers: {sorted(list(current_specifiers)) if current_specifiers else 'None'}") + print(f"Expected specifiers (from base): {sorted(list(base_specifiers)) if base_specifiers else 'None'}") - if issues_found == 0: - print(f"\nNo specifier mismatches found for key '{args.key_name}' compared to the base language.") - else: - print(f"\nFound {issues_found} potential specifier mismatch(es) for key '{args.key_name}'.") + missing_in_current = base_specifiers - current_specifiers + extra_in_current = current_specifiers - base_specifiers + + if missing_in_current: + print(f" MISSING in '{lang_code}': {sorted(list(missing_in_current))}") + if extra_in_current: + print(f" EXTRA in '{lang_code}': {sorted(list(extra_in_current))}") + print("-" * 20) + + total_issues_found += issues_found + + if total_issues_found != 0: exit(1) if __name__ == "__main__": From 0422beb855bc146050b9dd5e95d55f81522fed37 Mon Sep 17 00:00:00 2001 From: OMGeeky Date: Mon, 28 Jul 2025 21:35:38 +0200 Subject: [PATCH 07/21] Update string formatter check script - Add scanning for used keys in Java files. - Refactor argument parsing to separate project root and res root. - If no specific key is provided, check only keys used in Java code. --- AndorsTrail/tools/check_format_specifiers.py | 43 +++++++++++++++----- 1 file changed, 33 insertions(+), 10 deletions(-) diff --git a/AndorsTrail/tools/check_format_specifiers.py b/AndorsTrail/tools/check_format_specifiers.py index 56b7d8863..58adc6fe8 100644 --- a/AndorsTrail/tools/check_format_specifiers.py +++ b/AndorsTrail/tools/check_format_specifiers.py @@ -92,13 +92,35 @@ def get_all_keys(filepath): except Exception: return [] +def find_used_keys_in_java(project_root): + """ + Scans all .java files under project_root for usages of string resource keys. + Returns a set of keys found. + """ + key_pattern = re.compile(r'R\.string\.([a-zA-Z0-9_]+)') + used_keys = set() + for root, _, files in os.walk(project_root): + for fname in files: + if fname.endswith('.java'): + try: + with open(os.path.join(root, fname), encoding='utf-8') as f: + content = f.read() + used_keys.update(key_pattern.findall(content)) + except Exception: + pass + return used_keys + def main(): parser = argparse.ArgumentParser( description="Check format specifier consistency across language files for a given string key." ) parser.add_argument( "project_root", - help="Path to the Android project's root directory (or a specific module's root, or a 'res' directory)." + help="Path to the Android project's root directory (or a specific module's root directory)." + ) + parser.add_argument( + "res_root", + help="Path to the some 'res' directory." ) parser.add_argument( "key_name", @@ -120,11 +142,12 @@ def main(): args = parser.parse_args() print(f"Using base language: '{args.base_lang}' from file '{args.strings_filename}'") - print(f"Project root/res path: {args.project_root}\n") + print(f"Project root path: {args.project_root}\n") + print(f"Project res path: {args.res_root}\n") - res_directories = find_res_directories(args.project_root) + res_directories = find_res_directories(args.res_root) if not res_directories: - print(f"Error: No 'res' directory found under {args.project_root}") + print(f"Error: No 'res' directory found under {args.res_root}") return all_strings_files = {} @@ -132,7 +155,7 @@ def main(): all_strings_files.update(find_strings_files(res_dir, args.strings_filename)) if not all_strings_files: - print(f"Error: No '{args.strings_filename}' files found in any 'res/values-*' directories under {args.project_root}.") + print(f"Error: No '{args.strings_filename}' files found in any 'res/values-*' directories under {args.res_root}.") return base_file_path = all_strings_files.get(args.base_lang) @@ -146,16 +169,16 @@ def main(): print(f"Available language files found: {list(all_strings_files.keys())}") return - # If no key_name is provided, check all keys in the base file + # If no key_name is provided, check only keys used in .java files if args.key_name is None: - keys_to_check = get_all_keys(base_file_path) + used_keys = find_used_keys_in_java(args.project_root) + all_keys = set(get_all_keys(base_file_path)) + keys_to_check = sorted(list(all_keys & used_keys)) if not keys_to_check: - print(f"Error: No string keys found in base file: {base_file_path}") + print('no keys to check') return - print(f"Checking all {len(keys_to_check)} keys in base file: {base_file_path}\n") else: keys_to_check = [args.key_name] - print(f"Searching for string key: '{args.key_name}'\n") total_issues_found = 0 From 9c4009034fcaf7a9f9e8b4fdcfb471d09186faff Mon Sep 17 00:00:00 2001 From: OMGeeky Date: Mon, 28 Jul 2025 21:51:31 +0200 Subject: [PATCH 08/21] Enhance format specifier check script output The script now provides a summary of errors per file at the end of its execution. This makes it easier to identify which translation files have issues with format specifiers or non-escaped percentage signs. --- AndorsTrail/tools/check_format_specifiers.py | 19 +++++++++++++------ 1 file changed, 13 insertions(+), 6 deletions(-) diff --git a/AndorsTrail/tools/check_format_specifiers.py b/AndorsTrail/tools/check_format_specifiers.py index 58adc6fe8..248af21ba 100644 --- a/AndorsTrail/tools/check_format_specifiers.py +++ b/AndorsTrail/tools/check_format_specifiers.py @@ -181,14 +181,13 @@ def main(): keys_to_check = [args.key_name] total_issues_found = 0 + file_error_counts = {} for key_name in keys_to_check: base_value, base_specifiers = get_string_value_and_specifiers(base_file_path, key_name) if base_specifiers is None: continue - issues_found = 0 - for lang_code, file_path in all_strings_files.items(): if lang_code == args.base_lang: continue @@ -197,9 +196,11 @@ def main(): if current_specifiers is None: continue + error_count = 0 + non_escaped_percent_indices = find_non_escaped_percent(current_value) if non_escaped_percent_indices: - issues_found += 1 + error_count += 1 print(f"--- Language: {lang_code} (NON-ESCAPED % FOUND) ---") print(f"Key: {key_name}") print(f"File: {file_path}") @@ -208,7 +209,7 @@ def main(): print("-" * 20) if current_specifiers != base_specifiers: - issues_found += 1 + error_count += 1 print(f"--- Language: {lang_code} (ISSUE FOUND) ---") print(f"Key: {key_name}") print(f"File: {file_path}") @@ -225,9 +226,15 @@ def main(): print(f" EXTRA in '{lang_code}': {sorted(list(extra_in_current))}") print("-" * 20) - total_issues_found += issues_found + if error_count: + file_error_counts[file_path] = file_error_counts.get(file_path, 0) + error_count - if total_issues_found != 0: + if file_error_counts: + print("\nSummary of errors per file:") + for file_path, count in file_error_counts.items(): + print(f"{file_path}: {count} error(s)") + + if file_error_counts: exit(1) if __name__ == "__main__": From 6e74243ea8cef0d7cb8099b9cdb3e418b869ac35 Mon Sep 17 00:00:00 2001 From: OMGeeky Date: Mon, 28 Jul 2025 21:51:59 +0200 Subject: [PATCH 09/21] Refactor: Improve format specifier regex The regular expression for identifying format specifiers in XML string resources has been updated. The new regex now correctly identifies specifiers like `%.2f` which include precision for floating point numbers. This change ensures more accurate validation of format specifiers. --- AndorsTrail/tools/check_format_specifiers.py | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/AndorsTrail/tools/check_format_specifiers.py b/AndorsTrail/tools/check_format_specifiers.py index 248af21ba..72a75b7b1 100644 --- a/AndorsTrail/tools/check_format_specifiers.py +++ b/AndorsTrail/tools/check_format_specifiers.py @@ -23,7 +23,7 @@ def get_string_value_and_specifiers(filepath, key_name): value = string_tag.text if string_tag.text else "" # Regex to find format specifiers like %s, %d, %1$s, %2$d, etc. # It handles optional positional arguments (e.g., 1$) and type characters. - specifiers = set(re.findall(r'%(?:(?:\d+\$)?(?:[sdfeoxXgGaAbhHc]))', value)) + specifiers = set(re.findall(r'%(?:(?:\d+\$)?(?:[sdfeoxXgGaAbhHc]|(?:\.\d[fd])))', value)) return value, specifiers except ET.ParseError: print(f"Warning: Could not parse XML file: {filepath}") @@ -72,7 +72,7 @@ def find_non_escaped_percent(value): # Find all % positions percent_indices = [m.start() for m in re.finditer(r'%', value)] # Find all valid format specifiers and %% positions - valid_specifier_pattern = r'%(?:%|(?:\d+\$)?[sdfeoxXgGaAbhHc])' + valid_specifier_pattern = r'%(?:%|(?:\d+\$)?(?:[sdfeoxXgGaAbhHc]|(?:\.\d[fd])))' valid_matches = [m.span() for m in re.finditer(valid_specifier_pattern, value)] # Mark all indices covered by valid specifiers or %% covered_indices = set() From 149ad3ae1cd2a5f5df7f4f6a78ab0246715a910c Mon Sep 17 00:00:00 2001 From: OMGeeky Date: Mon, 28 Jul 2025 21:57:29 +0200 Subject: [PATCH 10/21] Differentiate between missing and extra format specifiers Missing format specifiers in translated strings are now reported as warnings, while extra format specifiers are reported as errors. This change allows the script to pass if only warnings (missing specifiers) are present, but still fail if there are errors (extra specifiers). The summary now also includes counts for both errors and warnings per file. --- AndorsTrail/tools/check_format_specifiers.py | 43 +++++++++++++------- 1 file changed, 28 insertions(+), 15 deletions(-) diff --git a/AndorsTrail/tools/check_format_specifiers.py b/AndorsTrail/tools/check_format_specifiers.py index 72a75b7b1..8d3a0cc34 100644 --- a/AndorsTrail/tools/check_format_specifiers.py +++ b/AndorsTrail/tools/check_format_specifiers.py @@ -182,6 +182,7 @@ def main(): total_issues_found = 0 file_error_counts = {} + file_warning_counts = {} for key_name in keys_to_check: base_value, base_specifiers = get_string_value_and_specifiers(base_file_path, key_name) @@ -197,6 +198,7 @@ def main(): continue error_count = 0 + warning_count = 0 non_escaped_percent_indices = find_non_escaped_percent(current_value) if non_escaped_percent_indices: @@ -209,30 +211,41 @@ def main(): print("-" * 20) if current_specifiers != base_specifiers: - error_count += 1 - print(f"--- Language: {lang_code} (ISSUE FOUND) ---") - print(f"Key: {key_name}") - print(f"File: {file_path}") - print(f"Value: \"{current_value}\"") - print(f"Specifiers: {sorted(list(current_specifiers)) if current_specifiers else 'None'}") - print(f"Expected specifiers (from base): {sorted(list(base_specifiers)) if base_specifiers else 'None'}") - missing_in_current = base_specifiers - current_specifiers extra_in_current = current_specifiers - base_specifiers - if missing_in_current: - print(f" MISSING in '{lang_code}': {sorted(list(missing_in_current))}") if extra_in_current: + error_count += 1 + print(f"--- Language: {lang_code} (ISSUE FOUND) ---") + print(f"Key: {key_name}") + print(f"File: {file_path}") + print(f"Value: \"{current_value}\"") + print(f"Specifiers: {sorted(list(current_specifiers)) if current_specifiers else 'None'}") + print(f"Expected specifiers (from base): {sorted(list(base_specifiers)) if base_specifiers else 'None'}") print(f" EXTRA in '{lang_code}': {sorted(list(extra_in_current))}") - print("-" * 20) + print("-" * 20) + if missing_in_current: + warning_count += 1 + print(f"--- Language: {lang_code} (WARNING: MISSING SPECIFIERS) ---") + print(f"Key: {key_name}") + print(f"File: {file_path}") + print(f"Value: \"{current_value}\"") + print(f"Specifiers: {sorted(list(current_specifiers)) if current_specifiers else 'None'}") + print(f"Expected specifiers (from base): {sorted(list(base_specifiers)) if base_specifiers else 'None'}") + print(f" MISSING in '{lang_code}': {sorted(list(missing_in_current))}") + print("-" * 20) if error_count: file_error_counts[file_path] = file_error_counts.get(file_path, 0) + error_count + if warning_count: + file_warning_counts[file_path] = file_warning_counts.get(file_path, 0) + warning_count - if file_error_counts: - print("\nSummary of errors per file:") - for file_path, count in file_error_counts.items(): - print(f"{file_path}: {count} error(s)") + if file_error_counts or file_warning_counts: + print("\nSummary of errors and warnings per file:") + for file_path in set(list(file_error_counts.keys()) + list(file_warning_counts.keys())): + error_str = f"{file_error_counts.get(file_path, 0)} error(s)" + warning_str = f"{file_warning_counts.get(file_path, 0)} warning(s)" + print(f"{file_path}:\t {error_str:>5}, {warning_str:>5}") if file_error_counts: exit(1) From fd169e9f40393a19353257d1cc2679a95c1a5a9c Mon Sep 17 00:00:00 2001 From: OMGeeky Date: Mon, 28 Jul 2025 21:59:19 +0200 Subject: [PATCH 11/21] Add total error and warning summary to format specifier check output --- AndorsTrail/tools/check_format_specifiers.py | 4 ++++ 1 file changed, 4 insertions(+) diff --git a/AndorsTrail/tools/check_format_specifiers.py b/AndorsTrail/tools/check_format_specifiers.py index 8d3a0cc34..eb2a79133 100644 --- a/AndorsTrail/tools/check_format_specifiers.py +++ b/AndorsTrail/tools/check_format_specifiers.py @@ -247,6 +247,10 @@ def main(): warning_str = f"{file_warning_counts.get(file_path, 0)} warning(s)" print(f"{file_path}:\t {error_str:>5}, {warning_str:>5}") + total_errors = sum(file_error_counts.values()) + total_warnings = sum(file_warning_counts.values()) + print(f"\nTOTAL: {total_errors} error(s), {total_warnings} warning(s)") + if file_error_counts: exit(1) From 11d5966a519e1a63a18620aabef17c466ed4d1b7 Mon Sep 17 00:00:00 2001 From: OMGeeky Date: Mon, 28 Jul 2025 22:00:24 +0200 Subject: [PATCH 12/21] Sort summary output of errors and warnings by file path --- AndorsTrail/tools/check_format_specifiers.py | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/AndorsTrail/tools/check_format_specifiers.py b/AndorsTrail/tools/check_format_specifiers.py index eb2a79133..bf073d6d3 100644 --- a/AndorsTrail/tools/check_format_specifiers.py +++ b/AndorsTrail/tools/check_format_specifiers.py @@ -242,7 +242,7 @@ def main(): if file_error_counts or file_warning_counts: print("\nSummary of errors and warnings per file:") - for file_path in set(list(file_error_counts.keys()) + list(file_warning_counts.keys())): + for file_path in sorted(set(list(file_error_counts.keys()) + list(file_warning_counts.keys()))): error_str = f"{file_error_counts.get(file_path, 0)} error(s)" warning_str = f"{file_warning_counts.get(file_path, 0)} warning(s)" print(f"{file_path}:\t {error_str:>5}, {warning_str:>5}") From a2859fbc56463476e16946901ed7442bb2693f2d Mon Sep 17 00:00:00 2001 From: OMGeeky Date: Mon, 28 Jul 2025 23:33:23 +0200 Subject: [PATCH 13/21] Remove unnecessary @TargetApi annotations and remove unnecessary SDK-Version check --- .../app/src/main/java/com/gpl/rpg/AndorsTrail/Dialogs.java | 1 - .../gpl/rpg/AndorsTrail/activity/ConversationActivity.java | 6 ++---- .../gpl/rpg/AndorsTrail/activity/StartScreenActivity.java | 4 +++- .../activity/fragment/StartScreenActivity_MainMenu.java | 2 -- 4 files changed, 5 insertions(+), 8 deletions(-) diff --git a/AndorsTrail/app/src/main/java/com/gpl/rpg/AndorsTrail/Dialogs.java b/AndorsTrail/app/src/main/java/com/gpl/rpg/AndorsTrail/Dialogs.java index 75a0e1c4e..9816764f7 100644 --- a/AndorsTrail/app/src/main/java/com/gpl/rpg/AndorsTrail/Dialogs.java +++ b/AndorsTrail/app/src/main/java/com/gpl/rpg/AndorsTrail/Dialogs.java @@ -346,7 +346,6 @@ public final class Dialogs { CustomDialogFactory.show(d); } - @TargetApi(23) private static boolean hasPermissions(final Activity activity) { if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.M) { if (activity.getApplicationContext().checkSelfPermission(android.Manifest.permission.READ_EXTERNAL_STORAGE) != PackageManager.PERMISSION_GRANTED diff --git a/AndorsTrail/app/src/main/java/com/gpl/rpg/AndorsTrail/activity/ConversationActivity.java b/AndorsTrail/app/src/main/java/com/gpl/rpg/AndorsTrail/activity/ConversationActivity.java index 6837dd5ac..95421cc48 100644 --- a/AndorsTrail/app/src/main/java/com/gpl/rpg/AndorsTrail/activity/ConversationActivity.java +++ b/AndorsTrail/app/src/main/java/com/gpl/rpg/AndorsTrail/activity/ConversationActivity.java @@ -77,11 +77,9 @@ public final class ConversationActivity setContentView(R.layout.conversation); - if(Build.VERSION.SDK_INT >= Build.VERSION_CODES.HONEYCOMB) { - setFinishOnTouchOutside(false); - } + setFinishOnTouchOutside(false); - replyGroup = new RadioGroup(this); + replyGroup = new RadioGroup(this); replyGroup.setLayoutParams(new ListView.LayoutParams(ListView.LayoutParams.MATCH_PARENT, ListView.LayoutParams.WRAP_CONTENT)); statementList = (ListView) findViewById(R.id.conversation_statements); statementList.addFooterView(replyGroup); diff --git a/AndorsTrail/app/src/main/java/com/gpl/rpg/AndorsTrail/activity/StartScreenActivity.java b/AndorsTrail/app/src/main/java/com/gpl/rpg/AndorsTrail/activity/StartScreenActivity.java index fd55984dc..245d7d6a8 100644 --- a/AndorsTrail/app/src/main/java/com/gpl/rpg/AndorsTrail/activity/StartScreenActivity.java +++ b/AndorsTrail/app/src/main/java/com/gpl/rpg/AndorsTrail/activity/StartScreenActivity.java @@ -21,6 +21,8 @@ import android.content.pm.PackageManager; import android.content.res.Resources; import android.graphics.drawable.AnimationDrawable; import android.os.Bundle; + +import androidx.annotation.NonNull; import androidx.fragment.app.Fragment; import androidx.fragment.app.FragmentManager.OnBackStackChangedListener; import android.view.KeyEvent; @@ -112,7 +114,7 @@ public final class StartScreenActivity extends AndorsTrailBaseFragmentActivity i } @Override - public void onRequestPermissionsResult(int requestCode, String[] permissions, int[] grantResults) { + public void onRequestPermissionsResult(int requestCode, @NonNull String[] permissions, int[] grantResults) { if (grantResults.length > 0 && grantResults[0] != PackageManager.PERMISSION_GRANTED) { final CustomDialog d = CustomDialogFactory.createDialog(this, diff --git a/AndorsTrail/app/src/main/java/com/gpl/rpg/AndorsTrail/activity/fragment/StartScreenActivity_MainMenu.java b/AndorsTrail/app/src/main/java/com/gpl/rpg/AndorsTrail/activity/fragment/StartScreenActivity_MainMenu.java index ba424a9b2..ac8c814ed 100644 --- a/AndorsTrail/app/src/main/java/com/gpl/rpg/AndorsTrail/activity/fragment/StartScreenActivity_MainMenu.java +++ b/AndorsTrail/app/src/main/java/com/gpl/rpg/AndorsTrail/activity/fragment/StartScreenActivity_MainMenu.java @@ -196,7 +196,6 @@ public class StartScreenActivity_MainMenu extends Fragment { } - @TargetApi(29) public void migrateDataOnDemand(final Activity activity) { if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.Q) { if (activity.getApplicationContext().checkSelfPermission(Manifest.permission.READ_EXTERNAL_STORAGE) == PackageManager.PERMISSION_GRANTED) { @@ -232,7 +231,6 @@ public class StartScreenActivity_MainMenu extends Fragment { private static final int READ_EXTERNAL_STORAGE_REQUEST=1; private static final int WRITE_EXTERNAL_STORAGE_REQUEST=2; - @TargetApi(23) public static void checkAndRequestPermissions(final Activity activity) { if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.M && Build.VERSION.SDK_INT <= Build.VERSION_CODES.Q) { if (activity.getApplicationContext().checkSelfPermission(Manifest.permission.READ_EXTERNAL_STORAGE) != PackageManager.PERMISSION_GRANTED) { From f884af20b8f2181a6a8ff21037214d42ab4c6c9f Mon Sep 17 00:00:00 2001 From: OMGeeky Date: Tue, 29 Jul 2025 00:08:02 +0200 Subject: [PATCH 14/21] Replace custom Pair implementation with android.util.Pair --- .../gpl/rpg/AndorsTrail/AndorsTrailApplication.java | 2 +- .../resource/parsers/ActorConditionsTypeParser.java | 2 +- .../resource/parsers/ConversationListParser.java | 2 +- .../AndorsTrail/resource/parsers/DropListParser.java | 2 +- .../resource/parsers/ItemCategoryParser.java | 2 +- .../AndorsTrail/resource/parsers/ItemTypeParser.java | 2 +- .../resource/parsers/MonsterTypeParser.java | 2 +- .../rpg/AndorsTrail/resource/parsers/QuestParser.java | 2 +- .../AndorsTrail/resource/parsers/WorldMapParser.java | 2 +- .../parsers/json/JsonCollectionParserFor.java | 2 +- .../main/java/com/gpl/rpg/AndorsTrail/util/Pair.java | 11 ----------- 11 files changed, 10 insertions(+), 21 deletions(-) delete mode 100644 AndorsTrail/app/src/main/java/com/gpl/rpg/AndorsTrail/util/Pair.java diff --git a/AndorsTrail/app/src/main/java/com/gpl/rpg/AndorsTrail/AndorsTrailApplication.java b/AndorsTrail/app/src/main/java/com/gpl/rpg/AndorsTrail/AndorsTrailApplication.java index eedfce2c8..ede2dbbf7 100644 --- a/AndorsTrail/app/src/main/java/com/gpl/rpg/AndorsTrail/AndorsTrailApplication.java +++ b/AndorsTrail/app/src/main/java/com/gpl/rpg/AndorsTrail/AndorsTrailApplication.java @@ -8,7 +8,6 @@ import com.gpl.rpg.AndorsTrail.context.ControllerContext; import com.gpl.rpg.AndorsTrail.context.WorldContext; import com.gpl.rpg.AndorsTrail.controller.Constants; import com.gpl.rpg.AndorsTrail.util.AndroidStorage; -import com.gpl.rpg.AndorsTrail.util.Pair; import android.app.Activity; import android.app.Application; @@ -17,6 +16,7 @@ import android.content.res.Configuration; import android.content.res.Resources; import android.os.Build; import android.os.Environment; +import android.util.Pair; import android.view.Window; import android.view.WindowInsets; import android.view.WindowInsetsController; diff --git a/AndorsTrail/app/src/main/java/com/gpl/rpg/AndorsTrail/resource/parsers/ActorConditionsTypeParser.java b/AndorsTrail/app/src/main/java/com/gpl/rpg/AndorsTrail/resource/parsers/ActorConditionsTypeParser.java index 3ed83d905..90ee7fee6 100644 --- a/AndorsTrail/app/src/main/java/com/gpl/rpg/AndorsTrail/resource/parsers/ActorConditionsTypeParser.java +++ b/AndorsTrail/app/src/main/java/com/gpl/rpg/AndorsTrail/resource/parsers/ActorConditionsTypeParser.java @@ -8,7 +8,7 @@ import com.gpl.rpg.AndorsTrail.resource.DynamicTileLoader; import com.gpl.rpg.AndorsTrail.resource.TranslationLoader; import com.gpl.rpg.AndorsTrail.resource.parsers.json.JsonCollectionParserFor; import com.gpl.rpg.AndorsTrail.resource.parsers.json.JsonFieldNames; -import com.gpl.rpg.AndorsTrail.util.Pair; +import android.util.Pair; public final class ActorConditionsTypeParser extends JsonCollectionParserFor { diff --git a/AndorsTrail/app/src/main/java/com/gpl/rpg/AndorsTrail/resource/parsers/ConversationListParser.java b/AndorsTrail/app/src/main/java/com/gpl/rpg/AndorsTrail/resource/parsers/ConversationListParser.java index 215c984b2..e3c426399 100644 --- a/AndorsTrail/app/src/main/java/com/gpl/rpg/AndorsTrail/resource/parsers/ConversationListParser.java +++ b/AndorsTrail/app/src/main/java/com/gpl/rpg/AndorsTrail/resource/parsers/ConversationListParser.java @@ -13,7 +13,7 @@ import com.gpl.rpg.AndorsTrail.resource.parsers.json.JsonArrayParserFor; import com.gpl.rpg.AndorsTrail.resource.parsers.json.JsonCollectionParserFor; import com.gpl.rpg.AndorsTrail.resource.parsers.json.JsonFieldNames; import com.gpl.rpg.AndorsTrail.util.L; -import com.gpl.rpg.AndorsTrail.util.Pair; +import android.util.Pair; public final class ConversationListParser extends JsonCollectionParserFor { diff --git a/AndorsTrail/app/src/main/java/com/gpl/rpg/AndorsTrail/resource/parsers/DropListParser.java b/AndorsTrail/app/src/main/java/com/gpl/rpg/AndorsTrail/resource/parsers/DropListParser.java index bcb87337f..063a9ef5d 100644 --- a/AndorsTrail/app/src/main/java/com/gpl/rpg/AndorsTrail/resource/parsers/DropListParser.java +++ b/AndorsTrail/app/src/main/java/com/gpl/rpg/AndorsTrail/resource/parsers/DropListParser.java @@ -11,7 +11,7 @@ import com.gpl.rpg.AndorsTrail.resource.parsers.json.JsonArrayParserFor; import com.gpl.rpg.AndorsTrail.resource.parsers.json.JsonCollectionParserFor; import com.gpl.rpg.AndorsTrail.resource.parsers.json.JsonFieldNames; import com.gpl.rpg.AndorsTrail.util.L; -import com.gpl.rpg.AndorsTrail.util.Pair; +import android.util.Pair; public final class DropListParser extends JsonCollectionParserFor { diff --git a/AndorsTrail/app/src/main/java/com/gpl/rpg/AndorsTrail/resource/parsers/ItemCategoryParser.java b/AndorsTrail/app/src/main/java/com/gpl/rpg/AndorsTrail/resource/parsers/ItemCategoryParser.java index dcb4cb59f..b677e8b98 100644 --- a/AndorsTrail/app/src/main/java/com/gpl/rpg/AndorsTrail/resource/parsers/ItemCategoryParser.java +++ b/AndorsTrail/app/src/main/java/com/gpl/rpg/AndorsTrail/resource/parsers/ItemCategoryParser.java @@ -8,7 +8,7 @@ import com.gpl.rpg.AndorsTrail.model.item.ItemCategory; import com.gpl.rpg.AndorsTrail.resource.TranslationLoader; import com.gpl.rpg.AndorsTrail.resource.parsers.json.JsonCollectionParserFor; import com.gpl.rpg.AndorsTrail.resource.parsers.json.JsonFieldNames; -import com.gpl.rpg.AndorsTrail.util.Pair; +import android.util.Pair; public final class ItemCategoryParser extends JsonCollectionParserFor { diff --git a/AndorsTrail/app/src/main/java/com/gpl/rpg/AndorsTrail/resource/parsers/ItemTypeParser.java b/AndorsTrail/app/src/main/java/com/gpl/rpg/AndorsTrail/resource/parsers/ItemTypeParser.java index edc8eb7d1..f85aca1de 100644 --- a/AndorsTrail/app/src/main/java/com/gpl/rpg/AndorsTrail/resource/parsers/ItemTypeParser.java +++ b/AndorsTrail/app/src/main/java/com/gpl/rpg/AndorsTrail/resource/parsers/ItemTypeParser.java @@ -13,7 +13,7 @@ import com.gpl.rpg.AndorsTrail.resource.DynamicTileLoader; import com.gpl.rpg.AndorsTrail.resource.TranslationLoader; import com.gpl.rpg.AndorsTrail.resource.parsers.json.JsonCollectionParserFor; import com.gpl.rpg.AndorsTrail.resource.parsers.json.JsonFieldNames; -import com.gpl.rpg.AndorsTrail.util.Pair; +import android.util.Pair; public final class ItemTypeParser extends JsonCollectionParserFor { diff --git a/AndorsTrail/app/src/main/java/com/gpl/rpg/AndorsTrail/resource/parsers/MonsterTypeParser.java b/AndorsTrail/app/src/main/java/com/gpl/rpg/AndorsTrail/resource/parsers/MonsterTypeParser.java index 4f6f47b64..6b50ea74b 100644 --- a/AndorsTrail/app/src/main/java/com/gpl/rpg/AndorsTrail/resource/parsers/MonsterTypeParser.java +++ b/AndorsTrail/app/src/main/java/com/gpl/rpg/AndorsTrail/resource/parsers/MonsterTypeParser.java @@ -14,7 +14,7 @@ import com.gpl.rpg.AndorsTrail.resource.TranslationLoader; import com.gpl.rpg.AndorsTrail.resource.parsers.json.JsonCollectionParserFor; import com.gpl.rpg.AndorsTrail.resource.parsers.json.JsonFieldNames; import com.gpl.rpg.AndorsTrail.util.ConstRange; -import com.gpl.rpg.AndorsTrail.util.Pair; +import android.util.Pair; import com.gpl.rpg.AndorsTrail.util.Size; public final class MonsterTypeParser extends JsonCollectionParserFor { diff --git a/AndorsTrail/app/src/main/java/com/gpl/rpg/AndorsTrail/resource/parsers/QuestParser.java b/AndorsTrail/app/src/main/java/com/gpl/rpg/AndorsTrail/resource/parsers/QuestParser.java index 0693e63d8..6316bd6d9 100644 --- a/AndorsTrail/app/src/main/java/com/gpl/rpg/AndorsTrail/resource/parsers/QuestParser.java +++ b/AndorsTrail/app/src/main/java/com/gpl/rpg/AndorsTrail/resource/parsers/QuestParser.java @@ -12,7 +12,7 @@ import com.gpl.rpg.AndorsTrail.resource.TranslationLoader; import com.gpl.rpg.AndorsTrail.resource.parsers.json.JsonArrayParserFor; import com.gpl.rpg.AndorsTrail.resource.parsers.json.JsonCollectionParserFor; import com.gpl.rpg.AndorsTrail.resource.parsers.json.JsonFieldNames; -import com.gpl.rpg.AndorsTrail.util.Pair; +import android.util.Pair; public final class QuestParser extends JsonCollectionParserFor { private final TranslationLoader translationLoader; diff --git a/AndorsTrail/app/src/main/java/com/gpl/rpg/AndorsTrail/resource/parsers/WorldMapParser.java b/AndorsTrail/app/src/main/java/com/gpl/rpg/AndorsTrail/resource/parsers/WorldMapParser.java index 1e16b09a9..2667fa505 100644 --- a/AndorsTrail/app/src/main/java/com/gpl/rpg/AndorsTrail/resource/parsers/WorldMapParser.java +++ b/AndorsTrail/app/src/main/java/com/gpl/rpg/AndorsTrail/resource/parsers/WorldMapParser.java @@ -16,7 +16,7 @@ import com.gpl.rpg.AndorsTrail.model.map.WorldMapSegment.WorldMapSegmentMap; import com.gpl.rpg.AndorsTrail.resource.TranslationLoader; import com.gpl.rpg.AndorsTrail.util.Coord; import com.gpl.rpg.AndorsTrail.util.L; -import com.gpl.rpg.AndorsTrail.util.Pair; +import android.util.Pair; import com.gpl.rpg.AndorsTrail.util.XmlResourceParserUtils; public final class WorldMapParser { diff --git a/AndorsTrail/app/src/main/java/com/gpl/rpg/AndorsTrail/resource/parsers/json/JsonCollectionParserFor.java b/AndorsTrail/app/src/main/java/com/gpl/rpg/AndorsTrail/resource/parsers/json/JsonCollectionParserFor.java index 59aeec324..642288c3f 100644 --- a/AndorsTrail/app/src/main/java/com/gpl/rpg/AndorsTrail/resource/parsers/json/JsonCollectionParserFor.java +++ b/AndorsTrail/app/src/main/java/com/gpl/rpg/AndorsTrail/resource/parsers/json/JsonCollectionParserFor.java @@ -11,7 +11,7 @@ import org.json.JSONException; import com.gpl.rpg.AndorsTrail.AndorsTrailApplication; import com.gpl.rpg.AndorsTrail.util.L; -import com.gpl.rpg.AndorsTrail.util.Pair; +import android.util.Pair; public abstract class JsonCollectionParserFor extends JsonParserFor> { public HashSet parseRows(String input, HashMap dest) { diff --git a/AndorsTrail/app/src/main/java/com/gpl/rpg/AndorsTrail/util/Pair.java b/AndorsTrail/app/src/main/java/com/gpl/rpg/AndorsTrail/util/Pair.java deleted file mode 100644 index 663dc10c7..000000000 --- a/AndorsTrail/app/src/main/java/com/gpl/rpg/AndorsTrail/util/Pair.java +++ /dev/null @@ -1,11 +0,0 @@ -package com.gpl.rpg.AndorsTrail.util; - -// Should really use android.util.Pair<> instead, but it is not available for API level 4 (Android 1.6). -public final class Pair { - public final T1 first; - public final T2 second; - public Pair(T1 a, T2 b) { - this.first = a; - this.second = b; - } -} From a09176d3448ccc6b8539f30c2f3475a0e6d5746d Mon Sep 17 00:00:00 2001 From: OMGeeky Date: Tue, 29 Jul 2025 03:05:50 +0200 Subject: [PATCH 15/21] Refactor activity view setup to use app.setView for consistency --- .../AndorsTrail/AndorsTrailApplication.java | 27 ++++++++++++------- .../AndorsTrail/activity/AboutActivity.java | 4 +-- .../activity/BulkSelectionInterface.java | 1 + .../activity/DisplayWorldMapActivity.java | 5 +--- .../activity/HeroinfoActivity.java | 5 +--- .../activity/ItemInfoActivity.java | 2 +- .../activity/LoadSaveActivity.java | 1 + .../AndorsTrail/activity/LoadingActivity.java | 3 +-- .../AndorsTrail/activity/MainActivity.java | 4 +-- .../rpg/AndorsTrail/activity/Preferences.java | 2 +- .../AndorsTrail/activity/ShopActivity.java | 3 +-- .../activity/SkillInfoActivity.java | 4 +-- .../activity/StartScreenActivity.java | 3 +-- .../AndorsTrail/view/CustomDialogFactory.java | 4 +-- 14 files changed, 33 insertions(+), 35 deletions(-) diff --git a/AndorsTrail/app/src/main/java/com/gpl/rpg/AndorsTrail/AndorsTrailApplication.java b/AndorsTrail/app/src/main/java/com/gpl/rpg/AndorsTrail/AndorsTrailApplication.java index ede2dbbf7..724c3c102 100644 --- a/AndorsTrail/app/src/main/java/com/gpl/rpg/AndorsTrail/AndorsTrailApplication.java +++ b/AndorsTrail/app/src/main/java/com/gpl/rpg/AndorsTrail/AndorsTrailApplication.java @@ -22,6 +22,8 @@ import android.view.WindowInsets; import android.view.WindowInsetsController; import android.view.WindowManager; +import androidx.annotation.LayoutRes; + public final class AndorsTrailApplication extends Application { public static final boolean DEVELOPMENT_DEBUGRESOURCES = false; @@ -58,28 +60,35 @@ public final class AndorsTrailApplication extends Application { public boolean isInitialized() { return world.model != null; } + public void setView(Activity activity, @LayoutRes int about) { + setWindowParameters(activity); + activity.setContentView(about); + setFullscreenMode(activity); + } public void setWindowParameters(Activity activity) { activity.requestWindowFeature(Window.FEATURE_NO_TITLE); - setFullscreenMode(preferences.fullscreen, activity.getWindow()); } + public void setFullscreenMode(Activity activity) { + setFullscreenMode(preferences.fullscreen, activity.getWindow()); + } public static void setFullscreenMode(boolean fullscreen, Window window) { if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.R) { final WindowInsetsController insetsController = window.getInsetsController(); if (insetsController != null) { +// insetsController.show(WindowInsets.Type.displayCutout()); if (fullscreen) { - insetsController.hide(WindowInsets.Type.statusBars()); + insetsController.hide(WindowInsets.Type.systemBars()); } else { - insetsController.show(WindowInsets.Type.statusBars()); + insetsController.show(WindowInsets.Type.systemBars()); } } - } else { - if (fullscreen) { - window.setFlags(WindowManager.LayoutParams.FLAG_FULLSCREEN, WindowManager.LayoutParams.FLAG_FULLSCREEN); + } + if (fullscreen) { + window.setFlags(WindowManager.LayoutParams.FLAG_FULLSCREEN, WindowManager.LayoutParams.FLAG_FULLSCREEN); - } else { - window.setFlags(0, WindowManager.LayoutParams.FLAG_FULLSCREEN); - } + } else { + window.setFlags(0, WindowManager.LayoutParams.FLAG_FULLSCREEN); } } diff --git a/AndorsTrail/app/src/main/java/com/gpl/rpg/AndorsTrail/activity/AboutActivity.java b/AndorsTrail/app/src/main/java/com/gpl/rpg/AndorsTrail/activity/AboutActivity.java index ceafb5ee1..47d741cb4 100644 --- a/AndorsTrail/app/src/main/java/com/gpl/rpg/AndorsTrail/activity/AboutActivity.java +++ b/AndorsTrail/app/src/main/java/com/gpl/rpg/AndorsTrail/activity/AboutActivity.java @@ -24,9 +24,7 @@ public final class AboutActivity extends AndorsTrailBaseActivity implements Imag super.onCreate(savedInstanceState); AndorsTrailApplication app = AndorsTrailApplication.getApplicationFromActivity(this); - app.setWindowParameters(this); - - setContentView(R.layout.about); + app.setView(this, R.layout.about); final Resources res = getResources(); final TextView tv = (TextView) findViewById(R.id.about_contents); diff --git a/AndorsTrail/app/src/main/java/com/gpl/rpg/AndorsTrail/activity/BulkSelectionInterface.java b/AndorsTrail/app/src/main/java/com/gpl/rpg/AndorsTrail/activity/BulkSelectionInterface.java index 3c928623d..1137426cb 100644 --- a/AndorsTrail/app/src/main/java/com/gpl/rpg/AndorsTrail/activity/BulkSelectionInterface.java +++ b/AndorsTrail/app/src/main/java/com/gpl/rpg/AndorsTrail/activity/BulkSelectionInterface.java @@ -91,6 +91,7 @@ public final class BulkSelectionInterface extends AndorsTrailBaseActivity implem int intialSelection = 1; setContentView(R.layout.bulkselection); + app.setFullscreenMode(this); // initialize UI variables TextView bulkselection_action_type = (TextView)findViewById(R.id.bulkselection_action_type); diff --git a/AndorsTrail/app/src/main/java/com/gpl/rpg/AndorsTrail/activity/DisplayWorldMapActivity.java b/AndorsTrail/app/src/main/java/com/gpl/rpg/AndorsTrail/activity/DisplayWorldMapActivity.java index f5a3a3687..781f809c2 100644 --- a/AndorsTrail/app/src/main/java/com/gpl/rpg/AndorsTrail/activity/DisplayWorldMapActivity.java +++ b/AndorsTrail/app/src/main/java/com/gpl/rpg/AndorsTrail/activity/DisplayWorldMapActivity.java @@ -38,10 +38,7 @@ public final class DisplayWorldMapActivity extends AndorsTrailBaseActivity { AndorsTrailApplication app = AndorsTrailApplication.getApplicationFromActivity(this); if (!app.isInitialized()) { finish(); return; } this.world = app.getWorld(); - - app.setWindowParameters(this); - - setContentView(R.layout.displayworldmap); + app.setView(this, R.layout.displayworldmap); displayworldmap_webview = (WebView) findViewById(R.id.displayworldmap_webview); displayworldmap_webview.setBackgroundColor(ThemeHelper.getThemeColor(this, R.attr.ui_theme_displayworldmap_bg_color)); diff --git a/AndorsTrail/app/src/main/java/com/gpl/rpg/AndorsTrail/activity/HeroinfoActivity.java b/AndorsTrail/app/src/main/java/com/gpl/rpg/AndorsTrail/activity/HeroinfoActivity.java index ad4153624..d127cfaa5 100644 --- a/AndorsTrail/app/src/main/java/com/gpl/rpg/AndorsTrail/activity/HeroinfoActivity.java +++ b/AndorsTrail/app/src/main/java/com/gpl/rpg/AndorsTrail/activity/HeroinfoActivity.java @@ -29,10 +29,7 @@ public final class HeroinfoActivity extends AndorsTrailBaseFragmentActivity { AndorsTrailApplication app = AndorsTrailApplication.getApplicationFromActivity(this); if (!app.isInitialized()) { finish(); return; } this.world = app.getWorld(); - - app.setWindowParameters(this); - - setContentView(R.layout.tabbedlayout); + app.setView(this, R.layout.tabbedlayout); Resources res = getResources(); diff --git a/AndorsTrail/app/src/main/java/com/gpl/rpg/AndorsTrail/activity/ItemInfoActivity.java b/AndorsTrail/app/src/main/java/com/gpl/rpg/AndorsTrail/activity/ItemInfoActivity.java index 2750e844c..d8515e674 100644 --- a/AndorsTrail/app/src/main/java/com/gpl/rpg/AndorsTrail/activity/ItemInfoActivity.java +++ b/AndorsTrail/app/src/main/java/com/gpl/rpg/AndorsTrail/activity/ItemInfoActivity.java @@ -46,7 +46,7 @@ public final class ItemInfoActivity extends AndorsTrailBaseActivity { boolean buttonEnabled = params.getBoolean("buttonEnabled"); boolean moreButtonEnabled = params.getBoolean("moreActions"); - setContentView(R.layout.iteminfo); + app.setView(this, R.layout.iteminfo); TextView tv = (TextView) findViewById(R.id.iteminfo_title); tv.setText(itemType.getName(world.model.player)); diff --git a/AndorsTrail/app/src/main/java/com/gpl/rpg/AndorsTrail/activity/LoadSaveActivity.java b/AndorsTrail/app/src/main/java/com/gpl/rpg/AndorsTrail/activity/LoadSaveActivity.java index e2fb26f3d..a224380f3 100644 --- a/AndorsTrail/app/src/main/java/com/gpl/rpg/AndorsTrail/activity/LoadSaveActivity.java +++ b/AndorsTrail/app/src/main/java/com/gpl/rpg/AndorsTrail/activity/LoadSaveActivity.java @@ -71,6 +71,7 @@ public final class LoadSaveActivity extends AndorsTrailBaseActivity implements O isLoading = (loadsave.equalsIgnoreCase("load")); setContentView(R.layout.loadsave); + app.setFullscreenMode(this); TextView tv = (TextView) findViewById(R.id.loadsave_title); if (isLoading) { diff --git a/AndorsTrail/app/src/main/java/com/gpl/rpg/AndorsTrail/activity/LoadingActivity.java b/AndorsTrail/app/src/main/java/com/gpl/rpg/AndorsTrail/activity/LoadingActivity.java index a8d9bc232..96979c2f1 100644 --- a/AndorsTrail/app/src/main/java/com/gpl/rpg/AndorsTrail/activity/LoadingActivity.java +++ b/AndorsTrail/app/src/main/java/com/gpl/rpg/AndorsTrail/activity/LoadingActivity.java @@ -36,8 +36,7 @@ public final class LoadingActivity extends AndorsTrailBaseActivity implements On setTheme(ThemeHelper.getBaseTheme()); super.onCreate(savedInstanceState); AndorsTrailApplication app = AndorsTrailApplication.getApplicationFromActivity(this); - app.setWindowParameters(this); - setContentView(R.layout.startscreen); + app.setView(this, R.layout.startscreen); TextView tv = (TextView) findViewById(R.id.startscreen_version); tv.setVisibility(View.GONE); diff --git a/AndorsTrail/app/src/main/java/com/gpl/rpg/AndorsTrail/activity/MainActivity.java b/AndorsTrail/app/src/main/java/com/gpl/rpg/AndorsTrail/activity/MainActivity.java index 3ca1b476e..e2e6472d2 100644 --- a/AndorsTrail/app/src/main/java/com/gpl/rpg/AndorsTrail/activity/MainActivity.java +++ b/AndorsTrail/app/src/main/java/com/gpl/rpg/AndorsTrail/activity/MainActivity.java @@ -91,9 +91,9 @@ public final class MainActivity AndorsTrailPreferences preferences = app.getPreferences(); this.world = app.getWorld(); this.controllers = app.getControllerContext(); - app.setWindowParameters(this); - setContentView(R.layout.main); + app.setView(this, R.layout.main); + mainview = (MainView) findViewById(R.id.main_mainview); statusview = (StatusView) findViewById(R.id.main_statusview); combatview = (CombatView) findViewById(R.id.main_combatview); diff --git a/AndorsTrail/app/src/main/java/com/gpl/rpg/AndorsTrail/activity/Preferences.java b/AndorsTrail/app/src/main/java/com/gpl/rpg/AndorsTrail/activity/Preferences.java index 83957feaf..275148baf 100644 --- a/AndorsTrail/app/src/main/java/com/gpl/rpg/AndorsTrail/activity/Preferences.java +++ b/AndorsTrail/app/src/main/java/com/gpl/rpg/AndorsTrail/activity/Preferences.java @@ -16,7 +16,7 @@ public final class Preferences extends PreferenceActivity { requestWindowFeature(Window.FEATURE_NO_TITLE); super.onCreate(savedInstanceState); AndorsTrailApplication app = AndorsTrailApplication.getApplicationFromActivity(this); - AndorsTrailApplication.setFullscreenMode(app.getPreferences().fullscreen, getWindow()); + app.setFullscreenMode(this); app.setLocale(this); diff --git a/AndorsTrail/app/src/main/java/com/gpl/rpg/AndorsTrail/activity/ShopActivity.java b/AndorsTrail/app/src/main/java/com/gpl/rpg/AndorsTrail/activity/ShopActivity.java index e1e76dbf8..b8b427158 100644 --- a/AndorsTrail/app/src/main/java/com/gpl/rpg/AndorsTrail/activity/ShopActivity.java +++ b/AndorsTrail/app/src/main/java/com/gpl/rpg/AndorsTrail/activity/ShopActivity.java @@ -23,9 +23,8 @@ public final class ShopActivity extends AndorsTrailBaseFragmentActivity { AndorsTrailApplication app = AndorsTrailApplication.getApplicationFromActivity(this); if (!app.isInitialized()) { finish(); return; } - app.setWindowParameters(this); - setContentView(R.layout.tabbedlayout); + app.setView(this, R.layout.tabbedlayout); final Resources res = getResources(); diff --git a/AndorsTrail/app/src/main/java/com/gpl/rpg/AndorsTrail/activity/SkillInfoActivity.java b/AndorsTrail/app/src/main/java/com/gpl/rpg/AndorsTrail/activity/SkillInfoActivity.java index b066d8ee8..cbe9da732 100644 --- a/AndorsTrail/app/src/main/java/com/gpl/rpg/AndorsTrail/activity/SkillInfoActivity.java +++ b/AndorsTrail/app/src/main/java/com/gpl/rpg/AndorsTrail/activity/SkillInfoActivity.java @@ -31,9 +31,7 @@ public final class SkillInfoActivity extends AndorsTrailBaseActivity { final WorldContext world = app.getWorld(); final Player player = world.model.player; - app.setWindowParameters(this); - - setContentView(R.layout.skill_info_view); + app.setView(this, R.layout.skill_info_view); final Resources res = getResources(); final Intent intent = getIntent(); diff --git a/AndorsTrail/app/src/main/java/com/gpl/rpg/AndorsTrail/activity/StartScreenActivity.java b/AndorsTrail/app/src/main/java/com/gpl/rpg/AndorsTrail/activity/StartScreenActivity.java index 245d7d6a8..d03b01fa4 100644 --- a/AndorsTrail/app/src/main/java/com/gpl/rpg/AndorsTrail/activity/StartScreenActivity.java +++ b/AndorsTrail/app/src/main/java/com/gpl/rpg/AndorsTrail/activity/StartScreenActivity.java @@ -51,9 +51,8 @@ public final class StartScreenActivity extends AndorsTrailBaseFragmentActivity i final Resources res = getResources(); TileManager tileManager = app.getWorld().tileManager; tileManager.setDensity(res); - app.setWindowParameters(this); - setContentView(R.layout.startscreen); + app.setView(this, R.layout.startscreen); if (findViewById(R.id.startscreen_fragment_container) != null) { StartScreenActivity_MainMenu mainMenu = new StartScreenActivity_MainMenu(); diff --git a/AndorsTrail/app/src/main/java/com/gpl/rpg/AndorsTrail/view/CustomDialogFactory.java b/AndorsTrail/app/src/main/java/com/gpl/rpg/AndorsTrail/view/CustomDialogFactory.java index 942258691..051cae34f 100644 --- a/AndorsTrail/app/src/main/java/com/gpl/rpg/AndorsTrail/view/CustomDialogFactory.java +++ b/AndorsTrail/app/src/main/java/com/gpl/rpg/AndorsTrail/view/CustomDialogFactory.java @@ -13,7 +13,6 @@ import android.view.View.OnClickListener; import android.view.ViewGroup; import android.view.ViewGroup.LayoutParams; import android.view.Window; -import android.view.WindowManager; import android.widget.Button; import android.widget.TextView; @@ -76,7 +75,8 @@ public class CustomDialogFactory { dialog.requestWindowFeature(Window.FEATURE_NO_TITLE); dialog.setContentView(R.layout.custom_dialog_title_icon); dialog.getWindow().setBackgroundDrawableResource(android.R.color.transparent); - AndorsTrailApplication.setFullscreenMode(((AndorsTrailApplication)context.getApplicationContext()).getPreferences().fullscreen, dialog.getWindow()); + boolean fullscreen = ((AndorsTrailApplication) context.getApplicationContext()).getPreferences().fullscreen; + AndorsTrailApplication.setFullscreenMode(fullscreen, dialog.getWindow()); setTitle(dialog, title, icon); From 363a395169669fbf55c21d911ce1e0a5ab77c9dd Mon Sep 17 00:00:00 2001 From: OMGeeky Date: Tue, 29 Jul 2025 03:33:10 +0200 Subject: [PATCH 16/21] start implementing edge-to-edge behaviour and insets --- AndorsTrail/app/build.gradle | 4 +-- .../AndorsTrail/AndorsTrailApplication.java | 25 ++++++++++++++++++- .../StartScreenActivity_MainMenu.java | 3 ++- .../fragment/StartScreenActivity_NewGame.java | 6 +++-- 4 files changed, 32 insertions(+), 6 deletions(-) diff --git a/AndorsTrail/app/build.gradle b/AndorsTrail/app/build.gradle index f0b4b0ba5..a1c1fc9b1 100644 --- a/AndorsTrail/app/build.gradle +++ b/AndorsTrail/app/build.gradle @@ -2,12 +2,12 @@ apply plugin: 'com.android.application' android { - compileSdkVersion 34 + compileSdkVersion 35 defaultConfig { applicationId "com.gpl.rpg.AndorsTrail" minSdkVersion 14 - targetSdkVersion 34 + targetSdkVersion 35 } buildTypes { diff --git a/AndorsTrail/app/src/main/java/com/gpl/rpg/AndorsTrail/AndorsTrailApplication.java b/AndorsTrail/app/src/main/java/com/gpl/rpg/AndorsTrail/AndorsTrailApplication.java index 724c3c102..9682ed2f4 100644 --- a/AndorsTrail/app/src/main/java/com/gpl/rpg/AndorsTrail/AndorsTrailApplication.java +++ b/AndorsTrail/app/src/main/java/com/gpl/rpg/AndorsTrail/AndorsTrailApplication.java @@ -14,9 +14,11 @@ import android.app.Application; import android.content.Context; import android.content.res.Configuration; import android.content.res.Resources; +import android.graphics.Insets; import android.os.Build; import android.os.Environment; import android.util.Pair; +import android.view.View; import android.view.Window; import android.view.WindowInsets; import android.view.WindowInsetsController; @@ -76,7 +78,7 @@ public final class AndorsTrailApplication extends Application { if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.R) { final WindowInsetsController insetsController = window.getInsetsController(); if (insetsController != null) { -// insetsController.show(WindowInsets.Type.displayCutout()); + insetsController.show(WindowInsets.Type.displayCutout()); if (fullscreen) { insetsController.hide(WindowInsets.Type.systemBars()); } else { @@ -91,6 +93,16 @@ public final class AndorsTrailApplication extends Application { window.setFlags(0, WindowManager.LayoutParams.FLAG_FULLSCREEN); } } + public int getUsableTouchAreaInsetMask(){ + int i = 0; + if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.R) { + i |= WindowInsets.Type.displayCutout(); + if (!preferences.fullscreen) { + i |= WindowInsets.Type.systemBars(); + } + } + return i; + } //Get default locale at startup, as somehow it seems that changing the app's //configured locale impacts the value returned by Locale.getDefault() nowadays. @@ -194,4 +206,15 @@ public final class AndorsTrailApplication extends Application { controllers = new ControllerContext(this, world); setup = new WorldSetup(world, controllers, getApplicationContext()); } + + public void setUsablePadding(View root) { + if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.R) { + root.setOnApplyWindowInsetsListener((v, insets) -> { + Insets bars = insets.getInsets(getUsableTouchAreaInsetMask()); + v.setPadding(bars.left, bars.top, bars.right, bars.bottom); + return WindowInsets.CONSUMED; + }); + } + + } } diff --git a/AndorsTrail/app/src/main/java/com/gpl/rpg/AndorsTrail/activity/fragment/StartScreenActivity_MainMenu.java b/AndorsTrail/app/src/main/java/com/gpl/rpg/AndorsTrail/activity/fragment/StartScreenActivity_MainMenu.java index ac8c814ed..5209bdf50 100644 --- a/AndorsTrail/app/src/main/java/com/gpl/rpg/AndorsTrail/activity/fragment/StartScreenActivity_MainMenu.java +++ b/AndorsTrail/app/src/main/java/com/gpl/rpg/AndorsTrail/activity/fragment/StartScreenActivity_MainMenu.java @@ -59,12 +59,13 @@ public class StartScreenActivity_MainMenu extends Fragment { updatePreferences(false); super.onCreateView(inflater, container, savedInstanceState); - if (container != null) { container.removeAllViews(); } View root = inflater.inflate(R.layout.startscreen_mainmenu, container, false); + AndorsTrailApplication app = AndorsTrailApplication.getApplicationFromActivity(getActivity()); + app.setUsablePadding(root); save_preview_holder = (ViewGroup) root.findViewById(R.id.save_preview_holder); save_preview_hero_icon = (ImageView) root.findViewById(R.id.save_preview_hero_icon); diff --git a/AndorsTrail/app/src/main/java/com/gpl/rpg/AndorsTrail/activity/fragment/StartScreenActivity_NewGame.java b/AndorsTrail/app/src/main/java/com/gpl/rpg/AndorsTrail/activity/fragment/StartScreenActivity_NewGame.java index 0705bce29..ad817a72e 100644 --- a/AndorsTrail/app/src/main/java/com/gpl/rpg/AndorsTrail/activity/fragment/StartScreenActivity_NewGame.java +++ b/AndorsTrail/app/src/main/java/com/gpl/rpg/AndorsTrail/activity/fragment/StartScreenActivity_NewGame.java @@ -3,6 +3,7 @@ package com.gpl.rpg.AndorsTrail.activity.fragment; import android.app.Activity; import android.content.Intent; import android.os.Bundle; + import androidx.fragment.app.Fragment; import android.view.LayoutInflater; import android.view.View; @@ -39,8 +40,9 @@ public class StartScreenActivity_NewGame extends Fragment { } View root = inflater.inflate(R.layout.startscreen_newgame, container, false); - - + AndorsTrailApplication app = AndorsTrailApplication.getApplicationFromActivity(getActivity()); + app.setUsablePadding(root); + startscreen_enterheroname = (TextView) root.findViewById(R.id.startscreen_enterheroname); new SpinnerEmulator(root, R.id.startscreen_mode_selector_button, R.array.startscreen_mode_selector, R.string.startscreen_game_mode) { From cd49473e86dbac6839ae10f946b406fb65ca5b92 Mon Sep 17 00:00:00 2001 From: OMGeeky Date: Tue, 29 Jul 2025 04:06:06 +0200 Subject: [PATCH 17/21] continue implementing edge-to-edge behaviour and insets (Start-Screen) --- .../gpl/rpg/AndorsTrail/activity/StartScreenActivity.java | 6 +++++- .../activity/fragment/StartScreenActivity_MainMenu.java | 2 -- .../activity/fragment/StartScreenActivity_NewGame.java | 2 -- 3 files changed, 5 insertions(+), 5 deletions(-) diff --git a/AndorsTrail/app/src/main/java/com/gpl/rpg/AndorsTrail/activity/StartScreenActivity.java b/AndorsTrail/app/src/main/java/com/gpl/rpg/AndorsTrail/activity/StartScreenActivity.java index d03b01fa4..a379298f9 100644 --- a/AndorsTrail/app/src/main/java/com/gpl/rpg/AndorsTrail/activity/StartScreenActivity.java +++ b/AndorsTrail/app/src/main/java/com/gpl/rpg/AndorsTrail/activity/StartScreenActivity.java @@ -54,7 +54,9 @@ public final class StartScreenActivity extends AndorsTrailBaseFragmentActivity i app.setView(this, R.layout.startscreen); - if (findViewById(R.id.startscreen_fragment_container) != null) { + View startscreen_fragment_container = findViewById(R.id.startscreen_fragment_container); + if (startscreen_fragment_container != null) { + app.setUsablePadding(startscreen_fragment_container); StartScreenActivity_MainMenu mainMenu = new StartScreenActivity_MainMenu(); getSupportFragmentManager().beginTransaction() @@ -68,9 +70,11 @@ public final class StartScreenActivity extends AndorsTrailBaseFragmentActivity i tv = (TextView) findViewById(R.id.startscreen_version); + app.setUsablePadding(tv); tv.setText('v' + AndorsTrailApplication.CURRENT_VERSION_DISPLAY); development_version = (TextView) findViewById(R.id.startscreen_dev_version); + app.setUsablePadding((View) development_version.getParent()); if (AndorsTrailApplication.DEVELOPMENT_INCOMPATIBLE_SAVEGAMES) { development_version.setText(R.string.startscreen_incompatible_savegames); development_version.setVisibility(View.VISIBLE); diff --git a/AndorsTrail/app/src/main/java/com/gpl/rpg/AndorsTrail/activity/fragment/StartScreenActivity_MainMenu.java b/AndorsTrail/app/src/main/java/com/gpl/rpg/AndorsTrail/activity/fragment/StartScreenActivity_MainMenu.java index 5209bdf50..bcfd8ed3f 100644 --- a/AndorsTrail/app/src/main/java/com/gpl/rpg/AndorsTrail/activity/fragment/StartScreenActivity_MainMenu.java +++ b/AndorsTrail/app/src/main/java/com/gpl/rpg/AndorsTrail/activity/fragment/StartScreenActivity_MainMenu.java @@ -64,8 +64,6 @@ public class StartScreenActivity_MainMenu extends Fragment { } View root = inflater.inflate(R.layout.startscreen_mainmenu, container, false); - AndorsTrailApplication app = AndorsTrailApplication.getApplicationFromActivity(getActivity()); - app.setUsablePadding(root); save_preview_holder = (ViewGroup) root.findViewById(R.id.save_preview_holder); save_preview_hero_icon = (ImageView) root.findViewById(R.id.save_preview_hero_icon); diff --git a/AndorsTrail/app/src/main/java/com/gpl/rpg/AndorsTrail/activity/fragment/StartScreenActivity_NewGame.java b/AndorsTrail/app/src/main/java/com/gpl/rpg/AndorsTrail/activity/fragment/StartScreenActivity_NewGame.java index ad817a72e..4794c61d6 100644 --- a/AndorsTrail/app/src/main/java/com/gpl/rpg/AndorsTrail/activity/fragment/StartScreenActivity_NewGame.java +++ b/AndorsTrail/app/src/main/java/com/gpl/rpg/AndorsTrail/activity/fragment/StartScreenActivity_NewGame.java @@ -40,8 +40,6 @@ public class StartScreenActivity_NewGame extends Fragment { } View root = inflater.inflate(R.layout.startscreen_newgame, container, false); - AndorsTrailApplication app = AndorsTrailApplication.getApplicationFromActivity(getActivity()); - app.setUsablePadding(root); startscreen_enterheroname = (TextView) root.findViewById(R.id.startscreen_enterheroname); From ffef76b28b48d47dee2c55a3b8f57f3e6433da68 Mon Sep 17 00:00:00 2001 From: OMGeeky Date: Tue, 29 Jul 2025 05:05:40 +0200 Subject: [PATCH 18/21] continue implementing edge-to-edge behaviour and insets --- .../rpg/AndorsTrail/AndorsTrailApplication.java | 5 ----- .../rpg/AndorsTrail/activity/AboutActivity.java | 2 +- .../activity/ActorConditionInfoActivity.java | 4 +--- .../activity/AndorsTrailBaseActivity.java | 12 ++++++++++++ .../activity/AndorsTrailBaseFragmentActivity.java | 14 ++++++++++++++ .../activity/BulkSelectionInterface.java | 4 +--- .../AndorsTrail/activity/ConversationActivity.java | 2 +- .../activity/DisplayWorldMapActivity.java | 2 +- .../rpg/AndorsTrail/activity/HeroinfoActivity.java | 2 +- .../rpg/AndorsTrail/activity/ItemInfoActivity.java | 2 +- .../rpg/AndorsTrail/activity/LevelUpActivity.java | 2 +- .../rpg/AndorsTrail/activity/LoadSaveActivity.java | 3 +-- .../rpg/AndorsTrail/activity/LoadingActivity.java | 2 +- .../gpl/rpg/AndorsTrail/activity/MainActivity.java | 2 +- .../activity/MonsterEncounterActivity.java | 2 +- .../AndorsTrail/activity/MonsterInfoActivity.java | 2 +- .../gpl/rpg/AndorsTrail/activity/Preferences.java | 6 ++++-- .../gpl/rpg/AndorsTrail/activity/ShopActivity.java | 2 +- .../AndorsTrail/activity/SkillInfoActivity.java | 2 +- .../AndorsTrail/activity/StartScreenActivity.java | 7 +++---- AndorsTrail/res/layout/about.xml | 1 + AndorsTrail/res/layout/actorconditioninfo.xml | 3 ++- AndorsTrail/res/layout/bulkselection.xml | 2 +- AndorsTrail/res/layout/conversation.xml | 1 + AndorsTrail/res/layout/displayworldmap.xml | 3 ++- AndorsTrail/res/layout/iteminfo.xml | 3 ++- AndorsTrail/res/layout/levelup.xml | 3 ++- AndorsTrail/res/layout/loadsave.xml | 1 + AndorsTrail/res/layout/monsterencounter.xml | 3 ++- AndorsTrail/res/layout/monsterinfo.xml | 3 ++- AndorsTrail/res/layout/skill_info_view.xml | 3 ++- 31 files changed, 66 insertions(+), 39 deletions(-) diff --git a/AndorsTrail/app/src/main/java/com/gpl/rpg/AndorsTrail/AndorsTrailApplication.java b/AndorsTrail/app/src/main/java/com/gpl/rpg/AndorsTrail/AndorsTrailApplication.java index 9682ed2f4..f655b0602 100644 --- a/AndorsTrail/app/src/main/java/com/gpl/rpg/AndorsTrail/AndorsTrailApplication.java +++ b/AndorsTrail/app/src/main/java/com/gpl/rpg/AndorsTrail/AndorsTrailApplication.java @@ -62,11 +62,6 @@ public final class AndorsTrailApplication extends Application { public boolean isInitialized() { return world.model != null; } - public void setView(Activity activity, @LayoutRes int about) { - setWindowParameters(activity); - activity.setContentView(about); - setFullscreenMode(activity); - } public void setWindowParameters(Activity activity) { activity.requestWindowFeature(Window.FEATURE_NO_TITLE); } diff --git a/AndorsTrail/app/src/main/java/com/gpl/rpg/AndorsTrail/activity/AboutActivity.java b/AndorsTrail/app/src/main/java/com/gpl/rpg/AndorsTrail/activity/AboutActivity.java index 47d741cb4..fa8b38647 100644 --- a/AndorsTrail/app/src/main/java/com/gpl/rpg/AndorsTrail/activity/AboutActivity.java +++ b/AndorsTrail/app/src/main/java/com/gpl/rpg/AndorsTrail/activity/AboutActivity.java @@ -24,7 +24,7 @@ public final class AboutActivity extends AndorsTrailBaseActivity implements Imag super.onCreate(savedInstanceState); AndorsTrailApplication app = AndorsTrailApplication.getApplicationFromActivity(this); - app.setView(this, R.layout.about); + initializeView(this, R.layout.about, R.id.about_root); final Resources res = getResources(); final TextView tv = (TextView) findViewById(R.id.about_contents); diff --git a/AndorsTrail/app/src/main/java/com/gpl/rpg/AndorsTrail/activity/ActorConditionInfoActivity.java b/AndorsTrail/app/src/main/java/com/gpl/rpg/AndorsTrail/activity/ActorConditionInfoActivity.java index 6354edf6c..d2a9e0dfb 100644 --- a/AndorsTrail/app/src/main/java/com/gpl/rpg/AndorsTrail/activity/ActorConditionInfoActivity.java +++ b/AndorsTrail/app/src/main/java/com/gpl/rpg/AndorsTrail/activity/ActorConditionInfoActivity.java @@ -30,9 +30,7 @@ public final class ActorConditionInfoActivity extends AndorsTrailBaseActivity { String conditionTypeID = getIntent().getData().getLastPathSegment(); ActorConditionType conditionType = world.actorConditionsTypes.getActorConditionType(conditionTypeID); - - setContentView(R.layout.actorconditioninfo); - + initializeView(this, R.layout.actorconditioninfo, R.id.actorconditioninfo_root); TextView tv = (TextView) findViewById(R.id.actorconditioninfo_title); tv.setText(conditionType.name); diff --git a/AndorsTrail/app/src/main/java/com/gpl/rpg/AndorsTrail/activity/AndorsTrailBaseActivity.java b/AndorsTrail/app/src/main/java/com/gpl/rpg/AndorsTrail/activity/AndorsTrailBaseActivity.java index 83f8a4d07..598ff027a 100644 --- a/AndorsTrail/app/src/main/java/com/gpl/rpg/AndorsTrail/activity/AndorsTrailBaseActivity.java +++ b/AndorsTrail/app/src/main/java/com/gpl/rpg/AndorsTrail/activity/AndorsTrailBaseActivity.java @@ -2,6 +2,10 @@ package com.gpl.rpg.AndorsTrail.activity; import android.app.Activity; import android.os.Bundle; +import android.view.View; + +import androidx.annotation.IdRes; +import androidx.annotation.LayoutRes; import com.gpl.rpg.AndorsTrail.AndorsTrailApplication; @@ -19,5 +23,13 @@ public abstract class AndorsTrailBaseActivity extends Activity { AndorsTrailApplication app = AndorsTrailApplication.getApplicationFromActivity(this); app.setLocale(this); } + protected void initializeView(Activity activity, @LayoutRes int layoutId, @IdRes int rootViewId) { + AndorsTrailApplication app = AndorsTrailApplication.getApplicationFromActivity(activity); + app.setWindowParameters(activity); + activity.setContentView(layoutId); + View root = activity.findViewById(rootViewId); + app.setUsablePadding(root); + app.setFullscreenMode(activity); + } } diff --git a/AndorsTrail/app/src/main/java/com/gpl/rpg/AndorsTrail/activity/AndorsTrailBaseFragmentActivity.java b/AndorsTrail/app/src/main/java/com/gpl/rpg/AndorsTrail/activity/AndorsTrailBaseFragmentActivity.java index fc6f573f4..591192c68 100644 --- a/AndorsTrail/app/src/main/java/com/gpl/rpg/AndorsTrail/activity/AndorsTrailBaseFragmentActivity.java +++ b/AndorsTrail/app/src/main/java/com/gpl/rpg/AndorsTrail/activity/AndorsTrailBaseFragmentActivity.java @@ -1,6 +1,11 @@ package com.gpl.rpg.AndorsTrail.activity; +import android.app.Activity; import android.os.Bundle; +import android.view.View; + +import androidx.annotation.IdRes; +import androidx.annotation.LayoutRes; import androidx.fragment.app.FragmentActivity; import com.gpl.rpg.AndorsTrail.AndorsTrailApplication; @@ -19,4 +24,13 @@ public abstract class AndorsTrailBaseFragmentActivity extends FragmentActivity { AndorsTrailApplication app = AndorsTrailApplication.getApplicationFromActivity(this); app.setLocale(this); } + + protected void initializeView(Activity activity, @LayoutRes int layoutId, @IdRes int rootViewId) { + AndorsTrailApplication app = AndorsTrailApplication.getApplicationFromActivity(activity); + app.setWindowParameters(activity); + activity.setContentView(layoutId); + View root = activity.findViewById(rootViewId); + app.setUsablePadding(root); + app.setFullscreenMode(activity); + } } diff --git a/AndorsTrail/app/src/main/java/com/gpl/rpg/AndorsTrail/activity/BulkSelectionInterface.java b/AndorsTrail/app/src/main/java/com/gpl/rpg/AndorsTrail/activity/BulkSelectionInterface.java index 1137426cb..874591929 100644 --- a/AndorsTrail/app/src/main/java/com/gpl/rpg/AndorsTrail/activity/BulkSelectionInterface.java +++ b/AndorsTrail/app/src/main/java/com/gpl/rpg/AndorsTrail/activity/BulkSelectionInterface.java @@ -89,9 +89,7 @@ public final class BulkSelectionInterface extends AndorsTrailBaseActivity implem interfaceType = BulkInterfaceType.valueOf(params.getString("interfaceType")); int intialSelection = 1; - - setContentView(R.layout.bulkselection); - app.setFullscreenMode(this); + initializeView(this, R.layout.bulkselection, R.id.bulkselection_root); // initialize UI variables TextView bulkselection_action_type = (TextView)findViewById(R.id.bulkselection_action_type); diff --git a/AndorsTrail/app/src/main/java/com/gpl/rpg/AndorsTrail/activity/ConversationActivity.java b/AndorsTrail/app/src/main/java/com/gpl/rpg/AndorsTrail/activity/ConversationActivity.java index 95421cc48..5a98e9c68 100644 --- a/AndorsTrail/app/src/main/java/com/gpl/rpg/AndorsTrail/activity/ConversationActivity.java +++ b/AndorsTrail/app/src/main/java/com/gpl/rpg/AndorsTrail/activity/ConversationActivity.java @@ -75,7 +75,7 @@ public final class ConversationActivity requestWindowFeature(Window.FEATURE_NO_TITLE); - setContentView(R.layout.conversation); + initializeView(this, R.layout.conversation, R.id.conversation_root); setFinishOnTouchOutside(false); diff --git a/AndorsTrail/app/src/main/java/com/gpl/rpg/AndorsTrail/activity/DisplayWorldMapActivity.java b/AndorsTrail/app/src/main/java/com/gpl/rpg/AndorsTrail/activity/DisplayWorldMapActivity.java index 781f809c2..f7c5ce397 100644 --- a/AndorsTrail/app/src/main/java/com/gpl/rpg/AndorsTrail/activity/DisplayWorldMapActivity.java +++ b/AndorsTrail/app/src/main/java/com/gpl/rpg/AndorsTrail/activity/DisplayWorldMapActivity.java @@ -38,7 +38,7 @@ public final class DisplayWorldMapActivity extends AndorsTrailBaseActivity { AndorsTrailApplication app = AndorsTrailApplication.getApplicationFromActivity(this); if (!app.isInitialized()) { finish(); return; } this.world = app.getWorld(); - app.setView(this, R.layout.displayworldmap); + initializeView(this, R.layout.displayworldmap, R.id.worldmap_root); displayworldmap_webview = (WebView) findViewById(R.id.displayworldmap_webview); displayworldmap_webview.setBackgroundColor(ThemeHelper.getThemeColor(this, R.attr.ui_theme_displayworldmap_bg_color)); diff --git a/AndorsTrail/app/src/main/java/com/gpl/rpg/AndorsTrail/activity/HeroinfoActivity.java b/AndorsTrail/app/src/main/java/com/gpl/rpg/AndorsTrail/activity/HeroinfoActivity.java index d127cfaa5..6106cda38 100644 --- a/AndorsTrail/app/src/main/java/com/gpl/rpg/AndorsTrail/activity/HeroinfoActivity.java +++ b/AndorsTrail/app/src/main/java/com/gpl/rpg/AndorsTrail/activity/HeroinfoActivity.java @@ -29,7 +29,7 @@ public final class HeroinfoActivity extends AndorsTrailBaseFragmentActivity { AndorsTrailApplication app = AndorsTrailApplication.getApplicationFromActivity(this); if (!app.isInitialized()) { finish(); return; } this.world = app.getWorld(); - app.setView(this, R.layout.tabbedlayout); + initializeView(this, R.layout.tabbedlayout, android.R.id.tabhost); Resources res = getResources(); diff --git a/AndorsTrail/app/src/main/java/com/gpl/rpg/AndorsTrail/activity/ItemInfoActivity.java b/AndorsTrail/app/src/main/java/com/gpl/rpg/AndorsTrail/activity/ItemInfoActivity.java index d8515e674..4fcc1719a 100644 --- a/AndorsTrail/app/src/main/java/com/gpl/rpg/AndorsTrail/activity/ItemInfoActivity.java +++ b/AndorsTrail/app/src/main/java/com/gpl/rpg/AndorsTrail/activity/ItemInfoActivity.java @@ -46,7 +46,7 @@ public final class ItemInfoActivity extends AndorsTrailBaseActivity { boolean buttonEnabled = params.getBoolean("buttonEnabled"); boolean moreButtonEnabled = params.getBoolean("moreActions"); - app.setView(this, R.layout.iteminfo); + initializeView(this, R.layout.iteminfo, R.id.iteminfo_root); TextView tv = (TextView) findViewById(R.id.iteminfo_title); tv.setText(itemType.getName(world.model.player)); diff --git a/AndorsTrail/app/src/main/java/com/gpl/rpg/AndorsTrail/activity/LevelUpActivity.java b/AndorsTrail/app/src/main/java/com/gpl/rpg/AndorsTrail/activity/LevelUpActivity.java index 3f9831aa5..5a891754f 100644 --- a/AndorsTrail/app/src/main/java/com/gpl/rpg/AndorsTrail/activity/LevelUpActivity.java +++ b/AndorsTrail/app/src/main/java/com/gpl/rpg/AndorsTrail/activity/LevelUpActivity.java @@ -37,7 +37,7 @@ public final class LevelUpActivity extends AndorsTrailBaseActivity { requestWindowFeature(Window.FEATURE_NO_TITLE); - setContentView(R.layout.levelup); + initializeView(this, R.layout.levelup, R.id.levelup_root); levelup_title = (TextView) findViewById(R.id.levelup_title); levelup_description = (TextView) findViewById(R.id.levelup_description); diff --git a/AndorsTrail/app/src/main/java/com/gpl/rpg/AndorsTrail/activity/LoadSaveActivity.java b/AndorsTrail/app/src/main/java/com/gpl/rpg/AndorsTrail/activity/LoadSaveActivity.java index a224380f3..183ed5afc 100644 --- a/AndorsTrail/app/src/main/java/com/gpl/rpg/AndorsTrail/activity/LoadSaveActivity.java +++ b/AndorsTrail/app/src/main/java/com/gpl/rpg/AndorsTrail/activity/LoadSaveActivity.java @@ -70,8 +70,7 @@ public final class LoadSaveActivity extends AndorsTrailBaseActivity implements O String loadsave = getIntent().getData().getLastPathSegment(); isLoading = (loadsave.equalsIgnoreCase("load")); - setContentView(R.layout.loadsave); - app.setFullscreenMode(this); + initializeView(this, R.layout.loadsave, R.id.loadsave_root); TextView tv = (TextView) findViewById(R.id.loadsave_title); if (isLoading) { diff --git a/AndorsTrail/app/src/main/java/com/gpl/rpg/AndorsTrail/activity/LoadingActivity.java b/AndorsTrail/app/src/main/java/com/gpl/rpg/AndorsTrail/activity/LoadingActivity.java index 96979c2f1..6def27a7e 100644 --- a/AndorsTrail/app/src/main/java/com/gpl/rpg/AndorsTrail/activity/LoadingActivity.java +++ b/AndorsTrail/app/src/main/java/com/gpl/rpg/AndorsTrail/activity/LoadingActivity.java @@ -36,7 +36,7 @@ public final class LoadingActivity extends AndorsTrailBaseActivity implements On setTheme(ThemeHelper.getBaseTheme()); super.onCreate(savedInstanceState); AndorsTrailApplication app = AndorsTrailApplication.getApplicationFromActivity(this); - app.setView(this, R.layout.startscreen); + initializeView(this, R.layout.startscreen, R.id.startscreen_fragment_container); TextView tv = (TextView) findViewById(R.id.startscreen_version); tv.setVisibility(View.GONE); diff --git a/AndorsTrail/app/src/main/java/com/gpl/rpg/AndorsTrail/activity/MainActivity.java b/AndorsTrail/app/src/main/java/com/gpl/rpg/AndorsTrail/activity/MainActivity.java index e2e6472d2..e2cf01ac2 100644 --- a/AndorsTrail/app/src/main/java/com/gpl/rpg/AndorsTrail/activity/MainActivity.java +++ b/AndorsTrail/app/src/main/java/com/gpl/rpg/AndorsTrail/activity/MainActivity.java @@ -92,7 +92,7 @@ public final class MainActivity this.world = app.getWorld(); this.controllers = app.getControllerContext(); - app.setView(this, R.layout.main); + initializeView(this, R.layout.main, R.id.main_container); mainview = (MainView) findViewById(R.id.main_mainview); statusview = (StatusView) findViewById(R.id.main_statusview); diff --git a/AndorsTrail/app/src/main/java/com/gpl/rpg/AndorsTrail/activity/MonsterEncounterActivity.java b/AndorsTrail/app/src/main/java/com/gpl/rpg/AndorsTrail/activity/MonsterEncounterActivity.java index 5d11ea8a5..e50f2d28e 100644 --- a/AndorsTrail/app/src/main/java/com/gpl/rpg/AndorsTrail/activity/MonsterEncounterActivity.java +++ b/AndorsTrail/app/src/main/java/com/gpl/rpg/AndorsTrail/activity/MonsterEncounterActivity.java @@ -34,7 +34,7 @@ public final class MonsterEncounterActivity extends AndorsTrailBaseActivity { return; } - setContentView(R.layout.monsterencounter); + initializeView(this, R.layout.monsterencounter, R.id.monsterencounter_root); CharSequence difficulty = getText(MonsterInfoActivity.getMonsterDifficultyResource(controllers, monster)); diff --git a/AndorsTrail/app/src/main/java/com/gpl/rpg/AndorsTrail/activity/MonsterInfoActivity.java b/AndorsTrail/app/src/main/java/com/gpl/rpg/AndorsTrail/activity/MonsterInfoActivity.java index 219e60c15..e7f6ec22a 100644 --- a/AndorsTrail/app/src/main/java/com/gpl/rpg/AndorsTrail/activity/MonsterInfoActivity.java +++ b/AndorsTrail/app/src/main/java/com/gpl/rpg/AndorsTrail/activity/MonsterInfoActivity.java @@ -43,7 +43,7 @@ public final class MonsterInfoActivity extends AndorsTrailBaseActivity { this.controllers = app.getControllerContext(); requestWindowFeature(Window.FEATURE_NO_TITLE); - setContentView(R.layout.monsterinfo); + initializeView(this, R.layout.monsterinfo, R.id.monsterinfo_root); monsterinfo_title = (TextView) findViewById(R.id.monsterinfo_title); monsterinfo_difficulty = (TextView) findViewById(R.id.monsterinfo_difficulty); diff --git a/AndorsTrail/app/src/main/java/com/gpl/rpg/AndorsTrail/activity/Preferences.java b/AndorsTrail/app/src/main/java/com/gpl/rpg/AndorsTrail/activity/Preferences.java index 275148baf..d46e704e0 100644 --- a/AndorsTrail/app/src/main/java/com/gpl/rpg/AndorsTrail/activity/Preferences.java +++ b/AndorsTrail/app/src/main/java/com/gpl/rpg/AndorsTrail/activity/Preferences.java @@ -13,14 +13,16 @@ public final class Preferences extends PreferenceActivity { @Override protected void onCreate(Bundle savedInstanceState) { setTheme(ThemeHelper.getBaseTheme()); - requestWindowFeature(Window.FEATURE_NO_TITLE); - super.onCreate(savedInstanceState); AndorsTrailApplication app = AndorsTrailApplication.getApplicationFromActivity(this); + app.setWindowParameters(this); + super.onCreate(savedInstanceState); app.setFullscreenMode(this); app.setLocale(this); addPreferencesFromResource(R.xml.preferences); + + } @Override diff --git a/AndorsTrail/app/src/main/java/com/gpl/rpg/AndorsTrail/activity/ShopActivity.java b/AndorsTrail/app/src/main/java/com/gpl/rpg/AndorsTrail/activity/ShopActivity.java index b8b427158..235348917 100644 --- a/AndorsTrail/app/src/main/java/com/gpl/rpg/AndorsTrail/activity/ShopActivity.java +++ b/AndorsTrail/app/src/main/java/com/gpl/rpg/AndorsTrail/activity/ShopActivity.java @@ -24,7 +24,7 @@ public final class ShopActivity extends AndorsTrailBaseFragmentActivity { AndorsTrailApplication app = AndorsTrailApplication.getApplicationFromActivity(this); if (!app.isInitialized()) { finish(); return; } - app.setView(this, R.layout.tabbedlayout); + initializeView(this, R.layout.tabbedlayout, android.R.id.tabhost); final Resources res = getResources(); diff --git a/AndorsTrail/app/src/main/java/com/gpl/rpg/AndorsTrail/activity/SkillInfoActivity.java b/AndorsTrail/app/src/main/java/com/gpl/rpg/AndorsTrail/activity/SkillInfoActivity.java index cbe9da732..acd1bcecc 100644 --- a/AndorsTrail/app/src/main/java/com/gpl/rpg/AndorsTrail/activity/SkillInfoActivity.java +++ b/AndorsTrail/app/src/main/java/com/gpl/rpg/AndorsTrail/activity/SkillInfoActivity.java @@ -31,7 +31,7 @@ public final class SkillInfoActivity extends AndorsTrailBaseActivity { final WorldContext world = app.getWorld(); final Player player = world.model.player; - app.setView(this, R.layout.skill_info_view); + initializeView(this, R.layout.skill_info_view, R.id.skillinfo_root); final Resources res = getResources(); final Intent intent = getIntent(); diff --git a/AndorsTrail/app/src/main/java/com/gpl/rpg/AndorsTrail/activity/StartScreenActivity.java b/AndorsTrail/app/src/main/java/com/gpl/rpg/AndorsTrail/activity/StartScreenActivity.java index a379298f9..27a93601e 100644 --- a/AndorsTrail/app/src/main/java/com/gpl/rpg/AndorsTrail/activity/StartScreenActivity.java +++ b/AndorsTrail/app/src/main/java/com/gpl/rpg/AndorsTrail/activity/StartScreenActivity.java @@ -52,11 +52,10 @@ public final class StartScreenActivity extends AndorsTrailBaseFragmentActivity i TileManager tileManager = app.getWorld().tileManager; tileManager.setDensity(res); - app.setView(this, R.layout.startscreen); + initializeView(this, R.layout.startscreen, R.id.startscreen_fragment_container); + app.setFullscreenMode(this); - View startscreen_fragment_container = findViewById(R.id.startscreen_fragment_container); - if (startscreen_fragment_container != null) { - app.setUsablePadding(startscreen_fragment_container); + if (findViewById(R.id.startscreen_fragment_container) != null) { StartScreenActivity_MainMenu mainMenu = new StartScreenActivity_MainMenu(); getSupportFragmentManager().beginTransaction() diff --git a/AndorsTrail/res/layout/about.xml b/AndorsTrail/res/layout/about.xml index 3eebd04fa..2ccfefb46 100644 --- a/AndorsTrail/res/layout/about.xml +++ b/AndorsTrail/res/layout/about.xml @@ -5,6 +5,7 @@ android:layout_height="match_parent" android:padding="@dimen/dialog_margin" android:orientation="vertical" + android:id="@+id/about_root" > + android:orientation="vertical" + android:id="@+id/actorconditioninfo_root"> + android:orientation="vertical" android:id="@+id/bulkselection_root"> + android:orientation="vertical" + android:id="@+id/worldmap_root"> + android:orientation="vertical" + android:id="@+id/iteminfo_root"> + android:padding="@dimen/dialog_margin" + android:id="@+id/levelup_root"> + android:orientation="vertical" + android:id="@+id/monsterencounter_root"> + android:orientation="vertical" + android:id="@+id/monsterinfo_root"> + android:orientation="vertical" + android:id="@+id/skillinfo_root"> Date: Tue, 29 Jul 2025 05:38:01 +0200 Subject: [PATCH 19/21] setSystemBarsBehavior so it disappears automatically when in fullscreen also don't run code, that is deprecated when on higher version --- .../rpg/AndorsTrail/AndorsTrailApplication.java | 14 ++++++++------ 1 file changed, 8 insertions(+), 6 deletions(-) diff --git a/AndorsTrail/app/src/main/java/com/gpl/rpg/AndorsTrail/AndorsTrailApplication.java b/AndorsTrail/app/src/main/java/com/gpl/rpg/AndorsTrail/AndorsTrailApplication.java index f655b0602..df47121ea 100644 --- a/AndorsTrail/app/src/main/java/com/gpl/rpg/AndorsTrail/AndorsTrailApplication.java +++ b/AndorsTrail/app/src/main/java/com/gpl/rpg/AndorsTrail/AndorsTrailApplication.java @@ -24,7 +24,6 @@ import android.view.WindowInsets; import android.view.WindowInsetsController; import android.view.WindowManager; -import androidx.annotation.LayoutRes; public final class AndorsTrailApplication extends Application { @@ -71,8 +70,10 @@ public final class AndorsTrailApplication extends Application { } public static void setFullscreenMode(boolean fullscreen, Window window) { if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.R) { + final WindowInsetsController insetsController = window.getInsetsController(); if (insetsController != null) { + insetsController.setSystemBarsBehavior(WindowInsetsController.BEHAVIOR_SHOW_TRANSIENT_BARS_BY_SWIPE); insetsController.show(WindowInsets.Type.displayCutout()); if (fullscreen) { insetsController.hide(WindowInsets.Type.systemBars()); @@ -80,12 +81,13 @@ public final class AndorsTrailApplication extends Application { insetsController.show(WindowInsets.Type.systemBars()); } } - } - if (fullscreen) { - window.setFlags(WindowManager.LayoutParams.FLAG_FULLSCREEN, WindowManager.LayoutParams.FLAG_FULLSCREEN); - } else { - window.setFlags(0, WindowManager.LayoutParams.FLAG_FULLSCREEN); + if (fullscreen) { + window.setFlags(WindowManager.LayoutParams.FLAG_FULLSCREEN, WindowManager.LayoutParams.FLAG_FULLSCREEN); + + } else { + window.setFlags(0, WindowManager.LayoutParams.FLAG_FULLSCREEN); + } } } public int getUsableTouchAreaInsetMask(){ From 0d73ee10fa1580dd15de7ebf1b180969398f9887 Mon Sep 17 00:00:00 2001 From: OMGeeky Date: Tue, 29 Jul 2025 05:52:29 +0200 Subject: [PATCH 20/21] set usable padding for title logo in StartScreenActivity --- .../com/gpl/rpg/AndorsTrail/activity/StartScreenActivity.java | 4 ++++ 1 file changed, 4 insertions(+) diff --git a/AndorsTrail/app/src/main/java/com/gpl/rpg/AndorsTrail/activity/StartScreenActivity.java b/AndorsTrail/app/src/main/java/com/gpl/rpg/AndorsTrail/activity/StartScreenActivity.java index 27a93601e..64c7484a8 100644 --- a/AndorsTrail/app/src/main/java/com/gpl/rpg/AndorsTrail/activity/StartScreenActivity.java +++ b/AndorsTrail/app/src/main/java/com/gpl/rpg/AndorsTrail/activity/StartScreenActivity.java @@ -100,6 +100,10 @@ public final class StartScreenActivity extends AndorsTrailBaseFragmentActivity i } }); } + View titleLogo = findViewById(R.id.title_logo); + if (titleLogo != null) { + app.setUsablePadding(titleLogo); + } if (development_version.getVisibility() == View.VISIBLE) { development_version.setText(development_version.getText() From a4fbe2087174d40a3416b189652eb0dcd90ed912 Mon Sep 17 00:00:00 2001 From: OMGeeky Date: Sun, 3 Aug 2025 18:57:39 +0200 Subject: [PATCH 21/21] refactor window insets handling for fullscreen and touch area Signed-off-by: OMGeeky --- .../AndorsTrail/AndorsTrailApplication.java | 28 +++++++++++-------- 1 file changed, 17 insertions(+), 11 deletions(-) diff --git a/AndorsTrail/app/src/main/java/com/gpl/rpg/AndorsTrail/AndorsTrailApplication.java b/AndorsTrail/app/src/main/java/com/gpl/rpg/AndorsTrail/AndorsTrailApplication.java index df47121ea..3613a6e74 100644 --- a/AndorsTrail/app/src/main/java/com/gpl/rpg/AndorsTrail/AndorsTrailApplication.java +++ b/AndorsTrail/app/src/main/java/com/gpl/rpg/AndorsTrail/AndorsTrailApplication.java @@ -24,6 +24,8 @@ import android.view.WindowInsets; import android.view.WindowInsetsController; import android.view.WindowManager; +import androidx.annotation.RequiresApi; + public final class AndorsTrailApplication extends Application { @@ -74,11 +76,11 @@ public final class AndorsTrailApplication extends Application { final WindowInsetsController insetsController = window.getInsetsController(); if (insetsController != null) { insetsController.setSystemBarsBehavior(WindowInsetsController.BEHAVIOR_SHOW_TRANSIENT_BARS_BY_SWIPE); - insetsController.show(WindowInsets.Type.displayCutout()); + int insetType = WindowInsets.Type.statusBars(); if (fullscreen) { - insetsController.hide(WindowInsets.Type.systemBars()); + insetsController.hide(insetType); } else { - insetsController.show(WindowInsets.Type.systemBars()); + insetsController.show(insetType); } } } else { @@ -90,14 +92,15 @@ public final class AndorsTrailApplication extends Application { } } } + + @RequiresApi(Build.VERSION_CODES.R) public int getUsableTouchAreaInsetMask(){ int i = 0; - if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.R) { - i |= WindowInsets.Type.displayCutout(); - if (!preferences.fullscreen) { - i |= WindowInsets.Type.systemBars(); - } - } + i |= WindowInsets.Type.displayCutout(); + i |= WindowInsets.Type.navigationBars(); + if (!preferences.fullscreen) { + i |= WindowInsets.Type.statusBars(); + } return i; } @@ -208,10 +211,13 @@ public final class AndorsTrailApplication extends Application { if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.R) { root.setOnApplyWindowInsetsListener((v, insets) -> { Insets bars = insets.getInsets(getUsableTouchAreaInsetMask()); - v.setPadding(bars.left, bars.top, bars.right, bars.bottom); + int left = Math.max(bars.left, v.getPaddingLeft()); + int top = Math.max(bars.top, v.getPaddingTop()); + int right = Math.max(bars.right, v.getPaddingRight()); + int bottom = Math.max(bars.bottom, v.getPaddingBottom()); + v.setPadding(left, top, right, bottom); return WindowInsets.CONSUMED; }); } - } }