From 9b995adc516b1a97c77df00031440253345b27de Mon Sep 17 00:00:00 2001 From: dgis Date: Fri, 30 Oct 2020 00:14:00 +0100 Subject: [PATCH] Replaces the haptic feedback switch with a slider to adjust the vibration duration. --- ReadMe.txt | 5 ++- app/build.gradle | 4 +- app/src/main/AndroidManifest.xml | 3 +- app/src/main/assets/ReadMe.txt | 5 ++- app/src/main/cpp/win32-layer.c | 5 ++- .../org/emulator/calculator/Settings.java | 25 ++++++++++++- .../java/org/emulator/calculator/Utils.java | 13 +++++++ .../emulator/forty/eight/MainActivity.java | 34 ++++++++++++----- .../forty/eight/SettingsFragment.java | 37 +++++++++++++++++++ app/src/main/res/values/strings.xml | 4 +- app/src/main/res/xml/pref_general.xml | 12 ++++-- 11 files changed, 123 insertions(+), 24 deletions(-) diff --git a/ReadMe.txt b/ReadMe.txt index 2184d3d..66ce874 100644 --- a/ReadMe.txt +++ b/ReadMe.txt @@ -63,11 +63,12 @@ LINKS CHANGES -Version 1.91 (2020-10-XX) +Version 2.0 (2020-11-XX) +- For the HP49/50 port 2, it is now possible to load a new Flash ROM file (It fully replaces the ROM). +- Replaces the haptic feedback switch with a slider to adjust the vibration duration. - Fix transparency issue (RGB -> BGR). - Fix a printer issue from Christoph Gießelink's HP82240B Printer Simulator version 1.12. -- For the HP49/50 port 2, it is now possible to load a new Flash ROM file (It fully replaces the ROM). Version 1.9 (2020-09-07) diff --git a/app/build.gradle b/app/build.gradle index 6ea5eb3..604f594 100644 --- a/app/build.gradle +++ b/app/build.gradle @@ -33,8 +33,8 @@ android { applicationId "org.emulator.forty.eight" minSdkVersion 19 targetSdkVersion 29 - versionCode 16 - versionName "1.9" + versionCode 17 + versionName "2.0" setProperty("archivesBaseName", "Emu48-v$versionName") testInstrumentationRunner "androidx.test.runner.AndroidJUnitRunner" externalNativeBuild { diff --git a/app/src/main/AndroidManifest.xml b/app/src/main/AndroidManifest.xml index f63b144..3dd6aa0 100644 --- a/app/src/main/AndroidManifest.xml +++ b/app/src/main/AndroidManifest.xml @@ -2,7 +2,8 @@ - + BGR). - Fix a printer issue from Christoph Gießelink's HP82240B Printer Simulator version 1.12. -- For the HP49/50 port 2, it is now possible to load a new Flash ROM file (It fully replaces the ROM). Version 1.9 (2020-09-07) diff --git a/app/src/main/cpp/win32-layer.c b/app/src/main/cpp/win32-layer.c index a95031d..ae2e6d0 100644 --- a/app/src/main/cpp/win32-layer.c +++ b/app/src/main/cpp/win32-layer.c @@ -1858,7 +1858,10 @@ BOOL PatBlt(HDC hdcDest, int x, int y, int w, int h, DWORD rop) { destinationStride = (float)(4 * ((destinationWidth * hBitmapDestination->bitmapInfoHeader->biBitCount + 31) / 32)); } - HPALETTE palette = hdcDest->realizedPalette; + x -= hdcDest->windowOriginX; + y -= hdcDest->windowOriginY; // TODO DSTINVERT in screen does not work!!! + + HPALETTE palette = hdcDest->realizedPalette; if(!palette) palette = hdcDest->selectedPalette; PALETTEENTRY * palPalEntry = palette && palette->paletteLog && palette->paletteLog->palPalEntry ? diff --git a/app/src/main/java/org/emulator/calculator/Settings.java b/app/src/main/java/org/emulator/calculator/Settings.java index 1249bb4..21716bc 100644 --- a/app/src/main/java/org/emulator/calculator/Settings.java +++ b/app/src/main/java/org/emulator/calculator/Settings.java @@ -90,7 +90,7 @@ public class Settings extends PreferenceDataStore { } private void putValue(String key, @Nullable Object value) { - if(applicationSettingKeys.indexOf(key) != -1) + if(applicationSettingKeys.contains(key)) applicationSettings.put(key, value); else if(isCommonSettings) commonSettings.put(key, value); @@ -105,7 +105,7 @@ public class Settings extends PreferenceDataStore { if(!isCommonSettings) value = embeddedStateSettings.get(key); if(value == null) { - if(applicationSettingKeys.indexOf(key) != -1) + if(applicationSettingKeys.contains(key)) value = applicationSettings.get(key); else value = commonSettings.get(key); @@ -113,6 +113,27 @@ public class Settings extends PreferenceDataStore { return value; } + public void removeValue(String key) { + if(applicationSettingKeys.contains(key)) + applicationSettings.remove(key); + else if(isCommonSettings) + commonSettings.remove(key); + else + embeddedStateSettings.remove(key); + if(oneKeyChangedListener != null) + oneKeyChangedListener.onOneKeyChanged(key); + } + + public boolean hasValue(String key) { + if(debug) Log.d(TAG, "has(key: '" + key + "')"); + if(applicationSettingKeys.contains(key)) + return applicationSettings.containsKey(key); + else if(isCommonSettings) + return commonSettings.containsKey(key); + else + return embeddedStateSettings.containsKey(key); + } + public boolean getIsDefaultSettings() { return isCommonSettings; } diff --git a/app/src/main/java/org/emulator/calculator/Utils.java b/app/src/main/java/org/emulator/calculator/Utils.java index 2f7e860..193158e 100644 --- a/app/src/main/java/org/emulator/calculator/Utils.java +++ b/app/src/main/java/org/emulator/calculator/Utils.java @@ -24,6 +24,8 @@ import android.graphics.PorterDuff; import android.graphics.drawable.Drawable; import android.net.Uri; import android.os.Build; +import android.os.VibrationEffect; +import android.os.Vibrator; import android.provider.OpenableColumns; import android.util.Log; import android.util.TypedValue; @@ -200,4 +202,15 @@ public class Utils { listView.setLayoutParams(params); listView.requestLayout(); } + + public static void vibrate(Vibrator vibrator, int durationInMilliSecond) { + if(vibrator != null && durationInMilliSecond > 0) { + if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.O) + // https://developer.android.com/reference/android/os/Vibrator#vibrate(android.os.VibrationEffect,%20android.media.AudioAttributes) + vibrator.vibrate(VibrationEffect.createOneShot(durationInMilliSecond, VibrationEffect.DEFAULT_AMPLITUDE)); + else + //deprecated in API 26 + vibrator.vibrate(durationInMilliSecond); + } + } } 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 0bbfa57..09340d3 100644 --- a/app/src/main/java/org/emulator/forty/eight/MainActivity.java +++ b/app/src/main/java/org/emulator/forty/eight/MainActivity.java @@ -29,9 +29,9 @@ import android.net.Uri; import android.os.Build; import android.os.Bundle; import android.os.ParcelFileDescriptor; +import android.os.Vibrator; import android.util.Log; import android.util.SparseArray; -import android.view.HapticFeedbackConstants; import android.view.LayoutInflater; import android.view.Menu; import android.view.MenuItem; @@ -39,7 +39,6 @@ import android.view.SubMenu; import android.view.View; import android.view.ViewGroup; import android.widget.Button; -import android.widget.CheckBox; import android.widget.FrameLayout; import android.widget.ImageButton; import android.widget.ImageView; @@ -104,8 +103,10 @@ public class MainActivity extends AppCompatActivity implements NavigationView.On private MainScreenView mainScreenView; private LCDOverlappingView lcdOverlappingView; private ImageButton imageButtonMenu; + private Vibrator vibrator; - public static final int INTENT_GETOPENFILENAME = 1; + + public static final int INTENT_GETOPENFILENAME = 1; public static final int INTENT_GETSAVEFILENAME = 2; public static final int INTENT_OBJECT_LOAD = 3; public static final int INTENT_OBJECT_SAVE = 4; @@ -163,6 +164,7 @@ public class MainActivity extends AppCompatActivity implements NavigationView.On settings = EmuApplication.getSettings(); settings.setIsDefaultSettings(true); + vibrator = (Vibrator) getSystemService(Context.VIBRATOR_SERVICE); ViewGroup mainScreenContainer = findViewById(R.id.main_screen_container); mainScreenView = new MainScreenView(this); @@ -1481,6 +1483,13 @@ public class MainActivity extends AppCompatActivity implements NavigationView.On } } + private void migrateDeprecatedSettings() { + if(settings.hasValue("settings_haptic_feedback")) { + settings.removeValue("settings_haptic_feedback"); + settings.putInt("settings_haptic_feedback_duration", 25); + } + } + private void onFileOpen(String url, Intent intent, String openWithKMLScriptFolder) { // Eventually, close the previous state file @@ -1494,6 +1503,8 @@ public class MainActivity extends AppCompatActivity implements NavigationView.On settings.clearEmbeddedStateSettings(); settings.loadFromStateFile(this, url); + migrateDeprecatedSettings(); + if(intent != null) // Make this file persistable to allow a next access to this same file. Utils.makeUriPersistable(this, intent, Uri.parse(url)); @@ -1986,11 +1997,15 @@ public class MainActivity extends AppCompatActivity implements NavigationView.On @SuppressWarnings("UnusedDeclaration") public void performHapticFeedback() { - if(settings.getBoolean("settings_haptic_feedback", true)) - mainScreenView.performHapticFeedback(HapticFeedbackConstants.VIRTUAL_KEY, HapticFeedbackConstants.FLAG_IGNORE_GLOBAL_SETTING); +// if(settings.getBoolean("settings_haptic_feedback", true)) +// //mainScreenView.performHapticFeedback(HapticFeedbackConstants.CONTEXT_CLICK, HapticFeedbackConstants.FLAG_IGNORE_GLOBAL_SETTING); +// mainScreenView.performHapticFeedback(HapticFeedbackConstants.VIRTUAL_KEY, HapticFeedbackConstants.FLAG_IGNORE_GLOBAL_SETTING); +// //mainScreenView.performHapticFeedback(HapticFeedbackConstants.LONG_PRESS, HapticFeedbackConstants.FLAG_IGNORE_GLOBAL_SETTING); + + Utils.vibrate(vibrator, settings.getInt("settings_haptic_feedback_duration", 25)); } - @SuppressWarnings("UnusedDeclaration") + @SuppressWarnings("UnusedDeclaration") public void sendByteUdp(int byteSent) { printerSimulator.write(byteSent); } @@ -2109,9 +2124,10 @@ public class MainActivity extends AppCompatActivity implements NavigationView.On NativeLib.setConfiguration("settings_sound_volume", isDynamicValue, volumeOption, 0, null); break; } - case "settings_haptic_feedback": - // Nothing to do - break; + case "settings_haptic_feedback": + case "settings_haptic_feedback_duration": + // Nothing to do + break; case "settings_background_kml_color": mainScreenView.setBackgroundKmlColor(settings.getBoolean("settings_background_kml_color", false)); diff --git a/app/src/main/java/org/emulator/forty/eight/SettingsFragment.java b/app/src/main/java/org/emulator/forty/eight/SettingsFragment.java index dc4e24f..5edf2cd 100644 --- a/app/src/main/java/org/emulator/forty/eight/SettingsFragment.java +++ b/app/src/main/java/org/emulator/forty/eight/SettingsFragment.java @@ -16,6 +16,7 @@ package org.emulator.forty.eight; import android.app.Activity; import android.app.Dialog; +import android.content.Context; import android.content.Intent; import android.content.res.Configuration; import android.graphics.BlendMode; @@ -25,6 +26,7 @@ import android.graphics.drawable.Drawable; import android.net.Uri; import android.os.Build; import android.os.Bundle; +import android.os.Vibrator; import android.text.InputType; import android.util.Log; import android.view.LayoutInflater; @@ -213,6 +215,41 @@ public class SettingsFragment extends AppCompatDialogFragment { } } + // Haptic feedback settings + + Vibrator vibrator = (Vibrator) requireContext().getSystemService(Context.VIBRATOR_SERVICE); + SeekBarPreference preferenceHapticFeedbackDuration = findPreference("settings_haptic_feedback_duration"); + if(preferenceHapticFeedbackDuration != null) { + preferenceHapticFeedbackDuration.setOnPreferenceChangeListener((preference, newValue) -> { + if(newValue instanceof Integer) + Utils.vibrate(vibrator, (int)newValue); + return true; + }); + preferenceHapticFeedbackDuration.setOnPreferenceClickListener(preference -> { + AlertDialog.Builder alert = new AlertDialog.Builder(requireContext()); + alert.setTitle(R.string.settings_haptic_feedback_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", preferenceHapticFeedbackDuration.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 >= preferenceHapticFeedbackDuration.getMin() && newValue <= preferenceHapticFeedbackDuration.getMax()) { + preferenceHapticFeedbackDuration.setValue(newValue); + Utils.vibrate(vibrator, 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"); diff --git a/app/src/main/res/values/strings.xml b/app/src/main/res/values/strings.xml index c3d5384..30495f3 100644 --- a/app/src/main/res/values/strings.xml +++ b/app/src/main/res/values/strings.xml @@ -160,7 +160,9 @@ Hide the button menu Sound Volume Sound Volume (0-255) - Allow haptic feedback + Haptic feedback + Duration of vibration when a key is touched. Between 1ms and 50ms. 0ms for no vibration. + Duration of Vibration (0-50ms) Background Color Use KML color diff --git a/app/src/main/res/xml/pref_general.xml b/app/src/main/res/xml/pref_general.xml index 0ea14f6..436ff75 100644 --- a/app/src/main/res/xml/pref_general.xml +++ b/app/src/main/res/xml/pref_general.xml @@ -82,10 +82,14 @@ android:min="0" android:max="255" app:showSeekBarValue="true" /> - +