Working preferences, keymap choosing.

This commit is contained in:
2024-10-20 23:40:46 +02:00
parent bf695b19e0
commit 5d66997f77
14 changed files with 276 additions and 126 deletions
+1 -1
View File
@@ -26,7 +26,7 @@
</service>
<activity
android:name=".PreferencesActivity"
android:name=".SettingsActivity"
android:exported="true"
android:label="@string/preferences_label">
<intent-filter>
@@ -22,6 +22,7 @@ package cfpi_fpsi.eu.titanboard;
import android.annotation.SuppressLint;
import android.inputmethodservice.InputMethodService;
import android.os.Vibrator;
import android.util.Log;
import android.view.KeyEvent;
import android.view.View;
import android.view.inputmethod.EditorInfo;
@@ -29,32 +30,33 @@ import android.view.inputmethod.ExtractedText;
import android.view.inputmethod.ExtractedTextRequest;
import android.view.inputmethod.InputConnection;
import java.util.ArrayDeque;
import java.util.ArrayList;
import java.util.Collections;
import java.util.Deque;
import java.util.Set;
// TODO: Implement auto-correct.
// TODO: Implement auto-caps.
// TODO: Implement device recognition and a keymap picking based on it.
/**
* @noinspection deprecation
*/
public class InputMethod extends InputMethodService {
private final Deque<String> mLanguageQueue = new ArrayDeque<>();
public MetaKeyManager mMetaKeyManager;
public KeymapManager mKeymapManager;
public String mCurrentLanguage;
private int mKeyCounter = 0;
private boolean mRegularKeyPressed = false;
private InputView mInputView;
private Settings mSettings;
@Override
public void onCreate() {
super.onCreate();
mSettings = new Settings(this);
Vibrator mVibrator = (Vibrator) getBaseContext().getSystemService(VIBRATOR_SERVICE);
mMetaKeyManager = new MetaKeyManager(mVibrator);
mKeymapManager = new KeymapManager(getResources().getXml(R.xml.keymaps_titan));
Collections.addAll(mLanguageQueue, mKeymapManager.getAvailableKeymaps());
cycleLanguages();
cycleKeymaps();
}
@SuppressLint("InflateParams")
@@ -128,9 +130,24 @@ public class InputMethod extends InputMethodService {
}
}
public void cycleLanguages() {
mCurrentLanguage = mLanguageQueue.pop();
mLanguageQueue.addLast(mCurrentLanguage);
public void cycleKeymaps() {
// We get the selected keymaps from the settings, find the index of the current language
// there, and then select the next keymap.
ArrayList<String> selectedLanguages = mSettings.getSelectedKeymaps();
if (selectedLanguages.isEmpty() || mCurrentLanguage == null) {
mCurrentLanguage = "eu";
return;
}
int index = selectedLanguages.indexOf(mCurrentLanguage);
if (index == selectedLanguages.size() - 1) {
index = 0;
} else {
++index;
}
mCurrentLanguage = selectedLanguages.get(index);
}
public boolean onKeyUp(int keyCode, KeyEvent event) {
@@ -162,6 +179,9 @@ public class InputMethod extends InputMethodService {
@Override
public void onStartInput(EditorInfo info, boolean restarting) {
super.onStartInput(info, restarting);
if (!mSettings.getSelectedKeymaps().contains(mCurrentLanguage)) {
cycleKeymaps();
}
mInputView.updateStateText();
}
@@ -20,6 +20,8 @@
package cfpi_fpsi.eu.titanboard;
import android.content.Context;
import android.content.Intent;
import android.graphics.Paint;
import android.util.AttributeSet;
import android.widget.Button;
import android.widget.LinearLayout;
@@ -43,10 +45,23 @@ public class InputView extends RelativeLayout {
super.onFinishInflate();
mMultiList = findViewById(R.id.multi_list);
mStateButton = findViewById(R.id.input_state);
mStateButton.setOnClickListener(button -> {
mInputMethod.cycleLanguages();
MetaKeyManager metaManager = mInputMethod.mMetaKeyManager;
if (metaManager.getAlt().isActive()) {
metaManager.getAlt().resetState();
} else {
mInputMethod.cycleKeymaps();
}
updateStateText();
});
mStateButton.setOnLongClickListener(button -> {
Intent intent = new Intent(getContext(), SettingsActivity.class);
intent.setFlags(Intent.FLAG_ACTIVITY_NEW_TASK);
getContext().startActivity(intent);
return true;
});
}
public void updateStateText() {
@@ -54,21 +69,35 @@ public class InputView extends RelativeLayout {
KeymapManager keymapManager = mInputMethod.mKeymapManager;
String currentLanguage = mInputMethod.mCurrentLanguage;
if (metaManager.getAlt().isPressed() || metaManager.getAlt().isLocked()) {
mStateButton.setText("#!");
mStateButton.setPaintFlags(mStateButton.getPaintFlags() & ~(Paint.UNDERLINE_TEXT_FLAG));
if (metaManager.getAlt().isPressed()) {
mStateButton.setText(R.string.inputview_symbols_locked_state);
return;
}
if (metaManager.getAlt().isLocked()) {
mStateButton.setText(R.string.inputview_symbols_locked_state);
mStateButton.setPaintFlags(mStateButton.getPaintFlags() | Paint.UNDERLINE_TEXT_FLAG);
return;
}
if (metaManager.getAlt().isLatched()) {
mStateButton.setText("#?");
mStateButton.setText(R.string.inputview_symbols_latched_state);
return;
}
if (metaManager.getShift().isPressed() || metaManager.getShift().isLocked()) {
if (metaManager.getShift().isPressed()) {
mStateButton.setText(keymapManager.getKeymap(currentLanguage).getLockedCode());
return;
}
if (metaManager.getShift().isLocked()) {
mStateButton.setText(keymapManager.getKeymap(currentLanguage).getLockedCode());
mStateButton.setPaintFlags(mStateButton.getPaintFlags() | Paint.UNDERLINE_TEXT_FLAG);
return;
}
if (metaManager.getShift().isLatched()) {
mStateButton.setText(keymapManager.getKeymap(currentLanguage).getLatchedCode());
return;
@@ -32,7 +32,7 @@ public class KeymapManager {
public KeymapManager(XmlPullParser parser) {
Keymap keymap = null;
int code = 0;
String label = null, name = null, latchedName = null, lockedName = null;
String name = null, latchedName = null, lockedName = null;
Key key = null;
try {
@@ -44,9 +44,6 @@ public class KeymapManager {
keymap = new Keymap();
for (int i = 0; i < parser.getAttributeCount(); ++i) {
switch (parser.getAttributeName(i)) {
case "label":
label = parser.getAttributeValue(i);
break;
case "name":
name = parser.getAttributeValue(i);
break;
@@ -60,8 +57,8 @@ public class KeymapManager {
}
} else if (type == XmlPullParser.END_TAG && parser.getName().equals("keymap")
&& keymap != null) {
keymap.setStrings(label, name, latchedName, lockedName);
mKeymaps.put(label, keymap);
keymap.setStrings(name, latchedName, lockedName);
mKeymaps.put(name, keymap);
}
// We got a new key.
@@ -109,10 +106,6 @@ public class KeymapManager {
}
}
public String[] getAvailableKeymaps() {
return mKeymaps.keySet().toArray(new String[0]);
}
public Keymap getKeymap(String lang) {
return mKeymaps.get(lang);
}
@@ -139,7 +132,6 @@ public class KeymapManager {
}
public static class Keymap extends HashMap<Integer, Key> {
private String mLabel; // The full name of the keymap.
private String mCode; // A two-letter code for when the keyboard is lowercase.
private String mLatchedCode; // Above, but when the keyboard is shift latched.
private String mLockedCode; // Above, but when the shift is locked/pressed.
@@ -156,12 +148,7 @@ public class KeymapManager {
return mLockedCode;
}
public String getLabel() {
return mLabel;
}
public void setStrings(String label, String code, String latched, String locked) {
mLabel = label;
public void setStrings(String code, String latched, String locked) {
mCode = code;
mLatchedCode = latched;
mLockedCode = locked;
@@ -0,0 +1,69 @@
/*
* An input method for the Unihertz Titan/physical keyboard phones
* Copyright (C) 2024 Emil Kosz
*
* 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 3 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, see <https://www.gnu.org/licenses/>.
*
*/
package cfpi_fpsi.eu.titanboard;
import android.content.Context;
import android.content.SharedPreferences;
import android.preference.PreferenceManager;
import java.util.ArrayList;
import java.util.HashMap;
import java.util.Map;
import java.util.Set;
public class Settings implements SharedPreferences.OnSharedPreferenceChangeListener {
private final SharedPreferences mPreferences;
private final Map<String, Object> mPreferenceValues;
public Settings(Context context) {
mPreferences = PreferenceManager.getDefaultSharedPreferences(context);
mPreferences.registerOnSharedPreferenceChangeListener(this);
mPreferenceValues = (Map<String, Object>) mPreferences.getAll();
}
@Override
public void onSharedPreferenceChanged(SharedPreferences sharedPreferences, String key) {
Object value = sharedPreferences.getAll().get(key);
if (value != null) {
mPreferenceValues.put(key, value);
}
}
public boolean isAutoCapsEnabled() {
return (boolean) mPreferenceValues.get("auto_caps");
}
public boolean isAutoPeriodsEnabled() {
return (boolean) mPreferenceValues.get("auto_periods");
}
public boolean isAutocorrectEnabled() {
return (boolean) mPreferenceValues.get("auto_correct");
}
public int getLongClickSpeed() {
return Integer.parseInt((String) mPreferenceValues.get("long_click_speed"));
}
public ArrayList<String> getSelectedKeymaps() {
Set<String> selectedKeymaps = (Set<String>) mPreferenceValues.get("selected_keymaps");
return new ArrayList<>(selectedKeymaps);
}
}
@@ -19,20 +19,19 @@
package cfpi_fpsi.eu.titanboard;
import android.app.Activity;
import android.content.Context;
import android.content.SharedPreferences;
import android.os.Bundle;
import android.preference.PreferenceActivity;
public class PreferencesActivity extends Activity {
SharedPreferences mPreferences;
import java.util.Objects;
/**
* @noinspection deprecation
*/
public class SettingsActivity extends PreferenceActivity {
@Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.preferences);
mPreferences = getBaseContext().getSharedPreferences(getString(R.string.preferences_key),
Context.MODE_PRIVATE);
addPreferencesFromResource(R.xml.preferences);
Objects.requireNonNull(getActionBar()).setDisplayHomeAsUpEnabled(true);
}
}
-50
View File
@@ -1,50 +0,0 @@
<?xml version="1.0" encoding="utf-8"?>
<RelativeLayout xmlns:android="http://schemas.android.com/apk/res/android"
android:layout_width="match_parent"
android:layout_height="match_parent">
<TextView
android:id="@+id/header1"
style="@style/PreferencesHeader"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:text="@string/preferences_functions" />
<TextView
android:id="@+id/longClickLabel"
style="@style/PreferencesLabel"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:layout_below="@id/header1"
android:text="@string/preferences_long_click_speed" />
<SeekBar
android:id="@+id/longClickValue"
style="@style/PreferencesSlider"
android:layout_below="@id/longClickLabel" />
<Switch
android:id="@+id/switch1"
style="@style/PreferencesSwitch"
android:layout_below="@id/longClickValue"
android:text="@string/preferences_auto_caps" />
<Switch
android:id="@+id/switch2"
style="@style/PreferencesSwitch"
android:layout_below="@id/switch1"
android:text="@string/preferences_auto_period" />
<Switch
android:id="@+id/switch3"
style="@style/PreferencesSwitch"
android:layout_below="@id/switch2"
android:text="@string/preferences_auto_correct" />
<TextView
style="@style/PreferencesHeader"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:layout_below="@id/switch3"
android:text="@string/preferences_languages" />
</RelativeLayout>
+52
View File
@@ -0,0 +1,52 @@
<?xml version="1.0" encoding="utf-8"?><!--
~ An input method for the Unihertz Titan/physical keyboard phones
~ Copyright (C) 2024 Emil Kosz
~
~ 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 3 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, see <https://www.gnu.org/licenses/>.
~
-->
<resources>
<string-array name="available_keymap_labels">
<item>European</item>
<item>Phonetic Cyrillic</item>
</string-array>
<string-array name="available_keymaps">
<item>eu</item>
<item>цp</item>
</string-array>
<string-array name="available_keymap_defaults">
<item>eu</item>
</string-array>
<string-array name="long_click_speed_labels">
<item>200 ms</item>
<item>300 ms</item>
<item>400 ms</item>
<item>500 ms</item>
<item>750 ms</item>
<item>1000 ms</item>
</string-array>
<string-array name="long_click_speeds">
<item>200</item>
<item>300</item>
<item>400</item>
<item>500</item>
<item>750</item>
<item>1000</item>
</string-array>
</resources>
+24
View File
@@ -0,0 +1,24 @@
<?xml version="1.0" encoding="utf-8"?><!--
~ An input method for the Unihertz Titan/physical keyboard phones
~ Copyright (C) 2024 Emil Kosz
~
~ 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 3 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, see <https://www.gnu.org/licenses/>.
~
-->
<resources>
<bool name="auto_caps_default">true</bool>
<bool name="auto_periods_default">true</bool>
<bool name="autocorrect_default">true</bool>
</resources>
@@ -2,14 +2,16 @@
<string name="app_name">Titanboard</string>
<string name="ime_label">Titanboard</string>
<string name="inputview_default_state">\?\?</string>
<string name="preferences_label">Titanboard preferences</string>
<string name="preferences_functions">Functions</string>
<string name="preferences_languages">Languages</string>
<string name="preferences_long_click_speed">Long click speed</string>
<string name="preferences_auto_caps">Automatic capitalization</string>
<string name="preferences_auto_period">Automatic periods</string>
<string name="preferences_auto_periods">Automatic periods</string>
<string name="preferences_auto_correct">Autocorrect</string>
<string name="preferences_key">cfpi_fpsi.eu.titanboard.prefs</string>
<string name="preferences_keymaps">Keymaps</string>
<string name="inputview_default_state">\?\?</string>
<string name="inputview_symbols_latched_state">#?</string>
<string name="inputview_symbols_locked_state">#!</string>
<string name="long_click_speed_default">400</string>
</resources>
-26
View File
@@ -32,30 +32,4 @@
<item name="android:textColor">#DDD</item>
<item name="android:textStyle">bold</item>
</style>
<style name="PreferencesHeader">
<item name="android:textSize">18sp</item>
<item name="android:textStyle">bold</item>
<item name="android:textColor">#AD1457</item>
<item name="android:layout_margin">8dp</item>
</style>
<style name="PreferencesLabel">
<item name="android:textColor">#000</item>
<item name="android:textSize">16sp</item>
<item name="android:layout_margin">8dp</item>
</style>
<style name="PreferencesSwitch">
<item name="android:textSize">16sp</item>
<item name="android:layout_margin">8dp</item>
<item name="android:layout_width">match_parent</item>
<item name="android:layout_height">48dp</item>
</style>
<style name="PreferencesSlider">
<item name="android:layout_margin">8dp</item>
<item name="android:layout_width">match_parent</item>
<item name="android:layout_height">48dp</item>
</style>
</resources>
-2
View File
@@ -23,7 +23,6 @@
Turkish, Hungarian, Swedish, Czech, Portuguese, Catalan, Serbian, Albanian. -->
<keymap
name="eu"
label="European"
latched-name="Eu"
locked-name="EU">
<!-- Checked. -->
@@ -329,7 +328,6 @@
<!-- https://en.wikipedia.org/wiki/Phonetic_keyboard_layout#Russian_Phonetic_Keyboard_2.0 -->
<keymap
name="цp"
label="Phonetic Cyrillic"
latched-name="Цp"
locked-name="ЦP">
<key code="29"> <!-- A -->
+1 -1
View File
@@ -1,6 +1,6 @@
<?xml version="1.0" encoding="utf-8"?>
<input-method xmlns:android="http://schemas.android.com/apk/res/android"
android:settingsActivity="cfpi_fpsi.eu.titanboard.PreferencesActivity"
android:settingsActivity="cfpi_fpsi.eu.titanboard.SettingsActivity"
android:supportsSwitchingToNextInputMethod="false">
<subtype
android:imeSubtypeMode="keyboard"
+46
View File
@@ -0,0 +1,46 @@
<?xml version="1.0" encoding="utf-8"?><!--
~ An input method for the Unihertz Titan/physical keyboard phones
~ Copyright (C) 2024 Emil Kosz
~
~ 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 3 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, see <https://www.gnu.org/licenses/>.
~
-->
<!--suppress DeprecatedClassUsageInspection -->
<PreferenceScreen xmlns:android="http://schemas.android.com/apk/res/android">
<SwitchPreference
android:defaultValue="@bool/auto_caps_default"
android:key="auto_caps"
android:title="@string/preferences_auto_caps" />
<SwitchPreference
android:defaultValue="@bool/auto_periods_default"
android:key="auto_periods"
android:title="@string/preferences_auto_periods" />
<SwitchPreference
android:defaultValue="@bool/autocorrect_default"
android:key="autocorrect"
android:title="@string/preferences_auto_correct" />
<ListPreference
android:defaultValue="@string/long_click_speed_default"
android:entries="@array/long_click_speed_labels"
android:entryValues="@array/long_click_speeds"
android:key="long_click_speed"
android:title="@string/preferences_long_click_speed" />
<MultiSelectListPreference
android:defaultValue="@array/available_keymap_defaults"
android:entries="@array/available_keymap_labels"
android:entryValues="@array/available_keymaps"
android:key="selected_keymaps"
android:title="@string/preferences_keymaps" />
</PreferenceScreen>