diff --git a/ReadMe.txt b/ReadMe.txt
index 571971e..fd07516 100644
--- a/ReadMe.txt
+++ b/ReadMe.txt
@@ -74,6 +74,8 @@ Version 1.8beta3 (2020-04-XX)
- Fix: Overlapping window source position when Background/Offset is not (0,0).
- Wrap the table of content in the former help documentation.
- Save the settings at the end of the state file.
+- Transform all child activities with dialog fragments (to prevent unwanted state save).
+- Fix an issue with the numpad keys which send the arrow keys and the numbers at the same time.
Version 1.7 (2019-12-12)
@@ -192,6 +194,8 @@ The Eric's Real scripts ("real*.kml" and "real*.bmp/png") are embedded in this a
TODO
+- Add a settings to switch between dark and light theme.
+- Increase the loading speed (for Charlemagne faceplates) if possible.
- Add the name of the file in the toast "State saved".
- The clock seems unsynchronized sometimes.
- Retain a key by right clicking if it is from a mouse.
diff --git a/app/build.gradle b/app/build.gradle
index c271469..d422cc4 100644
--- a/app/build.gradle
+++ b/app/build.gradle
@@ -28,11 +28,11 @@ if (keystorePropertiesFile.exists()) {
}
android {
- compileSdkVersion 28
+ compileSdkVersion 29
defaultConfig {
applicationId "org.emulator.forty.eight"
minSdkVersion 19
- targetSdkVersion 28
+ targetSdkVersion 29
versionCode 13
versionName "1.8beta2"
setProperty("archivesBaseName", "Emu48-v$versionName")
@@ -80,13 +80,12 @@ android {
dependencies {
implementation fileTree(dir: 'libs', include: ['*.jar'])
- implementation 'androidx.appcompat:appcompat:1.1.0'
- implementation 'androidx.constraintlayout:constraintlayout:2.0.0-beta3'
- implementation 'androidx.preference:preference:1.1.0'
- implementation 'com.google.android.material:material:1.2.0-alpha02'
- implementation 'androidx.legacy:legacy-support-v4:1.0.0'
- implementation 'androidx.viewpager:viewpager:1.0.0'
+ implementation 'androidx.appcompat:appcompat:1.2.0-beta01'
+ implementation 'androidx.constraintlayout:constraintlayout:1.1.3'
+ implementation 'androidx.preference:preference:1.1.1'
+ implementation 'com.google.android.material:material:1.1.0'
+ implementation 'androidx.documentfile:documentfile:1.0.1'
testImplementation 'junit:junit:4.13-beta-3'
- androidTestImplementation 'androidx.test:runner:1.3.0-alpha02'
+ androidTestImplementation 'androidx.test:runner:1.2.0'
androidTestImplementation 'androidx.test.espresso:espresso-core:3.3.0-alpha02'
}
diff --git a/app/src/main/AndroidManifest.xml b/app/src/main/AndroidManifest.xml
index 15b8cb1..f63b144 100644
--- a/app/src/main/AndroidManifest.xml
+++ b/app/src/main/AndroidManifest.xml
@@ -16,7 +16,8 @@
android:label="@string/app_name"
android:configChanges="orientation|screenSize|smallestScreenSize|screenLayout"
android:launchMode="singleTop"
- android:theme="@style/AppTheme.NoActionBar">
+ android:theme="@style/AppTheme.NoActionBar"
+ >
@@ -44,31 +45,6 @@
android:host="*"/>
-
-
-
-
-
-
-
-
-
{
+ dismiss();
+ });
// Programmatically load text from an asset and place it into the
// text view. Note that the text we are loading is ASCII, so we
// need to convert it to UTF-16.
try {
- InputStream is = getAssets().open(filepath);
+ InputStream is = requireContext().getAssets().open(getString(Utils.resId(this, "string", "info_readme")));
// We guarantee that the available method returns the total
// size of the asset... of course, this does mean that a single
@@ -58,23 +89,11 @@ public class InfoActivity extends AppCompatActivity {
String text = new String(buffer);
// Finally stick the string into the text view.
- TextView textViewInfo = findViewById(Utils.resId(this, "id", "textViewInfo"));
+ TextView textViewInfo = view.findViewById(Utils.resId(this, "id", "textViewInfo"));
textViewInfo.setMovementMethod(new ScrollingMovementMethod());
textViewInfo.setText(text);
Linkify.addLinks(textViewInfo, Linkify.ALL);
- } catch (IOException e) {
- // Should never happen!
- //throw new RuntimeException(e);
- }
+ } catch (IOException ignored) { }
+ return view;
}
-
- @Override
- public boolean onOptionsItemSelected(MenuItem item) {
- if(item.getItemId() == homeId) {
- finish();
- return true;
- }
- return super.onOptionsItemSelected(item);
- }
-
}
diff --git a/app/src/main/java/org/emulator/calculator/InfoWebActivity.java b/app/src/main/java/org/emulator/calculator/InfoWebActivity.java
deleted file mode 100644
index 0035b20..0000000
--- a/app/src/main/java/org/emulator/calculator/InfoWebActivity.java
+++ /dev/null
@@ -1,61 +0,0 @@
-// This program is free software; you can redistribute it and/or modify
-// it under the terms of the GNU General Public License as published by
-// the Free Software Foundation; either version 2 of the License, or
-// (at your option) any later version.
-//
-// This program is distributed in the hope that it will be useful,
-// but WITHOUT ANY WARRANTY; without even the implied warranty of
-// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
-// GNU General Public License for more details.
-//
-// You should have received a copy of the GNU General Public License along
-// with this program; if not, write to the Free Software Foundation, Inc.,
-// 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA.
-
-package org.emulator.calculator;
-
-import android.annotation.SuppressLint;
-import android.os.Bundle;
-import android.view.MenuItem;
-import android.webkit.WebView;
-import android.webkit.WebViewClient;
-
-import androidx.appcompat.app.AppCompatActivity;
-
-public class InfoWebActivity extends AppCompatActivity {
-
- private int homeId;
-
- @SuppressLint("SetJavaScriptEnabled")
- @Override
- protected void onCreate(Bundle savedInstanceState) {
- super.onCreate(savedInstanceState);
-
- setContentView(Utils.resId(this, "layout", "activity_web_info"));
- homeId = Utils.resId(this, "id", "home");
-
- WebView webView = findViewById(Utils.resId(this, "id", "webViewInfo"));
- webView.getSettings().setJavaScriptEnabled(true);
- webView.setWebViewClient(new WebViewClient() {
- @Override
- public void onPageFinished(WebView view, String url) {
- super.onPageFinished(view, url);
-
- if(url != null)
- // Inject a CSS style to wrap the table of content if needed
- view.evaluateJavascript("javascript:(function(){var css=document.createElement(\"style\");css.type=\"text/css\";css.innerHTML=\".nav1{overflow-wrap:break-word;}\";document.head.appendChild(css);})();", null);
- }
- });
- webView.loadUrl(getString(Utils.resId(this, "string", "help_url")));
- }
-
- @Override
- public boolean onOptionsItemSelected(MenuItem item) {
- if(item.getItemId() == homeId) {
- finish();
- return true;
- }
- return super.onOptionsItemSelected(item);
- }
-
-}
diff --git a/app/src/main/java/org/emulator/calculator/InfoWebFragment.java b/app/src/main/java/org/emulator/calculator/InfoWebFragment.java
new file mode 100644
index 0000000..f629ab9
--- /dev/null
+++ b/app/src/main/java/org/emulator/calculator/InfoWebFragment.java
@@ -0,0 +1,85 @@
+// This program is free software; you can redistribute it and/or modify
+// it under the terms of the GNU General Public License as published by
+// the Free Software Foundation; either version 2 of the License, or
+// (at your option) any later version.
+//
+// This program is distributed in the hope that it will be useful,
+// but WITHOUT ANY WARRANTY; without even the implied warranty of
+// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+// GNU General Public License for more details.
+//
+// You should have received a copy of the GNU General Public License along
+// with this program; if not, write to the Free Software Foundation, Inc.,
+// 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA.
+
+package org.emulator.calculator;
+
+import android.annotation.SuppressLint;
+import android.app.Dialog;
+import android.graphics.PorterDuff;
+import android.graphics.drawable.Drawable;
+import android.os.Bundle;
+import android.view.LayoutInflater;
+import android.view.View;
+import android.view.ViewGroup;
+import android.view.Window;
+import android.webkit.WebView;
+import android.webkit.WebViewClient;
+
+import androidx.annotation.NonNull;
+import androidx.appcompat.app.AppCompatDialogFragment;
+import androidx.appcompat.widget.Toolbar;
+
+public class InfoWebFragment extends AppCompatDialogFragment {
+
+ @Override
+ public void onCreate(Bundle savedInstanceState) {
+ super.onCreate(savedInstanceState);
+ setStyle(AppCompatDialogFragment.STYLE_NO_FRAME, Utils.resId(this, "style", "AppTheme"));
+ }
+
+ @NonNull
+ @Override
+ public Dialog onCreateDialog(Bundle savedInstanceState) {
+ Dialog dialog = super.onCreateDialog(savedInstanceState);
+ dialog.requestWindowFeature(Window.FEATURE_NO_TITLE);
+ return dialog;
+ }
+
+ @SuppressLint("SetJavaScriptEnabled")
+ @Override
+ public View onCreateView(@NonNull LayoutInflater inflater, ViewGroup container, Bundle savedInstanceState) {
+
+ String title = getString(Utils.resId(this, "string", "title_web_fragment_info"));
+ Dialog dialog = getDialog();
+ if(dialog != null)
+ dialog.setTitle(title);
+
+ View view = inflater.inflate(Utils.resId(this, "layout", "fragment_web_info"), container, false);
+
+ // Toolbar
+
+ Toolbar toolbar = view.findViewById(Utils.resId(this, "id", "my_toolbar"));
+ toolbar.setTitle(title);
+ Utils.colorizeDrawableWithColor(requireContext(), toolbar.getNavigationIcon(), android.R.attr.colorForeground);
+ toolbar.setNavigationOnClickListener(v -> {
+ dismiss();
+ });
+
+ WebView webView = view.findViewById(Utils.resId(this, "id", "webViewInfo"));
+ webView.getSettings().setJavaScriptEnabled(true);
+ webView.setWebViewClient(new WebViewClient() {
+ @Override
+ public void onPageFinished(WebView view, String url) {
+ super.onPageFinished(view, url);
+
+ if(url != null)
+ // Inject a CSS style to wrap the table of content if needed
+ view.evaluateJavascript("javascript:(function(){var css=document.createElement(\"style\");css.type=\"text/css\";css.innerHTML=\".nav1{overflow-wrap:break-word;}\";document.head.appendChild(css);})();", null);
+ }
+ });
+ webView.loadUrl(getString(Utils.resId(this, "string", "help_url")));
+
+ return view;
+ }
+}
diff --git a/app/src/main/java/org/emulator/calculator/MainScreenView.java b/app/src/main/java/org/emulator/calculator/MainScreenView.java
index 8d6302e..be64b77 100644
--- a/app/src/main/java/org/emulator/calculator/MainScreenView.java
+++ b/app/src/main/java/org/emulator/calculator/MainScreenView.java
@@ -30,14 +30,16 @@ import android.view.InputDevice;
import android.view.KeyEvent;
import android.view.MotionEvent;
+import java.util.Arrays;
import java.util.HashMap;
import java.util.HashSet;
+import java.util.List;
import java.util.Set;
public class MainScreenView extends PanAndScaleView {
protected static final String TAG = "MainScreenView";
- protected final boolean debug = false;
+ protected final boolean debug = true;
private Paint paintFullCalc = new Paint();
private Paint paintLCD = new Paint();
@@ -45,6 +47,7 @@ public class MainScreenView extends PanAndScaleView {
private Rect srcBitmapCopy = new Rect();
private SparseIntArray vkmap;
private HashMap charmap;
+ private List numpadKey;
private int kmlBackgroundColor = Color.BLACK;
private boolean useKmlBackgroundColor = false;
private int fallbackBackgroundColorType = 0;
@@ -102,7 +105,11 @@ public class MainScreenView extends PanAndScaleView {
// vkmap.put(KeyEvent.KEYCODE_CTRL_RIGHT, 0x11); // VK_CONTROL
vkmap.put(KeyEvent.KEYCODE_ESCAPE, 0x1B); // VK_ESCAPE
vkmap.put(KeyEvent.KEYCODE_SPACE, 0x20); // VK_SPACE
- vkmap.put(KeyEvent.KEYCODE_DPAD_LEFT, 0x25); // VK_LEFT
+ vkmap.put(KeyEvent.KEYCODE_PAGE_UP, 0x21); // VK_PRIOR
+ vkmap.put(KeyEvent.KEYCODE_PAGE_DOWN, 0x22); // VK_NEXT
+ vkmap.put(KeyEvent.KEYCODE_MOVE_END, 0x23); // VK_END
+ vkmap.put(KeyEvent.KEYCODE_MOVE_HOME, 0x24); // VK_HOME
+ vkmap.put(KeyEvent.KEYCODE_DPAD_LEFT, 0x25); // VK_LEFT
vkmap.put(KeyEvent.KEYCODE_DPAD_UP, 0x26); // VK_UP
vkmap.put(KeyEvent.KEYCODE_DPAD_RIGHT, 0x27); // VK_RIGHT
vkmap.put(KeyEvent.KEYCODE_DPAD_DOWN, 0x28); // VK_DOWN
@@ -166,6 +173,21 @@ public class MainScreenView extends PanAndScaleView {
vkmap.put(KeyEvent.KEYCODE_APOSTROPHE, 0xDE); // VK_OEM_7 (‘ »)
vkmap.put(KeyEvent.KEYCODE_BACKSLASH, 0xDC); // VK_OEM_5 (\|)
+ numpadKey = Arrays.asList(
+ KeyEvent.KEYCODE_NUMPAD_0,
+ KeyEvent.KEYCODE_NUMPAD_1,
+ KeyEvent.KEYCODE_NUMPAD_2,
+ KeyEvent.KEYCODE_NUMPAD_3,
+ KeyEvent.KEYCODE_NUMPAD_4,
+ KeyEvent.KEYCODE_NUMPAD_5,
+ KeyEvent.KEYCODE_NUMPAD_6,
+ KeyEvent.KEYCODE_NUMPAD_7,
+ KeyEvent.KEYCODE_NUMPAD_8,
+ KeyEvent.KEYCODE_NUMPAD_9,
+ KeyEvent.KEYCODE_NUMPAD_DOT,
+ KeyEvent.KEYCODE_NUMPAD_COMMA
+ );
+
this.setFocusable(true);
this.setFocusableInTouchMode(true);
}
@@ -213,6 +235,8 @@ public class MainScreenView extends PanAndScaleView {
public boolean onKeyDown(int keyCode, KeyEvent event) {
if((event.getFlags() & KeyEvent.FLAG_VIRTUAL_HARD_KEY) == 0
&& (event.getSource() & InputDevice.SOURCE_KEYBOARD) == InputDevice.SOURCE_KEYBOARD) {
+ if(!event.isNumLockOn() && numpadKey.indexOf(keyCode) != -1)
+ return false;
char pressedKey = (char) event.getUnicodeChar();
Integer windowsKeycode = charmap.get(pressedKey);
if(windowsKeycode == null)
@@ -232,6 +256,8 @@ public class MainScreenView extends PanAndScaleView {
public boolean onKeyUp(int keyCode, KeyEvent event) {
if((event.getFlags() & KeyEvent.FLAG_VIRTUAL_HARD_KEY) == 0
&& (event.getSource() & InputDevice.SOURCE_KEYBOARD) == InputDevice.SOURCE_KEYBOARD) {
+ if(!event.isNumLockOn() && numpadKey.indexOf(keyCode) != -1)
+ return false;
char pressedKey = (char) event.getUnicodeChar();
Integer windowsKeycode = charmap.get(pressedKey);
if(windowsKeycode == null)
diff --git a/app/src/main/java/org/emulator/calculator/PrinterSimulator.java b/app/src/main/java/org/emulator/calculator/PrinterSimulator.java
index 2d953a4..551a74a 100644
--- a/app/src/main/java/org/emulator/calculator/PrinterSimulator.java
+++ b/app/src/main/java/org/emulator/calculator/PrinterSimulator.java
@@ -70,14 +70,6 @@ public class PrinterSimulator {
m_bPrinter82240A = enable;
}
- /**
- * true to prevent the line wrapping for the textual printer when the character '\4' is sent by the calc.
- * @param preventLineWrap true to prevent the line wrapping; false otherwise.
- */
- public void setPreventLineWrap(boolean preventLineWrap) {
- this.preventLineWrap = preventLineWrap;
- }
-
/**
* Change the paper, so we cleanup everything.
@@ -252,8 +244,6 @@ public class PrinterSimulator {
// Text Printer
- private boolean preventLineWrap = false;
-
/**
* ROMAN8 Unicode table
*/
@@ -303,7 +293,7 @@ public class PrinterSimulator {
private void addTextData(int byData) {
do {
// special LF and LF characters
- if (/*!preventLineWrap &&*/ byData == 0x04 || byData == 0x0A) {
+ if (byData == 0x04 || byData == 0x0A) {
textUpdate.append('\r');
textUpdate.append('\n');
if(debug) Log.d(TAG, "addTextData(" + byData + ")");
diff --git a/app/src/main/java/org/emulator/calculator/PrinterSimulatorFragment.java b/app/src/main/java/org/emulator/calculator/PrinterSimulatorFragment.java
index e1a3b2a..1bcc573 100644
--- a/app/src/main/java/org/emulator/calculator/PrinterSimulatorFragment.java
+++ b/app/src/main/java/org/emulator/calculator/PrinterSimulatorFragment.java
@@ -22,7 +22,9 @@ import android.graphics.Bitmap;
import android.graphics.Canvas;
import android.graphics.Color;
import android.graphics.Paint;
+import android.graphics.PorterDuff;
import android.graphics.Rect;
+import android.graphics.drawable.Drawable;
import android.os.Bundle;
import android.util.AttributeSet;
import android.util.Log;
@@ -70,9 +72,7 @@ public class PrinterSimulatorFragment extends AppCompatDialogFragment {
@Override
public Dialog onCreateDialog(Bundle savedInstanceState) {
Dialog dialog = super.onCreateDialog(savedInstanceState);
- Window window = dialog.getWindow();
- if(window != null)
- window.requestFeature(Window.FEATURE_NO_TITLE);
+ dialog.requestWindowFeature(Window.FEATURE_NO_TITLE);
return dialog;
}
@@ -94,7 +94,7 @@ public class PrinterSimulatorFragment extends AppCompatDialogFragment {
Toolbar toolbar = view.findViewById(Utils.resId(this, "id", "my_toolbar"));
toolbar.setTitle(title);
- toolbar.setNavigationIcon(Utils.resId(this, "drawable", "ic_keyboard_backspace_white_24dp"));
+ Utils.colorizeDrawableWithColor(requireContext(), toolbar.getNavigationIcon(), android.R.attr.colorForeground);
toolbar.setNavigationOnClickListener(
v -> dismiss()
);
diff --git a/app/src/main/java/org/emulator/calculator/Settings.java b/app/src/main/java/org/emulator/calculator/Settings.java
index a814605..05515be 100644
--- a/app/src/main/java/org/emulator/calculator/Settings.java
+++ b/app/src/main/java/org/emulator/calculator/Settings.java
@@ -14,6 +14,7 @@
package org.emulator.calculator;
+import android.annotation.SuppressLint;
import android.content.Context;
import android.content.SharedPreferences;
import android.net.Uri;
@@ -33,226 +34,82 @@ import java.io.FileInputStream;
import java.io.FileOutputStream;
import java.io.IOException;
import java.nio.charset.StandardCharsets;
+import java.util.Arrays;
import java.util.Collection;
import java.util.HashMap;
import java.util.HashSet;
import java.util.Iterator;
+import java.util.List;
import java.util.Map;
import java.util.Set;
public class Settings extends PreferenceDataStore {
private static final String TAG = "Settings";
- protected final boolean debug = true;
+ protected final boolean debug = false;
- private final SharedPreferences defaultSettings;
+ private final SharedPreferences androidSettings;
+ private List applicationSettingKeys = Arrays.asList("settings_kml_default", "settings_kml_folder", "lastDocument", "MRU");
+ private final HashMap applicationSettings = new HashMap<>();
+ private final HashMap commonSettings = new HashMap<>();
private final HashMap embeddedStateSettings = new HashMap<>();
- private SharedPreferences.OnSharedPreferenceChangeListener sharedPreferenceChangeListener;
+ private boolean isCommonSettings = true;
+
+ public interface OnOneKeyChangedListener {
+ void onOneKeyChanged(String keyChanged);
+ }
+ private OnOneKeyChangedListener oneKeyChangedListener;
private static String magic = "MYHP";
- private boolean isDefaultSettings = true;
-
public Settings(@NonNull SharedPreferences sharedPreferences) {
if(debug) Log.d(TAG, "Settings()");
- this.defaultSettings = sharedPreferences;
+ androidSettings = sharedPreferences;
+
+ loadApplicationSettings();
}
- public void registerOnSharedPreferenceChangeListener(SharedPreferences.OnSharedPreferenceChangeListener listener) {
- if(debug) Log.d(TAG, "registerOnSharedPreferenceChangeListener()");
- sharedPreferenceChangeListener = listener;
+ public void registerOnOneKeyChangeListener(OnOneKeyChangedListener listener) {
+ if(debug) Log.d(TAG, "registerOnOneKeyChangeListener()");
+ oneKeyChangedListener = listener;
}
- public void unregisterOnSharedPreferenceChangeListener(SharedPreferences.OnSharedPreferenceChangeListener listener) {
- if(debug) Log.d(TAG, "unregisterOnSharedPreferenceChangeListener()");
- sharedPreferenceChangeListener = null;
+ public void unregisterOnOneKeyChangeListener() {
+ if(debug) Log.d(TAG, "unregisterOnOneKeyChangeListener()");
+ oneKeyChangedListener = null;
}
- @Override
- public void putString(String key, @Nullable String value) {
- putString(key, value, false);
- }
- public void putString(String key, @Nullable String value, boolean forceDefault) {
- if(debug) Log.d(TAG, (isDefaultSettings ? "DEFAULT" : "LOCAL") + " putString(key: '" + key + "' value: '" + value + "')");
- if(isDefaultSettings || forceDefault) {
- defaultSettings.edit().putString(key, value).apply();
- if(sharedPreferenceChangeListener != null)
- sharedPreferenceChangeListener.onSharedPreferenceChanged(defaultSettings, key);
- } else {
+ private void putValue(String key, @Nullable Object value) {
+ if(applicationSettingKeys.indexOf(key) != -1)
+ applicationSettings.put(key, value);
+ else if(isCommonSettings)
+ commonSettings.put(key, value);
+ else
embeddedStateSettings.put(key, value);
- if(sharedPreferenceChangeListener != null)
- sharedPreferenceChangeListener.onSharedPreferenceChanged(null, key);
+ if(oneKeyChangedListener != null)
+ oneKeyChangedListener.onOneKeyChanged(key);
+ }
+
+ private Object getValue(String key) {
+ Object value = null;
+ if(!isCommonSettings)
+ value = embeddedStateSettings.get(key);
+ if(value == null) {
+ if(applicationSettingKeys.indexOf(key) != -1)
+ value = applicationSettings.get(key);
+ else
+ value = commonSettings.get(key);
}
+ return value;
}
- @Override
- public void putStringSet(String key, @Nullable Set value) {
- putStringSet(key, value, false);
- }
- public void putStringSet(String key, @Nullable Set value, boolean forceDefault) {
- if(debug) Log.d(TAG, (isDefaultSettings ? "DEFAULT" : "LOCAL") + " putStringSet(key: '" + key + "' value: '" + "" + "')");
- if(isDefaultSettings || forceDefault) {
- defaultSettings.edit().putStringSet(key, value).apply();
- if(sharedPreferenceChangeListener != null)
- sharedPreferenceChangeListener.onSharedPreferenceChanged(defaultSettings, key);
- } else {
- embeddedStateSettings.put(key, value);
- if(sharedPreferenceChangeListener != null)
- sharedPreferenceChangeListener.onSharedPreferenceChanged(null, key);
- }
+ public boolean getIsDefaultSettings() {
+ return isCommonSettings;
}
- @Override
- public void putInt(String key, int value) {
- putInt(key, value, false);
- }
- public void putInt(String key, int value, boolean forceDefault) {
- if(debug) Log.d(TAG, (isDefaultSettings ? "DEFAULT" : "LOCAL") + " putInt(key: '" + key + "' value: '" + value + "')");
- if(isDefaultSettings || forceDefault) {
- defaultSettings.edit().putInt(key, value).apply();
- if(sharedPreferenceChangeListener != null)
- sharedPreferenceChangeListener.onSharedPreferenceChanged(defaultSettings, key);
- } else {
- embeddedStateSettings.put(key, value);
- if(sharedPreferenceChangeListener != null)
- sharedPreferenceChangeListener.onSharedPreferenceChanged(null, key);
- }
- }
-
- @Override
- public void putLong(String key, long value){
- putLong(key,value,false);
- }
- public void putLong(String key, long value, boolean forceDefault) {
- if(debug) Log.d(TAG, (isDefaultSettings ? "DEFAULT" : "LOCAL") + " putLong(key: '" + key + "' value: '" + value + "')");
- if(isDefaultSettings || forceDefault) {
- defaultSettings.edit().putLong(key, value).apply();
- if(sharedPreferenceChangeListener != null)
- sharedPreferenceChangeListener.onSharedPreferenceChanged(defaultSettings, key);
- } else {
- embeddedStateSettings.put(key, value);
- if(sharedPreferenceChangeListener != null)
- sharedPreferenceChangeListener.onSharedPreferenceChanged(null, key);
- }
- }
-
- @Override
- public void putFloat(String key, float value){
- putFloat(key,value,false);
- }
- public void putFloat(String key, float value, boolean forceDefault) {
- if(debug) Log.d(TAG, (isDefaultSettings ? "DEFAULT" : "LOCAL") + " putFloat(key: '" + key + "' value: '" + value + "')");
- if(isDefaultSettings || forceDefault) {
- defaultSettings.edit().putFloat(key, value).apply();
- if(sharedPreferenceChangeListener != null)
- sharedPreferenceChangeListener.onSharedPreferenceChanged(defaultSettings, key);
- } else {
- embeddedStateSettings.put(key, value);
- if(sharedPreferenceChangeListener != null)
- sharedPreferenceChangeListener.onSharedPreferenceChanged(null, key);
- }
- }
-
- @Override
- public void putBoolean(String key, boolean value){
- putBoolean(key,value,false);
- }
- public void putBoolean(String key, boolean value, boolean forceDefault) {
- if(debug) Log.d(TAG, (isDefaultSettings ? "DEFAULT" : "LOCAL") + " putBoolean(key: '" + key + "' value: '" + value + "')");
- if(isDefaultSettings || forceDefault) {
- defaultSettings.edit().putBoolean(key, value).apply();
- if(sharedPreferenceChangeListener != null)
- sharedPreferenceChangeListener.onSharedPreferenceChanged(defaultSettings, key);
- } else {
- embeddedStateSettings.put(key, value);
- if(sharedPreferenceChangeListener != null)
- sharedPreferenceChangeListener.onSharedPreferenceChanged(null, key);
- }
- }
-
- @Nullable
- @Override
- public String getString(String key, @Nullable String defValue) {
- if(debug) Log.d(TAG, "getString(key: '" + key + "')");
- if(!isDefaultSettings) {
- Object result = embeddedStateSettings.get(key);
- if(result instanceof String)
- return (String) result;
- }
- return defaultSettings.getString(key, defValue);
- }
-
- @SuppressWarnings("unchecked")
- @Nullable
- @Override
- public Set getStringSet(String key, @Nullable Set defValues) {
- if(debug) Log.d(TAG, "getStringSet(key: '" + key + "')");
- if(!isDefaultSettings) {
- Object result = embeddedStateSettings.get(key);
- if(result instanceof Set>)
- try {
- return (Set) result;
- } catch (Exception ignored) {}
- }
- return defaultSettings.getStringSet(key, defValues);
- }
-
- @Override
- public int getInt(String key, int defValue) {
- if(debug) Log.d(TAG, "getInt(key: '" + key + "')");
- if(!isDefaultSettings) {
- Object result = embeddedStateSettings.get(key);
- if(result != null)
- try {
- return (Integer) result;
- } catch (Exception ignored) {}
- }
- return defaultSettings.getInt(key, defValue);
- }
-
- @Override
- public long getLong(String key, long defValue) {
- if(debug) Log.d(TAG, "getLong(key: '" + key + "')");
- if(!isDefaultSettings) {
- Object result = embeddedStateSettings.get(key);
- if(result != null)
- try {
- return (Long) result;
- } catch (Exception ignored) {}
- }
- return defaultSettings.getLong(key, defValue);
- }
-
- @Override
- public float getFloat(String key, float defValue) {
- if(debug) Log.d(TAG, "getFloat(key: '" + key + "')");
- if(!isDefaultSettings) {
- Object result = embeddedStateSettings.get(key);
- if(result != null)
- try {
- return (Float) result;
- } catch (Exception ignored) {}
- }
- return defaultSettings.getFloat(key, defValue);
- }
-
- @Override
- public boolean getBoolean(String key, boolean defValue) {
- if(debug) Log.d(TAG, "getBoolean(key: '" + key + "')");
- if(!isDefaultSettings) {
- Object result = embeddedStateSettings.get(key);
- if(result != null)
- try {
- return (Boolean) result;
- } catch (Exception ignored) {}
- }
- return defaultSettings.getBoolean(key, defValue);
- }
-
-
- public void setDefaultSettings(boolean defaultSettings) {
- isDefaultSettings = defaultSettings;
+ public void setIsDefaultSettings(boolean isDefaultSettings) {
+ this.isCommonSettings = isDefaultSettings;
}
private static String toJSON(Collection array) {
@@ -340,26 +197,36 @@ public class Settings extends PreferenceDataStore {
public void saveInStateFile(Context context, String url) {
if(debug) Log.d(TAG, "saveInStateFile(url: '" + url + "')");
- Uri uri = Uri.parse(url);
- try {
- ParcelFileDescriptor pfd = context.getContentResolver().openFileDescriptor(uri, "wa");
- if(pfd != null) {
- FileOutputStream fileOutputStream = new FileOutputStream(pfd.getFileDescriptor());
- String json = toJSON(embeddedStateSettings);
- byte[] jsonBytes = json.getBytes(StandardCharsets.UTF_8);
- int jsonLength = jsonBytes.length;
- fileOutputStream.write(jsonBytes);
- // The JSON text should not be more than 64KB
- fileOutputStream.write((jsonLength >> 8) & 0xFF);
- fileOutputStream.write(jsonLength & 0xFF);
- for (int i = 0; i < magic.length(); i++) {
- fileOutputStream.write(magic.charAt(i));
+
+ // Consolidate common and embedded settings but without the app only settings
+ Map stateSettings = new HashMap<>();
+ stateSettings.putAll(commonSettings);
+ stateSettings.putAll(embeddedStateSettings);
+
+ String json = toJSON(stateSettings);
+ byte[] jsonBytes = json.getBytes(StandardCharsets.UTF_8);
+ int jsonLength = jsonBytes.length;
+
+ if(jsonLength < 65536) {
+ Uri uri = Uri.parse(url);
+ try {
+ ParcelFileDescriptor pfd = context.getContentResolver().openFileDescriptor(uri, "wa");
+ if (pfd != null) {
+ FileOutputStream fileOutputStream = new FileOutputStream(pfd.getFileDescriptor());
+
+ fileOutputStream.write(jsonBytes);
+ // The JSON text should not be more than 64KB
+ fileOutputStream.write((jsonLength >> 8) & 0xFF);
+ fileOutputStream.write(jsonLength & 0xFF);
+ for (int i = 0; i < magic.length(); i++) {
+ fileOutputStream.write(magic.charAt(i));
+ }
+ fileOutputStream.flush();
+ fileOutputStream.close();
}
- fileOutputStream.flush();
- fileOutputStream.close();
+ } catch (IOException e) {
+ e.printStackTrace();
}
- } catch (IOException e) {
- e.printStackTrace();
}
}
@@ -367,6 +234,12 @@ public class Settings extends PreferenceDataStore {
embeddedStateSettings.clear();
}
+ @SuppressLint("ApplySharedPref")
+ public void clearCommonDefaultSettings() {
+ embeddedStateSettings.clear();
+ commonSettings.clear();
+ }
+
@SuppressWarnings("ResultOfMethodCallIgnored")
public void loadFromStateFile(Context context, String url) {
if(debug) Log.d(TAG, "loadFromStateFile(url: '" + url + "')");
@@ -383,7 +256,7 @@ public class Settings extends PreferenceDataStore {
fileInputStream.read(lastChunk, 0, lastChunk.length);
} else {
int lastChunkOffset = lastChunk.length - (int)fileSize;
- fileInputStream.read(lastChunk, lastChunkOffset, lastChunk.length);
+ fileInputStream.read(lastChunk, lastChunkOffset, (int)fileSize);
}
fileInputStream.close();
@@ -408,4 +281,154 @@ public class Settings extends PreferenceDataStore {
e.printStackTrace();
}
}
+
+ private void loadApplicationSettings() {
+ commonSettings.clear();
+ Map keyValuePairs = androidSettings.getAll();
+ for (String key : keyValuePairs.keySet()) {
+ if (applicationSettingKeys.indexOf(key) != -1)
+ applicationSettings.put(key, keyValuePairs.get(key));
+ else
+ commonSettings.put(key, keyValuePairs.get(key));
+ }
+ }
+
+ public void saveApplicationSettings() {
+ if(debug) Log.d(TAG, "saveApplicationSettings()");
+
+ SharedPreferences.Editor settingsEditor = androidSettings.edit();
+ for (String key : commonSettings.keySet()) {
+ Object value = commonSettings.get(key);
+ putKeyValueInEditor(settingsEditor, key, value);
+ }
+ for (String key : applicationSettingKeys) {
+ Object value = applicationSettings.get(key);
+ putKeyValueInEditor(settingsEditor, key, value);
+ }
+
+ settingsEditor.apply();
+ }
+
+ private void putKeyValueInEditor(SharedPreferences.Editor settingsEditor, String key, Object value) {
+ if (value instanceof Integer)
+ settingsEditor.putInt(key, ((Number)value).intValue());
+ else if (value instanceof Long)
+ settingsEditor.putLong(key, ((Number)value).longValue());
+ else if (value instanceof Boolean)
+ settingsEditor.putBoolean(key, (Boolean) value);
+ else if (value instanceof Float || value instanceof Double)
+ settingsEditor.putFloat(key, ((Number)value).floatValue());
+ else if (value instanceof String)
+ settingsEditor.putString(key, (String) value);
+ else if (value instanceof Set>)
+ settingsEditor.putStringSet(key, (Set) value);
+ else
+ settingsEditor.putString(key, null);
+ }
+
+
+ // PreferenceDataStore
+
+ @Override
+ public void putString(String key, @Nullable String value) {
+ if(debug) Log.d(TAG, (isCommonSettings ? "DEFAULT" : "LOCAL") + " putString(key: '" + key + "' value: '" + value + "')");
+ putValue(key, value);
+ }
+
+ @Override
+ public void putStringSet(String key, @Nullable Set value) {
+ if(debug) Log.d(TAG, (isCommonSettings ? "DEFAULT" : "LOCAL") + " putStringSet(key: '" + key + "' value: '" + "" + "')");
+ putValue(key, value);
+ }
+
+ @Override
+ public void putInt(String key, int value) {
+ if(debug) Log.d(TAG, (isCommonSettings ? "DEFAULT" : "LOCAL") + " putInt(key: '" + key + "' value: '" + value + "')");
+ putValue(key, value);
+ }
+
+ @Override
+ public void putLong(String key, long value){
+ if(debug) Log.d(TAG, (isCommonSettings ? "DEFAULT" : "LOCAL") + " putLong(key: '" + key + "' value: '" + value + "')");
+ putValue(key, value);
+ }
+
+ @Override
+ public void putFloat(String key, float value){
+ if(debug) Log.d(TAG, (isCommonSettings ? "DEFAULT" : "LOCAL") + " putFloat(key: '" + key + "' value: '" + value + "')");
+ putValue(key, value);
+ }
+
+ @Override
+ public void putBoolean(String key, boolean value){
+ if(debug) Log.d(TAG, (isCommonSettings ? "DEFAULT" : "LOCAL") + " putBoolean(key: '" + key + "' value: '" + value + "')");
+ putValue(key, value);
+ }
+
+ @Nullable
+ @Override
+ public String getString(String key, @Nullable String defValue) {
+ if(debug) Log.d(TAG, "getString(key: '" + key + "')");
+ Object result = getValue(key);
+ if(result instanceof String)
+ return (String) result;
+ return defValue;
+ }
+
+ @SuppressWarnings("unchecked")
+ @Nullable
+ @Override
+ public Set getStringSet(String key, @Nullable Set defValues) {
+ if(debug) Log.d(TAG, "getStringSet(key: '" + key + "')");
+ Object result = getValue(key);
+ if(result instanceof Set>)
+ try {
+ return (Set) result;
+ } catch (Exception ignored) {}
+ return defValues;
+ }
+
+ @Override
+ public int getInt(String key, int defValue) {
+ if(debug) Log.d(TAG, "getInt(key: '" + key + "')");
+ Object result = getValue(key);
+ if(result != null)
+ try {
+ return ((Number) result).intValue();
+ } catch (Exception ignored) {}
+ return defValue;
+ }
+
+ @Override
+ public long getLong(String key, long defValue) {
+ if(debug) Log.d(TAG, "getLong(key: '" + key + "')");
+ Object result = getValue(key);
+ if(result != null)
+ try {
+ return ((Number) result).longValue();
+ } catch (Exception ignored) {}
+ return defValue;
+ }
+
+ @Override
+ public float getFloat(String key, float defValue) {
+ if(debug) Log.d(TAG, "getFloat(key: '" + key + "')");
+ Object result = getValue(key);
+ if(result != null)
+ try {
+ return ((Number) result).floatValue();
+ } catch (Exception ignored) {}
+ return defValue;
+ }
+
+ @Override
+ public boolean getBoolean(String key, boolean defValue) {
+ if(debug) Log.d(TAG, "getBoolean(key: '" + key + "')");
+ Object result = getValue(key);
+ if(result != null)
+ try {
+ return (Boolean) result;
+ } catch (Exception ignored) {}
+ return defValue;
+ }
}
diff --git a/app/src/main/java/org/emulator/calculator/Utils.java b/app/src/main/java/org/emulator/calculator/Utils.java
index 7030c54..df6a4a0 100644
--- a/app/src/main/java/org/emulator/calculator/Utils.java
+++ b/app/src/main/java/org/emulator/calculator/Utils.java
@@ -16,17 +16,24 @@ package org.emulator.calculator;
import android.content.Context;
import android.content.Intent;
+import android.content.res.Resources;
import android.database.Cursor;
+import android.graphics.BlendMode;
+import android.graphics.BlendModeColorFilter;
+import android.graphics.PorterDuff;
+import android.graphics.drawable.Drawable;
import android.net.Uri;
import android.os.Build;
import android.provider.OpenableColumns;
import android.util.Log;
+import android.util.TypedValue;
import android.view.View;
import android.view.ViewGroup;
import android.widget.ListAdapter;
import android.widget.ListView;
import android.widget.Toast;
+import androidx.core.content.ContextCompat;
import androidx.fragment.app.Fragment;
import javax.microedition.khronos.egl.EGL10;
@@ -43,29 +50,49 @@ public class Utils {
toast.show();
}
- static int resId(Context context, String resourcename, String variableName)
- {
+ static int resId(Context context, String resourceName, String variableName) {
try {
- return context.getResources().getIdentifier(variableName, resourcename, context.getApplicationContext().getPackageName());
+ return context.getResources().getIdentifier(variableName, resourceName, context.getApplicationContext().getPackageName());
} catch (Exception e) {
e.printStackTrace();
return -1;
}
}
- static int resId(Fragment fragment, String resourcename, String variableName)
- {
+ public static int resId(Fragment fragment, String resourceName, String variableName) {
try {
Context context = fragment.getContext();
if(context != null)
- return fragment.getResources().getIdentifier(variableName, resourcename, context.getApplicationContext().getPackageName());
+ return fragment.getResources().getIdentifier(variableName, resourceName, context.getApplicationContext().getPackageName());
} catch (Exception e) {
e.printStackTrace();
}
return -1;
}
- public static void makeUriPersistable(Context context, Intent data, Uri uri) {
+ public static int getThemedColor(Context context, int attr) {
+ Resources.Theme theme = context.getTheme();
+ if (theme != null) {
+ TypedValue tv = new TypedValue();
+ theme.resolveAttribute(attr, tv, true);
+ Resources resources = context.getResources();
+ if(resources != null)
+ return ContextCompat.getColor(context, tv.resourceId);
+ }
+ return 0;
+ }
+
+ public static void colorizeDrawableWithColor(Context context, Drawable icon, int colorAttribute) {
+ if(icon != null) {
+ if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.Q)
+ icon.setColorFilter(new BlendModeColorFilter(Utils.getThemedColor(context, colorAttribute), BlendMode.SRC_ATOP));
+ else
+ icon.setColorFilter(Utils.getThemedColor(context, colorAttribute), PorterDuff.Mode.SRC_ATOP);
+ }
+ }
+
+
+ public static void makeUriPersistable(Context context, Intent data, Uri uri) {
int takeFlags = data.getFlags() & (Intent.FLAG_GRANT_READ_URI_PERMISSION | Intent.FLAG_GRANT_WRITE_URI_PERMISSION);
if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.KITKAT)
context.getContentResolver().takePersistableUriPermission(uri, takeFlags);
diff --git a/app/src/main/java/org/emulator/forty/eight/MainActivity.java b/app/src/main/java/org/emulator/forty/eight/MainActivity.java
index db26447..f036c46 100644
--- a/app/src/main/java/org/emulator/forty/eight/MainActivity.java
+++ b/app/src/main/java/org/emulator/forty/eight/MainActivity.java
@@ -21,7 +21,6 @@ import android.content.Context;
import android.content.DialogInterface;
import android.content.Intent;
import android.content.res.AssetManager;
-import android.content.res.Resources;
import android.graphics.Bitmap;
import android.graphics.Color;
import android.graphics.drawable.BitmapDrawable;
@@ -32,7 +31,6 @@ import android.os.Bundle;
import android.os.ParcelFileDescriptor;
import android.util.Log;
import android.util.SparseArray;
-import android.util.TypedValue;
import android.view.HapticFeedbackConstants;
import android.view.Menu;
import android.view.MenuItem;
@@ -47,10 +45,8 @@ import android.widget.Toast;
import androidx.annotation.NonNull;
import androidx.annotation.Nullable;
-import androidx.appcompat.app.ActionBarDrawerToggle;
import androidx.appcompat.app.AlertDialog;
import androidx.appcompat.app.AppCompatActivity;
-import androidx.appcompat.widget.Toolbar;
import androidx.core.content.FileProvider;
import androidx.core.view.GravityCompat;
import androidx.documentfile.provider.DocumentFile;
@@ -59,8 +55,8 @@ import androidx.drawerlayout.widget.DrawerLayout;
import com.google.android.material.navigation.NavigationView;
import org.emulator.calculator.EmuApplication;
-import org.emulator.calculator.InfoActivity;
-import org.emulator.calculator.InfoWebActivity;
+import org.emulator.calculator.InfoFragment;
+import org.emulator.calculator.InfoWebFragment;
import org.emulator.calculator.LCDOverlappingView;
import org.emulator.calculator.MainScreenView;
import org.emulator.calculator.NativeLib;
@@ -96,7 +92,8 @@ import java.util.regex.Pattern;
public class MainActivity extends AppCompatActivity implements NavigationView.OnNavigationItemSelectedListener {
private static final String TAG = "MainActivity";
- private Settings settings;
+ private boolean debug = false;
+ private Settings settings;
private NavigationView navigationView;
private DrawerLayout drawer;
private MainScreenView mainScreenView;
@@ -107,7 +104,6 @@ public class MainActivity extends AppCompatActivity implements NavigationView.On
public static final int INTENT_GETSAVEFILENAME = 2;
public static final int INTENT_OBJECT_LOAD = 3;
public static final int INTENT_OBJECT_SAVE = 4;
- public static final int INTENT_SETTINGS = 5;
public static final int INTENT_PORT2LOAD = 6;
public static final int INTENT_PICK_KML_FOLDER_FOR_NEW_FILE = 7;
public static final int INTENT_PICK_KML_FOLDER_FOR_CHANGING = 8;
@@ -144,20 +140,14 @@ public class MainActivity extends AppCompatActivity implements NavigationView.On
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_main);
- Toolbar toolbar = findViewById(R.id.toolbar);
- setSupportActionBar(toolbar);
- toolbar.setVisibility(View.GONE);
drawer = findViewById(R.id.drawer_layout);
- ActionBarDrawerToggle toggle = new ActionBarDrawerToggle(this, drawer, toolbar, R.string.navigation_drawer_open, R.string.navigation_drawer_close);
- drawer.addDrawerListener(toggle);
- toggle.syncState();
navigationView = findViewById(R.id.nav_view);
navigationView.setNavigationItemSelectedListener(this);
settings = EmuApplication.getSettings();
- settings.setDefaultSettings(true);
+ settings.setIsDefaultSettings(true);
ViewGroup mainScreenContainer = findViewById(R.id.main_screen_container);
@@ -193,7 +183,7 @@ public class MainActivity extends AppCompatActivity implements NavigationView.On
}
}
updateMRU();
- updateFromPreferences(null);
+ updateFromPreferences(null, false);
updateNavigationDrawerItems();
@@ -240,7 +230,7 @@ public class MainActivity extends AppCompatActivity implements NavigationView.On
Utils.makeUriPersistable(this, intent, documentToOpenUri);
}
} catch (Exception e) {
- Log.e(TAG, e.getMessage());
+ if(debug) Log.e(TAG, e.getMessage());
}
else if(drawer != null)
drawer.openDrawer(GravityCompat.START);
@@ -285,7 +275,7 @@ public class MainActivity extends AppCompatActivity implements NavigationView.On
protected void onStop() {
//TODO We cannot make the difference between going to the settings or loading/saving a file and a real app stop/kill!
// -> Maybe by settings some flags when loading/saving
- settings.putStringSet("MRU", mruLinkedHashMap.keySet(), true);
+ settings.putStringSet("MRU", mruLinkedHashMap.keySet());
if(lcdOverlappingView != null)
lcdOverlappingView.saveViewLayout();
@@ -295,6 +285,8 @@ public class MainActivity extends AppCompatActivity implements NavigationView.On
onFileSave();
}
+ settings.saveApplicationSettings();
+
clearFolderCache();
super.onStop();
@@ -534,7 +526,7 @@ public class MainActivity extends AppCompatActivity implements NavigationView.On
String url = file.getUri().toString();
String name = file.getName();
String mime = file.getType();
- Log.d(TAG, "url: " + url + ", name: " + name + ", mime: " + mime);
+ if(debug) Log.d(TAG, "url: " + url + ", name: " + name + ", mime: " + mime);
if(kmlMimeType.equals(mime)) {
calculatorsAssetFilenames.add(url);
}
@@ -662,7 +654,7 @@ public class MainActivity extends AppCompatActivity implements NavigationView.On
private void newFileFromKML(String kmlScriptFilename) {
int result = NativeLib.onFileNew(kmlScriptFilename);
if(result > 0) {
- settings.setDefaultSettings(false);
+ settings.setIsDefaultSettings(false);
settings.clearEmbeddedStateSettings();
showCalculatorView(true);
displayFilename("");
@@ -731,7 +723,7 @@ public class MainActivity extends AppCompatActivity implements NavigationView.On
private void OnFileClose() {
ensureDocumentSaved(() -> {
NativeLib.onFileClose();
- settings.setDefaultSettings(true);
+ settings.setIsDefaultSettings(true);
settings.clearEmbeddedStateSettings();
showCalculatorView(false);
saveLastDocument("");
@@ -744,7 +736,32 @@ public class MainActivity extends AppCompatActivity implements NavigationView.On
}
private void OnSettings() {
- startActivityForResult(new Intent(this, SettingsActivity.class), INTENT_SETTINGS);
+ SettingsFragment settingsFragment = new SettingsFragment();
+ settingsFragment.registerOnSettingsKeyChangedListener(settingsKeyChanged -> {
+ HashSet changedKeysCleaned = new HashSet<>();
+ for (String key : settingsKeyChanged) {
+ if(debug) Log.d(TAG, "ChangedKey): " + key);
+ switch (key) {
+ case "settings_port1en":
+ case "settings_port1wr":
+ changedKeysCleaned.add("settings_port1");
+ break;
+ case "settings_port2en":
+ case "settings_port2wr":
+ case "settings_port2load":
+ changedKeysCleaned.add("settings_port2");
+ break;
+ default:
+ changedKeysCleaned.add(key);
+ break;
+ }
+ }
+ for (String key : changedKeysCleaned) {
+ updateFromPreferences(key, true);
+ }
+ settingsFragment.unregisterOnSettingsKeyChangedListener();
+ });
+ settingsFragment.show(getSupportFragmentManager(), "SettingsFragment");
}
private void openDocument() {
@@ -911,7 +928,7 @@ public class MainActivity extends AppCompatActivity implements NavigationView.On
}
} else if(which == lastIndex + 1) {
// Reset to default KML folder
- settings.putBoolean("settings_kml_default", true, true);
+ settings.putBoolean("settings_kml_default", true);
updateFromPreferences("settings_kml", true);
if(changeKML)
OnViewScript();
@@ -1002,156 +1019,129 @@ public class MainActivity extends AppCompatActivity implements NavigationView.On
}
private void OnTopics() {
- startActivity(new Intent(this, InfoWebActivity.class));
+ new InfoWebFragment().show(getSupportFragmentManager(), "InfoWebFragment");
}
private void OnAbout() {
- startActivity(new Intent(this, InfoActivity.class));
+ new InfoFragment().show(getSupportFragmentManager(), "InfoFragment");
}
@Override
protected void onActivityResult(int requestCode, int resultCode, @Nullable Intent data) {
if(resultCode == Activity.RESULT_OK && data != null) {
- if(requestCode == INTENT_SETTINGS) {
- String[] changedKeys = data.getStringArrayExtra("changedKeys");
- if(changedKeys != null) {
- HashSet changedKeysCleaned = new HashSet<>();
- for (String key : changedKeys) {
- //Log.d(TAG, "ChangedKey): " + key);
- switch (key) {
- case "settings_port1en":
- case "settings_port1wr":
- changedKeysCleaned.add("settings_port1");
- break;
- case "settings_port2en":
- case "settings_port2wr":
- case "settings_port2load":
- changedKeysCleaned.add("settings_port2");
- break;
- default:
- changedKeysCleaned.add(key);
- break;
+ Uri uri = data.getData();
+ String url = null;
+ if (uri != null)
+ url = uri.toString();
+ if (url != null) {
+ switch (requestCode) {
+ case INTENT_GETOPENFILENAME: {
+ if(debug) Log.d(TAG, "onActivityResult INTENT_GETOPENFILENAME " + url);
+ int openResult = onFileOpen(url);
+ if (openResult > 0) {
+ saveLastDocument(url);
+ Utils.makeUriPersistable(this, data, uri);
+ } else if(openResult == -2 && Build.VERSION.SDK_INT >= Build.VERSION_CODES.LOLLIPOP) { // >= API 21
+ // For security reason, you must select the folder where are the KML and ROM files and then, reopen this file!
+ new AlertDialog.Builder(this)
+ .setTitle(getString(R.string.message_open_security))
+ .setMessage(getString(R.string.message_open_security_description))
+ .setPositiveButton(android.R.string.ok, (dialog, which) -> {
+ Intent intent = new Intent(Intent.ACTION_OPEN_DOCUMENT_TREE);
+ startActivityForResult(intent, INTENT_PICK_KML_FOLDER_FOR_SECURITY);
+ }).show();
}
+ break;
}
- for (String key : changedKeysCleaned) {
- updateFromPreferences(key, true);
+ case INTENT_GETSAVEFILENAME: {
+ if(debug) Log.d(TAG, "onActivityResult INTENT_GETSAVEFILENAME " + url);
+ if (NativeLib.onFileSaveAs(url) != 0) {
+ showAlert(getString(R.string.message_state_saved));
+ settings.saveInStateFile(this, url);
+ saveLastDocument(url);
+ Utils.makeUriPersistable(this, data, uri);
+ displayFilename(url);
+ if (fileSaveAsCallback != null)
+ fileSaveAsCallback.run();
+ }
+ break;
}
- }
- } else {
- Uri uri = data.getData();
- String url = null;
- if (uri != null)
- url = uri.toString();
- if (url != null) {
- switch (requestCode) {
- case INTENT_GETOPENFILENAME: {
- //Log.d(TAG, "onActivityResult INTENT_GETOPENFILENAME " + url);
- int openResult = onFileOpen(url);
- if (openResult > 0) {
- saveLastDocument(url);
- Utils.makeUriPersistable(this, data, uri);
- } else if(openResult == -2 && Build.VERSION.SDK_INT >= Build.VERSION_CODES.LOLLIPOP) { // >= API 21
- // For security reason, you must select the folder where are the KML and ROM files and then, reopen this file!
+ case INTENT_OBJECT_LOAD: {
+ if(debug) Log.d(TAG, "onActivityResult INTENT_OBJECT_LOAD " + url);
+ NativeLib.onObjectLoad(url);
+ break;
+ }
+ case INTENT_OBJECT_SAVE: {
+ if(debug) Log.d(TAG, "onActivityResult INTENT_OBJECT_SAVE " + url);
+ NativeLib.onObjectSave(url, null);
+ break;
+ }
+ case INTENT_PICK_KML_FOLDER_FOR_NEW_FILE:
+ case INTENT_PICK_KML_FOLDER_FOR_CHANGING:
+ case INTENT_PICK_KML_FOLDER_FOR_SETTINGS:
+ case INTENT_PICK_KML_FOLDER_FOR_SECURITY: {
+ if(debug) Log.d(TAG, "onActivityResult INTENT_PICK_KML_FOLDER " + url);
+ settings.putBoolean("settings_kml_default", false);
+ settings.putString("settings_kml_folder", url);
+ updateFromPreferences("settings_kml", true);
+ Utils.makeUriPersistableReadOnly(this, data, uri);
+
+ switch (requestCode) {
+ case INTENT_PICK_KML_FOLDER_FOR_NEW_FILE:
+ OnFileNew();
+ break;
+ case INTENT_PICK_KML_FOLDER_FOR_CHANGING:
+ OnViewScript();
+ break;
+ case INTENT_PICK_KML_FOLDER_FOR_SETTINGS:
+ break;
+ case INTENT_PICK_KML_FOLDER_FOR_SECURITY:
new AlertDialog.Builder(this)
- .setTitle(getString(R.string.message_open_security))
- .setMessage(getString(R.string.message_open_security_description))
+ .setTitle(getString(R.string.message_open_security_retry))
+ .setMessage(getString(R.string.message_open_security_retry_description))
.setPositiveButton(android.R.string.ok, (dialog, which) -> {
- Intent intent = new Intent(Intent.ACTION_OPEN_DOCUMENT_TREE);
- startActivityForResult(intent, INTENT_PICK_KML_FOLDER_FOR_SECURITY);
}).show();
- }
- break;
+ break;
}
- case INTENT_GETSAVEFILENAME: {
- //Log.d(TAG, "onActivityResult INTENT_GETSAVEFILENAME " + url);
- if (NativeLib.onFileSaveAs(url) != 0) {
- showAlert(getString(R.string.message_state_saved));
- settings.saveInStateFile(this, url);
- saveLastDocument(url);
- Utils.makeUriPersistable(this, data, uri);
- displayFilename(url);
- if (fileSaveAsCallback != null)
- fileSaveAsCallback.run();
- }
- break;
- }
- case INTENT_OBJECT_LOAD: {
- //Log.d(TAG, "onActivityResult INTENT_OBJECT_LOAD " + url);
- NativeLib.onObjectLoad(url);
- break;
- }
- case INTENT_OBJECT_SAVE: {
- //Log.d(TAG, "onActivityResult INTENT_OBJECT_SAVE " + url);
- NativeLib.onObjectSave(url, null);
- break;
- }
- case INTENT_PICK_KML_FOLDER_FOR_NEW_FILE:
- case INTENT_PICK_KML_FOLDER_FOR_CHANGING:
- case INTENT_PICK_KML_FOLDER_FOR_SETTINGS:
- case INTENT_PICK_KML_FOLDER_FOR_SECURITY: {
- //Log.d(TAG, "onActivityResult INTENT_PICK_KML_FOLDER " + url);
- settings.putBoolean("settings_kml_default", false, true);
- settings.putString("settings_kml_folder", url, true);
- updateFromPreferences("settings_kml", true);
- Utils.makeUriPersistableReadOnly(this, data, uri);
-
- switch (requestCode) {
- case INTENT_PICK_KML_FOLDER_FOR_NEW_FILE:
- OnFileNew();
- break;
- case INTENT_PICK_KML_FOLDER_FOR_CHANGING:
- OnViewScript();
- break;
- case INTENT_PICK_KML_FOLDER_FOR_SETTINGS:
- break;
- case INTENT_PICK_KML_FOLDER_FOR_SECURITY:
- new AlertDialog.Builder(this)
- .setTitle(getString(R.string.message_open_security_retry))
- .setMessage(getString(R.string.message_open_security_retry_description))
- .setPositiveButton(android.R.string.ok, (dialog, which) -> {
- }).show();
- break;
- }
- break;
- }
- case INTENT_CREATE_RAM_CARD: {
- //Log.d(TAG, "onActivityResult INTENT_CREATE_RAM_CARD " + url);
- if(selectedRAMSize > 0) {
- int size = 2 * selectedRAMSize;
- FileOutputStream fileOutputStream;
- try {
- ParcelFileDescriptor pfd = getContentResolver().openFileDescriptor(uri, "w");
- if(pfd != null) {
- fileOutputStream = new FileOutputStream(pfd.getFileDescriptor());
- byte[] zero = new byte[1024];
- Arrays.fill(zero, (byte) 0);
- for (int i = 0; i < size; i++)
- fileOutputStream.write(zero);
- fileOutputStream.flush();
- fileOutputStream.close();
- }
- } catch (IOException e) {
- e.printStackTrace();
- }
- selectedRAMSize = -1;
- }
-
- break;
- }
- case INTENT_MACRO_LOAD: {
- //Log.d(TAG, "onActivityResult INTENT_MACRO_LOAD " + url);
- NativeLib.onToolMacroPlay(url);
- updateNavigationDrawerItems();
- break;
- }
- case INTENT_MACRO_SAVE: {
- //Log.d(TAG, "onActivityResult INTENT_MACRO_SAVE " + url);
- NativeLib.onToolMacroNew(url);
- updateNavigationDrawerItems();
- break;
- }
- default:
- break;
+ break;
}
+ case INTENT_CREATE_RAM_CARD: {
+ if(debug) Log.d(TAG, "onActivityResult INTENT_CREATE_RAM_CARD " + url);
+ if(selectedRAMSize > 0) {
+ int size = 2 * selectedRAMSize;
+ FileOutputStream fileOutputStream;
+ try {
+ ParcelFileDescriptor pfd = getContentResolver().openFileDescriptor(uri, "w");
+ if(pfd != null) {
+ fileOutputStream = new FileOutputStream(pfd.getFileDescriptor());
+ byte[] zero = new byte[1024];
+ Arrays.fill(zero, (byte) 0);
+ for (int i = 0; i < size; i++)
+ fileOutputStream.write(zero);
+ fileOutputStream.flush();
+ fileOutputStream.close();
+ }
+ } catch (IOException e) {
+ e.printStackTrace();
+ }
+ selectedRAMSize = -1;
+ }
+
+ break;
+ }
+ case INTENT_MACRO_LOAD: {
+ if(debug) Log.d(TAG, "onActivityResult INTENT_MACRO_LOAD " + url);
+ NativeLib.onToolMacroPlay(url);
+ updateNavigationDrawerItems();
+ break;
+ }
+ case INTENT_MACRO_SAVE: {
+ if(debug) Log.d(TAG, "onActivityResult INTENT_MACRO_SAVE " + url);
+ NativeLib.onToolMacroNew(url);
+ updateNavigationDrawerItems();
+ break;
+ }
+ default:
+ break;
}
}
}
@@ -1160,7 +1150,7 @@ public class MainActivity extends AppCompatActivity implements NavigationView.On
}
private void saveLastDocument(String url) {
- settings.putString("lastDocument", url, true);
+ settings.putString("lastDocument", url);
if(url != null && !url.isEmpty())
mruLinkedHashMap.put(url, null);
@@ -1177,14 +1167,7 @@ public class MainActivity extends AppCompatActivity implements NavigationView.On
} else {
mainScreenView.setEnablePanAndScale(false);
mainScreenView.setVisibility(View.GONE);
-
- Resources.Theme theme = getTheme();
- if (theme != null) {
- TypedValue tv = new TypedValue();
- theme.resolveAttribute(android.R.attr.colorForeground, tv, true);
- int iconColor = getResources().getColor(tv.resourceId);
- imageButtonMenu.setColorFilter(iconColor);
- }
+ imageButtonMenu.setColorFilter(Utils.getThemedColor(this, android.R.attr.colorForeground));
}
}
@@ -1192,18 +1175,18 @@ public class MainActivity extends AppCompatActivity implements NavigationView.On
// Eventually, close the previous state file
NativeLib.onFileClose();
- settings.setDefaultSettings(true);
+ settings.setIsDefaultSettings(true);
showCalculatorView(false);
displayFilename("");
// Pre-Load the embedded settings from the end of the classic state file
- settings.setDefaultSettings(false);
+ settings.setIsDefaultSettings(false);
settings.clearEmbeddedStateSettings();
settings.loadFromStateFile(this, url);
// Update the Emu VM with the new settings
- updateFromPreferences(null);
+ updateFromPreferences(null, false);
// Load the genuine state file
int result = NativeLib.onFileOpen(url);
@@ -1214,7 +1197,7 @@ public class MainActivity extends AppCompatActivity implements NavigationView.On
showKMLLog();
} else {
// Because it failed to load the state file, we switch to the default settings
- settings.setDefaultSettings(true);
+ settings.setIsDefaultSettings(true);
settings.clearEmbeddedStateSettings();
showKMLLogForce();
}
@@ -1564,147 +1547,140 @@ public class MainActivity extends AppCompatActivity implements NavigationView.On
updateFromPreferences("settings_port1", true);
}
- private void updateFromPreferences(Set keys) {
- if(keys != null) {
- for (String settingKey : keys)
- updateFromPreferences(settingKey, false);
- } else {
- String[] settingKeys = {
- "settings_realspeed", "settings_grayscale", "settings_rotation", "settings_auto_layout", "settings_allow_pinch_zoom", "settings_lcd_overlapping_mode", "settings_lcd_pixel_borders",
- "settings_hide_bar", "settings_hide_button_menu", "settings_sound_volume", "settings_haptic_feedback",
- "settings_background_kml_color", "settings_background_fallback_color",
- "settings_printer_model", "settings_printer_prevent_line_wrap", "settings_macro",
- "settings_kml", "settings_port1", "settings_port2" };
- for (String settingKey : settingKeys)
- updateFromPreferences(settingKey, false);
- }
- }
private void updateFromPreferences(String key, boolean isDynamic) {
int isDynamicValue = isDynamic ? 1 : 0;
- switch (key) {
- case "settings_realspeed":
- NativeLib.setConfiguration(key, isDynamicValue, settings.getBoolean(key, false) ? 1 : 0, 0, null);
- break;
- case "settings_grayscale":
- NativeLib.setConfiguration(key, isDynamicValue, settings.getBoolean(key, false) ? 1 : 0, 0, null);
- break;
+ if(key == null) {
+ String[] settingKeys = {
+ "settings_realspeed", "settings_grayscale", "settings_rotation", "settings_auto_layout", "settings_allow_pinch_zoom", "settings_lcd_overlapping_mode", "settings_lcd_pixel_borders",
+ "settings_hide_bar", "settings_hide_button_menu", "settings_sound_volume", "settings_haptic_feedback",
+ "settings_background_kml_color", "settings_background_fallback_color",
+ "settings_printer_model", "settings_macro",
+ "settings_kml", "settings_port1", "settings_port2" };
+ for (String settingKey : settingKeys)
+ updateFromPreferences(settingKey, false);
+ } else {
+ switch (key) {
+ case "settings_realspeed":
+ NativeLib.setConfiguration(key, isDynamicValue, settings.getBoolean(key, false) ? 1 : 0, 0, null);
+ break;
+ case "settings_grayscale":
+ NativeLib.setConfiguration(key, isDynamicValue, settings.getBoolean(key, false) ? 1 : 0, 0, null);
+ break;
- case "settings_rotation":
- int rotationMode = 0;
- try {
- rotationMode = Integer.parseInt(settings.getString("settings_rotation", "0"));
- } catch (NumberFormatException ex) {
- // Catch bad number format
- }
- mainScreenView.setRotationMode(rotationMode, isDynamic);
- break;
- case "settings_auto_layout":
- int autoLayoutMode = 1;
- try {
- autoLayoutMode = Integer.parseInt(settings.getString("settings_auto_layout", "1"));
- } catch (NumberFormatException ex) {
- // Catch bad number format
- }
- mainScreenView.setAutoLayout(autoLayoutMode, isDynamic);
- break;
- case "settings_allow_pinch_zoom":
- mainScreenView.setAllowPinchZoom(settings.getBoolean("settings_allow_pinch_zoom", true));
- break;
- case "settings_lcd_overlapping_mode":
- int overlappingLCDMode = LCDOverlappingView.OVERLAPPING_LCD_MODE_NONE;
- try {
- overlappingLCDMode = Integer.parseInt(settings.getString("settings_lcd_overlapping_mode", "0"));
- } catch (NumberFormatException ex) {
- // Catch bad number format
- }
- lcdOverlappingView.setOverlappingLCDMode(overlappingLCDMode);
- break;
- case "settings_lcd_pixel_borders":
- boolean usePixelBorders = settings.getBoolean("settings_lcd_pixel_borders", false);
- mainScreenView.setUsePixelBorders(usePixelBorders);
- lcdOverlappingView.setUsePixelBorders(usePixelBorders);
- break;
- case "settings_hide_bar":
- case "settings_hide_bar_status":
- case "settings_hide_bar_nav":
- if(settings.getBoolean("settings_hide_bar_status", false)
- || settings.getBoolean("settings_hide_bar_nav", false))
- hideSystemUI();
- else
- showSystemUI();
- break;
- case "settings_hide_button_menu":
- imageButtonMenu.setVisibility(settings.getBoolean("settings_hide_button_menu", false) ? View.GONE : View.VISIBLE);
- break;
+ case "settings_rotation":
+ int rotationMode = 0;
+ try {
+ rotationMode = Integer.parseInt(settings.getString("settings_rotation", "0"));
+ } catch (NumberFormatException ex) {
+ // Catch bad number format
+ }
+ mainScreenView.setRotationMode(rotationMode, isDynamic);
+ break;
+ case "settings_auto_layout":
+ int autoLayoutMode = 1;
+ try {
+ autoLayoutMode = Integer.parseInt(settings.getString("settings_auto_layout", "1"));
+ } catch (NumberFormatException ex) {
+ // Catch bad number format
+ }
+ mainScreenView.setAutoLayout(autoLayoutMode, isDynamic);
+ break;
+ case "settings_allow_pinch_zoom":
+ mainScreenView.setAllowPinchZoom(settings.getBoolean("settings_allow_pinch_zoom", true));
+ break;
+ case "settings_lcd_overlapping_mode":
+ int overlappingLCDMode = LCDOverlappingView.OVERLAPPING_LCD_MODE_NONE;
+ try {
+ overlappingLCDMode = Integer.parseInt(settings.getString("settings_lcd_overlapping_mode", "0"));
+ } catch (NumberFormatException ex) {
+ // Catch bad number format
+ }
+ lcdOverlappingView.setOverlappingLCDMode(overlappingLCDMode);
+ break;
+ case "settings_lcd_pixel_borders":
+ boolean usePixelBorders = settings.getBoolean("settings_lcd_pixel_borders", false);
+ mainScreenView.setUsePixelBorders(usePixelBorders);
+ lcdOverlappingView.setUsePixelBorders(usePixelBorders);
+ break;
+ case "settings_hide_bar":
+ case "settings_hide_bar_status":
+ case "settings_hide_bar_nav":
+ if (settings.getBoolean("settings_hide_bar_status", false)
+ || settings.getBoolean("settings_hide_bar_nav", false))
+ hideSystemUI();
+ else
+ showSystemUI();
+ break;
+ case "settings_hide_button_menu":
+ imageButtonMenu.setVisibility(settings.getBoolean("settings_hide_button_menu", false) ? View.GONE : View.VISIBLE);
+ break;
- case "settings_sound_volume": {
- int volumeOption = settings.getInt("settings_sound_volume", 64);
- NativeLib.setConfiguration("settings_sound_volume", isDynamicValue, volumeOption, 0, null);
- break;
- }
- case "settings_haptic_feedback":
- // Nothing to do
- break;
+ case "settings_sound_volume": {
+ int volumeOption = settings.getInt("settings_sound_volume", 64);
+ NativeLib.setConfiguration("settings_sound_volume", isDynamicValue, volumeOption, 0, null);
+ break;
+ }
+ case "settings_haptic_feedback":
+ // Nothing to do
+ break;
- case "settings_background_kml_color":
- mainScreenView.setBackgroundKmlColor(settings.getBoolean("settings_background_kml_color", false));
- break;
- case "settings_background_fallback_color":
- try {
- mainScreenView.setBackgroundFallbackColor(Integer.parseInt(settings.getString("settings_background_fallback_color", "0")));
- } catch (NumberFormatException ex) {
- // Catch bad number format
- }
- break;
- case "settings_printer_model":
- try {
- printerSimulator.setPrinterModel82240A(Integer.parseInt(settings.getString("settings_printer_model", "1")) == 0);
- } catch (NumberFormatException ex) {
- // Catch bad number format
- }
- break;
- case "settings_printer_prevent_line_wrap":
- printerSimulator.setPreventLineWrap(settings.getBoolean("settings_printer_prevent_line_wrap", false));
- break;
+ case "settings_background_kml_color":
+ mainScreenView.setBackgroundKmlColor(settings.getBoolean("settings_background_kml_color", false));
+ break;
+ case "settings_background_fallback_color":
+ try {
+ mainScreenView.setBackgroundFallbackColor(Integer.parseInt(settings.getString("settings_background_fallback_color", "0")));
+ } catch (NumberFormatException ex) {
+ // Catch bad number format
+ }
+ break;
+ case "settings_printer_model":
+ try {
+ printerSimulator.setPrinterModel82240A(Integer.parseInt(settings.getString("settings_printer_model", "1")) == 0);
+ } catch (NumberFormatException ex) {
+ // Catch bad number format
+ }
+ break;
- case "settings_kml":
- case "settings_kml_default":
- case "settings_kml_folder":
- kmlFolderUseDefault = settings.getBoolean("settings_kml_default", true);
- if(!kmlFolderUseDefault) {
- kmlFolderURL = settings.getString("settings_kml_folder", "");
- // https://github.com/googlesamples/android-DirectorySelection
- // https://stackoverflow.com/questions/44185477/intent-action-open-document-tree-doesnt-seem-to-return-a-real-path-to-drive/44185706
- // https://stackoverflow.com/questions/26744842/how-to-use-the-new-sd-card-access-api-presented-for-android-5-0-lollipop
- }
- kmlFolderChange = true;
- break;
+ case "settings_kml":
+ case "settings_kml_default":
+ case "settings_kml_folder":
+ kmlFolderUseDefault = settings.getBoolean("settings_kml_default", true);
+ if (!kmlFolderUseDefault) {
+ kmlFolderURL = settings.getString("settings_kml_folder", "");
+ // https://github.com/googlesamples/android-DirectorySelection
+ // https://stackoverflow.com/questions/44185477/intent-action-open-document-tree-doesnt-seem-to-return-a-real-path-to-drive/44185706
+ // https://stackoverflow.com/questions/26744842/how-to-use-the-new-sd-card-access-api-presented-for-android-5-0-lollipop
+ }
+ kmlFolderChange = true;
+ break;
- case "settings_macro":
- case "settings_macro_real_speed":
- case "settings_macro_manual_speed":
- boolean macroRealSpeed = settings.getBoolean("settings_macro_real_speed", true);
- int macroManualSpeed = settings.getInt("settings_macro_manual_speed", 500);
- NativeLib.setConfiguration("settings_macro", isDynamicValue, macroRealSpeed ? 1 : 0, macroManualSpeed, null);
- break;
+ case "settings_macro":
+ case "settings_macro_real_speed":
+ case "settings_macro_manual_speed":
+ boolean macroRealSpeed = settings.getBoolean("settings_macro_real_speed", true);
+ int macroManualSpeed = settings.getInt("settings_macro_manual_speed", 500);
+ NativeLib.setConfiguration("settings_macro", isDynamicValue, macroRealSpeed ? 1 : 0, macroManualSpeed, null);
+ break;
- case "settings_port1":
- case "settings_port1en":
- case "settings_port1wr":
- NativeLib.setConfiguration("settings_port1", isDynamicValue,
- settings.getBoolean("settings_port1en", false) ? 1 : 0,
- settings.getBoolean("settings_port1wr", false) ? 1 : 0,
- null);
- break;
- case "settings_port2":
- case "settings_port2en":
- case "settings_port2wr":
- case "settings_port2load":
- NativeLib.setConfiguration("settings_port2", isDynamicValue,
- settings.getBoolean("settings_port2en", false) ? 1 : 0,
- settings.getBoolean("settings_port2wr", false) ? 1 : 0,
- settings.getString("settings_port2load", ""));
- break;
+ case "settings_port1":
+ case "settings_port1en":
+ case "settings_port1wr":
+ NativeLib.setConfiguration("settings_port1", isDynamicValue,
+ settings.getBoolean("settings_port1en", false) ? 1 : 0,
+ settings.getBoolean("settings_port1wr", false) ? 1 : 0,
+ null);
+ break;
+ case "settings_port2":
+ case "settings_port2en":
+ case "settings_port2wr":
+ case "settings_port2load":
+ NativeLib.setConfiguration("settings_port2", isDynamicValue,
+ settings.getBoolean("settings_port2en", false) ? 1 : 0,
+ settings.getBoolean("settings_port2wr", false) ? 1 : 0,
+ settings.getString("settings_port2load", ""));
+ break;
+ }
}
}
diff --git a/app/src/main/java/org/emulator/forty/eight/SettingsActivity.java b/app/src/main/java/org/emulator/forty/eight/SettingsActivity.java
deleted file mode 100644
index 6ae39cc..0000000
--- a/app/src/main/java/org/emulator/forty/eight/SettingsActivity.java
+++ /dev/null
@@ -1,281 +0,0 @@
-// This program is free software; you can redistribute it and/or modify
-// it under the terms of the GNU General Public License as published by
-// the Free Software Foundation; either version 2 of the License, or
-// (at your option) any later version.
-//
-// This program is distributed in the hope that it will be useful,
-// but WITHOUT ANY WARRANTY; without even the implied warranty of
-// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
-// GNU General Public License for more details.
-//
-// You should have received a copy of the GNU General Public License along
-// with this program; if not, write to the Free Software Foundation, Inc.,
-// 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA.
-
-package org.emulator.forty.eight;
-
-import android.app.Activity;
-import android.content.Intent;
-import android.content.SharedPreferences;
-import android.content.res.Configuration;
-import android.net.Uri;
-import android.os.Build;
-import android.os.Bundle;
-import android.text.InputType;
-import android.util.Log;
-import android.view.MenuItem;
-import android.widget.EditText;
-
-import java.util.HashSet;
-import java.util.Locale;
-import java.util.Objects;
-
-import androidx.annotation.Nullable;
-import androidx.appcompat.app.ActionBar;
-import androidx.appcompat.app.AlertDialog;
-import androidx.appcompat.app.AppCompatActivity;
-import androidx.preference.Preference;
-import androidx.preference.PreferenceDataStore;
-import androidx.preference.PreferenceFragmentCompat;
-import androidx.preference.PreferenceManager;
-import androidx.preference.SeekBarPreference;
-
-import org.emulator.calculator.EmuApplication;
-import org.emulator.calculator.NativeLib;
-import org.emulator.calculator.Settings;
-import org.emulator.calculator.Utils;
-
-public class SettingsActivity extends AppCompatActivity {
-
- private static final String TAG = "SettingsActivity";
- protected final boolean debug = false;
-
- private static Settings settings;
- private HashSet settingsKeyChanged = new HashSet<>();
- private SharedPreferences.OnSharedPreferenceChangeListener sharedPreferenceChangeListener = (sharedPreferences, key) -> settingsKeyChanged.add(key);
- private GeneralPreferenceFragment generalPreferenceFragment;
-
- @Override
- protected void onCreate(Bundle savedInstanceState) {
- super.onCreate(savedInstanceState);
-
- settings = EmuApplication.getSettings();
- settings.registerOnSharedPreferenceChangeListener(sharedPreferenceChangeListener);
-
- ActionBar actionBar = getSupportActionBar();
- if (actionBar != null) {
- // Show the Up button in the action bar.
- actionBar.setDisplayHomeAsUpEnabled(true);
- }
-
- generalPreferenceFragment = new GeneralPreferenceFragment();
- getSupportFragmentManager().beginTransaction().replace(android.R.id.content, generalPreferenceFragment).commit();
- }
-
- @Override
- protected void onDestroy() {
- settings.unregisterOnSharedPreferenceChangeListener(sharedPreferenceChangeListener);
- super.onDestroy();
- }
-
- @Override
- public boolean onOptionsItemSelected(MenuItem item) {
- int id = item.getItemId();
- if (id == android.R.id.home) {
- onBackPressed();
- return true;
- }
- return super.onOptionsItemSelected(item);
- }
-
- @Override
- public void onBackPressed() {
- Intent resultIntent = new Intent();
- resultIntent.putExtra("changedKeys", settingsKeyChanged.toArray(new String[0]));
- setResult(Activity.RESULT_OK, resultIntent);
- finish();
- }
-
- /**
- * This fragment shows general preferences only. It is used when the
- * activity is showing a two-pane settings UI.
- */
- public static class GeneralPreferenceFragment extends PreferenceFragmentCompat {
-
- Preference preferencePort2load = null;
-
- @Override
- public void onCreatePreferences(Bundle savedInstanceState, String rootKey) {
- getPreferenceManager().setPreferenceDataStore(EmuApplication.getSettings());
-
- // Load the preferences from an XML resource
- setPreferencesFromResource(R.xml.pref_general, rootKey);
-
- setHasOptionsMenu(true);
-
- // Sound settings
-
- SeekBarPreference preferenceSoundVolume = findPreference("settings_sound_volume");
- if(preferenceSoundVolume != null) {
- if(!NativeLib.getSoundEnabled()) {
- preferenceSoundVolume.setSummary("Cannot initialize the sound engine.");
- preferenceSoundVolume.setEnabled(false);
- } else {
- preferenceSoundVolume.setOnPreferenceClickListener(preference -> {
- AlertDialog.Builder alert = new AlertDialog.Builder(Objects.requireNonNull(getContext()));
- alert.setTitle(R.string.settings_sound_volume_dialog_title);
- final EditText input = new EditText(getContext());
- input.setInputType(InputType.TYPE_CLASS_NUMBER);
- input.setRawInputType(Configuration.KEYBOARD_12KEY);
- input.setFocusable(true);
- input.setText(String.format(Locale.US,"%d", preferenceSoundVolume.getValue()));
- alert.setView(input);
- alert.setPositiveButton(R.string.message_ok, (dialog, whichButton) -> {
- String newValueText = input.getText().toString();
- try {
- int newValue = Integer.parseInt(newValueText);
- if(newValue >= preferenceSoundVolume.getMin() && newValue <= preferenceSoundVolume.getMax())
- preferenceSoundVolume.setValue(newValue);
- } catch (NumberFormatException ignored) {}
- });
- alert.setNegativeButton(R.string.message_cancel, (dialog, whichButton) -> {});
- alert.show();
- return true;
- });
- }
- }
-
- // Background color settings
-
- Preference preferenceBackgroundFallbackColor = findPreference("settings_background_fallback_color");
-// final ColorPickerPreferenceCompat preferenceBackgroundCustomColor = (ColorPickerPreferenceCompat)findPreference("settings_background_custom_color");
- if(preferenceBackgroundFallbackColor != null /*&& preferenceBackgroundCustomColor != null*/) {
- final String[] stringArrayBackgroundFallbackColor = getResources().getStringArray(R.array.settings_background_fallback_color_item);
- Preference.OnPreferenceChangeListener onPreferenceChangeListenerBackgroundFallbackColor = (preference, value) -> {
- if(value != null) {
- String stringValue = value.toString();
- int backgroundFallbackColor = -1;
- try {
- backgroundFallbackColor = Integer.parseInt(stringValue);
- } catch (NumberFormatException ignored) {}
- if(backgroundFallbackColor >= 0 && backgroundFallbackColor < stringArrayBackgroundFallbackColor.length)
- preference.setSummary(stringArrayBackgroundFallbackColor[backgroundFallbackColor]);
-// preferenceBackgroundCustomColor.setEnabled(backgroundFallbackColor == 2);
- }
- return true;
- };
- preferenceBackgroundFallbackColor.setOnPreferenceChangeListener(onPreferenceChangeListenerBackgroundFallbackColor);
- onPreferenceChangeListenerBackgroundFallbackColor.onPreferenceChange(preferenceBackgroundFallbackColor,
- settings.getString(preferenceBackgroundFallbackColor.getKey(), "0"));
-
-
- //preferenceBackgroundCustomColor.setColorValue(customColor);
-
-// Preference.OnPreferenceChangeListener onPreferenceChangeListenerBackgroundCustomColor = new Preference.OnPreferenceChangeListener() {
-// @Override
-// public boolean onPreferenceChange(Preference preference, Object value) {
-// if(value != null) {
-// int customColor = (Integer)value;
-// }
-// return true;
-// }
-// };
-// preferenceBackgroundCustomColor.setOnPreferenceChangeListener(onPreferenceChangeListenerBackgroundCustomColor);
-// onPreferenceChangeListenerBackgroundCustomColor.onPreferenceChange(preferenceBackgroundCustomColor, sharedPreferences.getBoolean(preferenceBackgroundCustomColor.getKey(), false));
- }
-
- // Macro
-
- Preference preferenceMacroRealSpeed = findPreference("settings_macro_real_speed");
- Preference preferenceMacroManualSpeed = findPreference("settings_macro_manual_speed");
- if(preferenceMacroRealSpeed != null && preferenceMacroManualSpeed != null) {
- Preference.OnPreferenceChangeListener onPreferenceChangeListenerMacroRealSpeed = (preference, value) -> {
- if(value != null)
- preferenceMacroManualSpeed.setEnabled(!(Boolean) value);
- return true;
- };
- preferenceMacroRealSpeed.setOnPreferenceChangeListener(onPreferenceChangeListenerMacroRealSpeed);
- onPreferenceChangeListenerMacroRealSpeed.onPreferenceChange(preferenceMacroRealSpeed, settings.getBoolean(preferenceMacroRealSpeed.getKey(), true));
- }
-
- // Ports 1 & 2 settings
-
- Preference preferencePort1en = findPreference("settings_port1en");
- Preference preferencePort1wr = findPreference("settings_port1wr");
- Preference preferencePort2en = findPreference("settings_port2en");
- Preference preferencePort2wr = findPreference("settings_port2wr");
- preferencePort2load = findPreference("settings_port2load");
- if(preferencePort1en != null && preferencePort1wr != null
- && preferencePort2en != null && preferencePort2wr != null
- && preferencePort2load != null) {
- boolean enablePortPreferences = NativeLib.isPortExtensionPossible();
-
- Preference.OnPreferenceChangeListener onPreferenceChangeListenerPort1en = (preference, value) -> {
- preferencePort1en.setEnabled(enablePortPreferences);
- preferencePort1wr.setEnabled(enablePortPreferences);
- return true;
- };
- preferencePort1en.setOnPreferenceChangeListener(onPreferenceChangeListenerPort1en);
- onPreferenceChangeListenerPort1en.onPreferenceChange(preferencePort1en, settings.getBoolean(preferencePort1en.getKey(), false));
-
- Preference.OnPreferenceChangeListener onPreferenceChangeListenerPort2en = (preference, value) -> {
- preferencePort2en.setEnabled(enablePortPreferences);
- preferencePort2wr.setEnabled(enablePortPreferences);
- preferencePort2load.setEnabled(enablePortPreferences);
- return true;
- };
- preferencePort2en.setOnPreferenceChangeListener(onPreferenceChangeListenerPort2en);
- onPreferenceChangeListenerPort2en.onPreferenceChange(preferencePort2en, settings.getBoolean(preferencePort2en.getKey(), false));
-
- updatePort2LoadFilename(settings.getString(preferencePort2load.getKey(), ""));
- preferencePort2load.setOnPreferenceClickListener(preference -> {
- Intent intent = new Intent(Intent.ACTION_OPEN_DOCUMENT);
- intent.addCategory(Intent.CATEGORY_OPENABLE);
- intent.setType("*/*");
- intent.putExtra(Intent.EXTRA_TITLE, "shared.bin");
- Activity activity = getActivity();
- if (activity != null)
- activity.startActivityForResult(intent, MainActivity.INTENT_PORT2LOAD);
- return true;
- });
- }
- }
-
- void updatePort2LoadFilename(String port2Filename) {
- if(preferencePort2load != null) {
- String displayName = port2Filename;
- try {
- displayName = Utils.getFileName(getActivity(), port2Filename);
- } catch (Exception e) {
- // Do nothing
- }
- preferencePort2load.setSummary(displayName);
- }
- }
- }
-
- @Override
- public void onActivityResult(int requestCode, int resultCode, @Nullable Intent data) {
- if(resultCode == Activity.RESULT_OK && data != null) {
- if(requestCode == MainActivity.INTENT_PORT2LOAD) {
- Uri uri = data.getData();
- String url;
- if (uri != null) {
- if(debug) Log.d(TAG, "onActivityResult INTENT_PORT2LOAD " + uri.toString());
- url = uri.toString();
- settings.putString("settings_port2load", url);
- makeUriPersistable(data, uri);
- if(generalPreferenceFragment != null)
- generalPreferenceFragment.updatePort2LoadFilename(url);
- }
- }
- }
- super.onActivityResult(requestCode, resultCode, data);
- }
-
- private void makeUriPersistable(Intent data, Uri uri) {
- int takeFlags = data.getFlags() & (Intent.FLAG_GRANT_READ_URI_PERMISSION | Intent.FLAG_GRANT_WRITE_URI_PERMISSION);
- if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.KITKAT)
- getContentResolver().takePersistableUriPermission(uri, takeFlags);
- }
-}
diff --git a/app/src/main/java/org/emulator/forty/eight/SettingsFragment.java b/app/src/main/java/org/emulator/forty/eight/SettingsFragment.java
new file mode 100644
index 0000000..4d4bd4b
--- /dev/null
+++ b/app/src/main/java/org/emulator/forty/eight/SettingsFragment.java
@@ -0,0 +1,343 @@
+// This program is free software; you can redistribute it and/or modify
+// it under the terms of the GNU General Public License as published by
+// the Free Software Foundation; either version 2 of the License, or
+// (at your option) any later version.
+//
+// This program is distributed in the hope that it will be useful,
+// but WITHOUT ANY WARRANTY; without even the implied warranty of
+// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+// GNU General Public License for more details.
+//
+// You should have received a copy of the GNU General Public License along
+// with this program; if not, write to the Free Software Foundation, Inc.,
+// 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA.
+
+package org.emulator.forty.eight;
+
+import android.app.Activity;
+import android.app.Dialog;
+import android.content.Intent;
+import android.content.res.Configuration;
+import android.graphics.BlendMode;
+import android.graphics.BlendModeColorFilter;
+import android.graphics.PorterDuff;
+import android.graphics.drawable.Drawable;
+import android.net.Uri;
+import android.os.Build;
+import android.os.Bundle;
+import android.text.InputType;
+import android.util.Log;
+import android.view.LayoutInflater;
+import android.view.Menu;
+import android.view.View;
+import android.view.ViewGroup;
+import android.view.Window;
+import android.widget.EditText;
+
+import androidx.annotation.NonNull;
+import androidx.annotation.Nullable;
+import androidx.appcompat.app.AlertDialog;
+import androidx.appcompat.app.AppCompatDialog;
+import androidx.appcompat.app.AppCompatDialogFragment;
+import androidx.appcompat.widget.Toolbar;
+import androidx.fragment.app.Fragment;
+import androidx.preference.Preference;
+import androidx.preference.PreferenceFragmentCompat;
+import androidx.preference.SeekBarPreference;
+
+import org.emulator.calculator.EmuApplication;
+import org.emulator.calculator.NativeLib;
+import org.emulator.calculator.Settings;
+import org.emulator.calculator.Utils;
+
+import java.util.HashSet;
+import java.util.Locale;
+
+public class SettingsFragment extends AppCompatDialogFragment {
+
+ private static final String TAG = "SettingsFragment";
+ protected final boolean debug = false;
+
+ private static Settings settings;
+ private HashSet settingsKeyChanged = new HashSet<>();
+ private Settings.OnOneKeyChangedListener sharedPreferenceChangeListener = (key) -> settingsKeyChanged.add(key);
+ private GeneralPreferenceFragment generalPreferenceFragment;
+
+ public interface OnSettingsKeyChangedListener {
+ void onSettingsKeyChanged(HashSet settingsKeyChanged);
+ }
+
+ private OnSettingsKeyChangedListener onSettingsKeyChangedListener;
+
+ @Override
+ public void onCreate(Bundle savedInstanceState) {
+ super.onCreate(savedInstanceState);
+
+ settings = EmuApplication.getSettings();
+ settings.registerOnOneKeyChangeListener(sharedPreferenceChangeListener);
+
+ setStyle(AppCompatDialogFragment.STYLE_NO_FRAME, R.style.AppTheme);
+ }
+
+ @NonNull
+ @Override
+ public Dialog onCreateDialog(Bundle savedInstanceState) {
+ Dialog dialog = new AppCompatDialog(getContext(), getTheme()) {
+ @Override
+ public void onBackPressed() {
+ dialogResult();
+ dismiss();
+ }
+ };
+ dialog.requestWindowFeature(Window.FEATURE_NO_TITLE);
+ return dialog;
+ }
+
+ @Override
+ public View onCreateView(@NonNull LayoutInflater inflater, ViewGroup container, Bundle savedInstanceState) {
+
+ String title = getString(settings.getIsDefaultSettings() ? R.string.dialog_common_settings_title : R.string.dialog_state_settings_title);
+ Dialog dialog = getDialog();
+ if(dialog != null)
+ dialog.setTitle(title);
+
+ View view = inflater.inflate(R.layout.fragment_settings, container, false);
+
+ // Configure the toolbar
+
+ Toolbar toolbar = view.findViewById(R.id.my_toolbar);
+ toolbar.setTitle(title);
+ Utils.colorizeDrawableWithColor(requireContext(), toolbar.getNavigationIcon(), android.R.attr.colorForeground);
+ toolbar.setNavigationOnClickListener(v -> {
+ dialogResult();
+ dismiss();
+ });
+ toolbar.inflateMenu(R.menu.fragment_settings);
+ Menu menu = toolbar.getMenu();
+ menu.findItem(R.id.menu_settings_reset_to_default).setEnabled(settings.getIsDefaultSettings());
+ menu.findItem(R.id.menu_settings_reset_to_common).setEnabled(!settings.getIsDefaultSettings());
+ toolbar.setOnMenuItemClickListener(item -> {
+ int id = item.getItemId();
+ if(id == R.id.menu_settings_reset_to_default) {
+ settings.clearCommonDefaultSettings();
+ restartPreferenceFragment();
+ } else if(id == R.id.menu_settings_reset_to_common) {
+ settings.clearEmbeddedStateSettings();
+ restartPreferenceFragment();
+ }
+ return true;
+ });
+
+ // Insert the Preference fragment
+ restartPreferenceFragment();
+ return view;
+ }
+
+ /**
+ * Start or restart the preference fragment to take into account the new settings.
+ */
+ private void restartPreferenceFragment() {
+ if(generalPreferenceFragment != null)
+ getChildFragmentManager().beginTransaction().remove(generalPreferenceFragment).commit();
+ generalPreferenceFragment = new GeneralPreferenceFragment();
+ getChildFragmentManager().beginTransaction().replace(R.id.settingsContent, generalPreferenceFragment).commit();
+ }
+
+ /**
+ * Common method to handle the result of the dialog.
+ */
+ private void dialogResult() {
+ if (onSettingsKeyChangedListener != null)
+ onSettingsKeyChangedListener.onSettingsKeyChanged(settingsKeyChanged);
+ }
+
+ @Override
+ public void onDestroy() {
+ settings.unregisterOnOneKeyChangeListener();
+ super.onDestroy();
+ }
+
+ void registerOnSettingsKeyChangedListener(OnSettingsKeyChangedListener listener) {
+ if(debug) Log.d(TAG, "registerOnSettingsKeyChangedListener()");
+ onSettingsKeyChangedListener = listener;
+ }
+
+ void unregisterOnSettingsKeyChangedListener() {
+ if(debug) Log.d(TAG, "unregisterOnSettingsKeyChangedListener()");
+ onSettingsKeyChangedListener = null;
+ }
+
+ public static class GeneralPreferenceFragment extends PreferenceFragmentCompat {
+
+ Preference preferencePort2load = null;
+
+ @Override
+ public void onCreatePreferences(Bundle savedInstanceState, String rootKey) {
+
+ // Register our own settings data store
+ getPreferenceManager().setPreferenceDataStore(EmuApplication.getSettings());
+
+ // Load the preferences from an XML resource
+ setPreferencesFromResource(R.xml.pref_general, rootKey);
+
+
+ // Sound settings
+
+ SeekBarPreference preferenceSoundVolume = findPreference("settings_sound_volume");
+ if(preferenceSoundVolume != null) {
+ if(!NativeLib.getSoundEnabled()) {
+ preferenceSoundVolume.setSummary("Cannot initialize the sound engine.");
+ preferenceSoundVolume.setEnabled(false);
+ } else {
+ preferenceSoundVolume.setOnPreferenceClickListener(preference -> {
+ AlertDialog.Builder alert = new AlertDialog.Builder(requireContext());
+ alert.setTitle(R.string.settings_sound_volume_dialog_title);
+ final EditText input = new EditText(getContext());
+ input.setInputType(InputType.TYPE_CLASS_NUMBER);
+ input.setRawInputType(Configuration.KEYBOARD_12KEY);
+ input.setFocusable(true);
+ input.setText(String.format(Locale.US,"%d", preferenceSoundVolume.getValue()));
+ alert.setView(input);
+ alert.setPositiveButton(R.string.message_ok, (dialog, whichButton) -> {
+ String newValueText = input.getText().toString();
+ try {
+ int newValue = Integer.parseInt(newValueText);
+ if(newValue >= preferenceSoundVolume.getMin() && newValue <= preferenceSoundVolume.getMax())
+ preferenceSoundVolume.setValue(newValue);
+ } catch (NumberFormatException ignored) {}
+ });
+ alert.setNegativeButton(R.string.message_cancel, (dialog, whichButton) -> {});
+ alert.show();
+ return true;
+ });
+ }
+ }
+
+ // Background color settings
+
+ Preference preferenceBackgroundFallbackColor = findPreference("settings_background_fallback_color");
+// final ColorPickerPreferenceCompat preferenceBackgroundCustomColor = (ColorPickerPreferenceCompat)findPreference("settings_background_custom_color");
+ if(preferenceBackgroundFallbackColor != null /*&& preferenceBackgroundCustomColor != null*/) {
+ final String[] stringArrayBackgroundFallbackColor = getResources().getStringArray(R.array.settings_background_fallback_color_item);
+ Preference.OnPreferenceChangeListener onPreferenceChangeListenerBackgroundFallbackColor = (preference, value) -> {
+ if(value != null) {
+ String stringValue = value.toString();
+ int backgroundFallbackColor = -1;
+ try {
+ backgroundFallbackColor = Integer.parseInt(stringValue);
+ } catch (NumberFormatException ignored) {}
+ if(backgroundFallbackColor >= 0 && backgroundFallbackColor < stringArrayBackgroundFallbackColor.length)
+ preference.setSummary(stringArrayBackgroundFallbackColor[backgroundFallbackColor]);
+// preferenceBackgroundCustomColor.setEnabled(backgroundFallbackColor == 2);
+ }
+ return true;
+ };
+ preferenceBackgroundFallbackColor.setOnPreferenceChangeListener(onPreferenceChangeListenerBackgroundFallbackColor);
+ onPreferenceChangeListenerBackgroundFallbackColor.onPreferenceChange(preferenceBackgroundFallbackColor,
+ settings.getString(preferenceBackgroundFallbackColor.getKey(), "0"));
+
+
+ //preferenceBackgroundCustomColor.setColorValue(customColor);
+
+// Preference.OnPreferenceChangeListener onPreferenceChangeListenerBackgroundCustomColor = new Preference.OnPreferenceChangeListener() {
+// @Override
+// public boolean onPreferenceChange(Preference preference, Object value) {
+// if(value != null) {
+// int customColor = (Integer)value;
+// }
+// return true;
+// }
+// };
+// preferenceBackgroundCustomColor.setOnPreferenceChangeListener(onPreferenceChangeListenerBackgroundCustomColor);
+// onPreferenceChangeListenerBackgroundCustomColor.onPreferenceChange(preferenceBackgroundCustomColor, sharedPreferences.getBoolean(preferenceBackgroundCustomColor.getKey(), false));
+ }
+
+ // Macro
+
+ Preference preferenceMacroRealSpeed = findPreference("settings_macro_real_speed");
+ Preference preferenceMacroManualSpeed = findPreference("settings_macro_manual_speed");
+ if(preferenceMacroRealSpeed != null && preferenceMacroManualSpeed != null) {
+ Preference.OnPreferenceChangeListener onPreferenceChangeListenerMacroRealSpeed = (preference, value) -> {
+ if(value != null)
+ preferenceMacroManualSpeed.setEnabled(!(Boolean) value);
+ return true;
+ };
+ preferenceMacroRealSpeed.setOnPreferenceChangeListener(onPreferenceChangeListenerMacroRealSpeed);
+ onPreferenceChangeListenerMacroRealSpeed.onPreferenceChange(preferenceMacroRealSpeed, settings.getBoolean(preferenceMacroRealSpeed.getKey(), true));
+ }
+
+ // Ports 1 & 2 settings
+
+ Preference preferencePort1en = findPreference("settings_port1en");
+ Preference preferencePort1wr = findPreference("settings_port1wr");
+ Preference preferencePort2en = findPreference("settings_port2en");
+ Preference preferencePort2wr = findPreference("settings_port2wr");
+ preferencePort2load = findPreference("settings_port2load");
+ if(preferencePort1en != null && preferencePort1wr != null
+ && preferencePort2en != null && preferencePort2wr != null
+ && preferencePort2load != null) {
+ boolean enablePortPreferences = NativeLib.isPortExtensionPossible();
+
+ Preference.OnPreferenceChangeListener onPreferenceChangeListenerPort1en = (preference, value) -> {
+ preferencePort1en.setEnabled(enablePortPreferences);
+ preferencePort1wr.setEnabled(enablePortPreferences);
+ return true;
+ };
+ preferencePort1en.setOnPreferenceChangeListener(onPreferenceChangeListenerPort1en);
+ onPreferenceChangeListenerPort1en.onPreferenceChange(preferencePort1en, settings.getBoolean(preferencePort1en.getKey(), false));
+
+ Preference.OnPreferenceChangeListener onPreferenceChangeListenerPort2en = (preference, value) -> {
+ preferencePort2en.setEnabled(enablePortPreferences);
+ preferencePort2wr.setEnabled(enablePortPreferences);
+ preferencePort2load.setEnabled(enablePortPreferences);
+ return true;
+ };
+ preferencePort2en.setOnPreferenceChangeListener(onPreferenceChangeListenerPort2en);
+ onPreferenceChangeListenerPort2en.onPreferenceChange(preferencePort2en, settings.getBoolean(preferencePort2en.getKey(), false));
+
+ updatePort2LoadFilename(settings.getString(preferencePort2load.getKey(), ""));
+ preferencePort2load.setOnPreferenceClickListener(preference -> {
+ Intent intent = new Intent(Intent.ACTION_OPEN_DOCUMENT);
+ intent.addCategory(Intent.CATEGORY_OPENABLE);
+ intent.setType("*/*");
+ intent.putExtra(Intent.EXTRA_TITLE, "shared.bin");
+ Fragment parentFragment = getParentFragment();
+ if (parentFragment != null)
+ parentFragment.startActivityForResult(intent, MainActivity.INTENT_PORT2LOAD);
+ return true;
+ });
+ }
+ }
+
+ void updatePort2LoadFilename(String port2Filename) {
+ if(preferencePort2load != null) {
+ String displayName = port2Filename;
+ try {
+ displayName = Utils.getFileName(getActivity(), port2Filename);
+ } catch (Exception e) {
+ // Do nothing
+ }
+ preferencePort2load.setSummary(displayName);
+ }
+ }
+ }
+
+ @Override
+ public void onActivityResult(int requestCode, int resultCode, @Nullable Intent data) {
+ if(resultCode == Activity.RESULT_OK && data != null) {
+ if(requestCode == MainActivity.INTENT_PORT2LOAD) {
+ Uri uri = data.getData();
+ String url;
+ if (uri != null) {
+ if(debug) Log.d(TAG, "onActivityResult INTENT_PORT2LOAD " + uri.toString());
+ url = uri.toString();
+ settings.putString("settings_port2load", url);
+ Utils.makeUriPersistable(requireContext(), data, uri);
+ if(generalPreferenceFragment != null)
+ generalPreferenceFragment.updatePort2LoadFilename(url);
+ }
+ }
+ }
+ super.onActivityResult(requestCode, resultCode, data);
+ }
+}
diff --git a/app/src/main/res/layout/activity_info.xml b/app/src/main/res/layout/activity_info.xml
deleted file mode 100644
index 29b0d3f..0000000
--- a/app/src/main/res/layout/activity_info.xml
+++ /dev/null
@@ -1,13 +0,0 @@
-
-
-
-
-
diff --git a/app/src/main/res/layout/activity_web_info.xml b/app/src/main/res/layout/activity_web_info.xml
deleted file mode 100644
index ab7bc58..0000000
--- a/app/src/main/res/layout/activity_web_info.xml
+++ /dev/null
@@ -1,17 +0,0 @@
-
-
-
-
-
-
diff --git a/app/src/main/res/layout/app_bar_main.xml b/app/src/main/res/layout/app_bar_main.xml
index 8898e60..59ab34e 100644
--- a/app/src/main/res/layout/app_bar_main.xml
+++ b/app/src/main/res/layout/app_bar_main.xml
@@ -5,17 +5,6 @@
android:layout_width="match_parent"
android:layout_height="match_parent">
-
-
-
-
-
\ No newline at end of file
diff --git a/app/src/main/res/layout/fragment_info.xml b/app/src/main/res/layout/fragment_info.xml
new file mode 100644
index 0000000..6dee618
--- /dev/null
+++ b/app/src/main/res/layout/fragment_info.xml
@@ -0,0 +1,32 @@
+
+
+
+
+
+
+
+
+
+
+
+
\ No newline at end of file
diff --git a/app/src/main/res/layout/fragment_settings.xml b/app/src/main/res/layout/fragment_settings.xml
new file mode 100644
index 0000000..856a2df
--- /dev/null
+++ b/app/src/main/res/layout/fragment_settings.xml
@@ -0,0 +1,25 @@
+
+
+
+
+
+
+
+
\ No newline at end of file
diff --git a/app/src/main/res/layout/fragment_web_info.xml b/app/src/main/res/layout/fragment_web_info.xml
new file mode 100644
index 0000000..0154459
--- /dev/null
+++ b/app/src/main/res/layout/fragment_web_info.xml
@@ -0,0 +1,24 @@
+
+
+
+
+
+
+
+
diff --git a/app/src/main/res/menu/fragment_settings.xml b/app/src/main/res/menu/fragment_settings.xml
new file mode 100644
index 0000000..4ed1c09
--- /dev/null
+++ b/app/src/main/res/menu/fragment_settings.xml
@@ -0,0 +1,10 @@
+
+
\ No newline at end of file
diff --git a/app/src/main/res/values/strings.xml b/app/src/main/res/values/strings.xml
index 4d27a0a..d9f235c 100644
--- a/app/src/main/res/values/strings.xml
+++ b/app/src/main/res/values/strings.xml
@@ -1,17 +1,21 @@
-
+
- About
+ About
ReadMe.txt
-
- Help
+
+ Help
file:///android_asset/Emu48.htm
-
+
- Settings
+ Common Settings
+ Settings (Saved in state file)
+
+ Reset to Default
+ Reset to Common
@@ -129,7 +133,7 @@
Manual (Zoom or pan)
Show the LCD pixel borders
- Experimental feature which show a more realistic pixel. Note: Due to the difference in screen resolution between Android and the calculator, the pixels are not necessarily uniform in size.
+ Experimental feature which shows a more realistic pixel. Note: Due to the difference in screen resolution between Android and the calculator, the pixels are not necessarily uniform in size.
Hide the status bar
Hide the navigation bar
@@ -162,8 +166,6 @@
HP82240A
HP82240B (default)
Generic Serial
- Prevent Line Wrapping
- Prevent the calc to wrap the line in the textual printer simulator
Macro
Use Real Replay Speed
diff --git a/app/src/main/res/xml/pref_general.xml b/app/src/main/res/xml/pref_general.xml
index 4b0ce96..b024f74 100644
--- a/app/src/main/res/xml/pref_general.xml
+++ b/app/src/main/res/xml/pref_general.xml
@@ -121,12 +121,6 @@
android:entryValues="@array/settings_printer_model_value"
android:defaultValue="1"
/>
-
-
-
-
-
-
diff --git a/build.gradle b/build.gradle
index 2472675..235a161 100644
--- a/build.gradle
+++ b/build.gradle
@@ -7,7 +7,7 @@ buildscript {
jcenter()
}
dependencies {
- classpath 'com.android.tools.build:gradle:3.6.2'
+ classpath 'com.android.tools.build:gradle:3.6.3'
// NOTE: Do not place your application dependencies here; they belong