diff --git a/app/src/main/java/cfpi_fpsi/eu/titanboard/IME.java b/app/src/main/java/cfpi_fpsi/eu/titanboard/IME.java index 227044e..e055aa6 100644 --- a/app/src/main/java/cfpi_fpsi/eu/titanboard/IME.java +++ b/app/src/main/java/cfpi_fpsi/eu/titanboard/IME.java @@ -24,12 +24,15 @@ import android.inputmethodservice.InputMethodService; import android.os.Vibrator; import android.view.KeyEvent; import android.view.View; +import android.view.inputmethod.EditorInfo; import android.view.inputmethod.InputConnection; import android.widget.Button; import android.widget.LinearLayout; import android.widget.TextView; -import java.util.HashMap; +import java.util.ArrayDeque; +import java.util.Collections; +import java.util.Deque; // TODO: Implement long-click for extra keys. // TODO: Implement auto-correct. @@ -40,7 +43,9 @@ import java.util.HashMap; public class IME extends InputMethodService { private MetaKeyManager mMetaKeyManager; - private Keymap mKeymap; + private KeymapManager mKeymapManager; + private Deque mLanguageQueue = new ArrayDeque<>(); + private String mCurrentLanguage; private LinearLayout mInputView; private Vibrator mVibrator; @@ -48,8 +53,10 @@ public class IME extends InputMethodService { public void onCreate() { super.onCreate(); // Ideally, detect the device, but for now, load all available keymaps. - - mKeymap = new Keymap(getResources().getXml(R.xml.keymap_titan_pl)); + mKeymapManager = new KeymapManager(getResources().getXml(R.xml.keymaps_titan)); + Collections.addAll(mLanguageQueue, mKeymapManager.getAvailableLanguages()); + mCurrentLanguage = mLanguageQueue.pop(); + mLanguageQueue.addLast(mCurrentLanguage); mVibrator = (Vibrator) getBaseContext().getSystemService(VIBRATOR_SERVICE); mMetaKeyManager = new MetaKeyManager(mVibrator); } @@ -119,6 +126,12 @@ public class IME extends InputMethodService { return mInputView; } + @Override + public void onStartInput(EditorInfo info, boolean restarting) { + super.onStartInput(info, restarting); + updateMetaStateTextView(); + } + @Override public void onFinishInput() { mMetaKeyManager.resetMetaKeyState(); @@ -127,23 +140,23 @@ public class IME extends InputMethodService { private String getKey(int keyCode) { if (mMetaKeyManager.getAlt().isActive()) { - return mKeymap.getKeyAlt(keyCode); + return mKeymapManager.getKeyAlt(mCurrentLanguage, keyCode); } if (mMetaKeyManager.getSym().isActive() && mMetaKeyManager.getShift().isActive()) { - return mKeymap.getKeyShiftSym(keyCode); + return mKeymapManager.getKeyShiftSym(mCurrentLanguage, keyCode); } if (mMetaKeyManager.getSym().isActive()) { - return mKeymap.getKeySym(keyCode); + return mKeymapManager.getKeySym(mCurrentLanguage, keyCode); } if (mMetaKeyManager.getShift().isActive()) { - return mKeymap.getKeyShift(keyCode); + return mKeymapManager.getKeyShift(mCurrentLanguage, keyCode); } // Nothing active. - return mKeymap.getKey(keyCode); + return mKeymapManager.getKeyNone(mCurrentLanguage, keyCode); } @SuppressLint("SetTextI18n") @@ -151,6 +164,7 @@ public class IME extends InputMethodService { TextView shiftStateView = mInputView.findViewById(R.id.state_shift); TextView altStateView = mInputView.findViewById(R.id.state_alt); TextView symStateView = mInputView.findViewById(R.id.state_sym); + Button languageButton = mInputView.findViewById(R.id.language_button); shiftStateView.setText(getStringForMetaKey( mMetaKeyManager.getShift(), "aa", "Aa", "AA")); @@ -158,6 +172,7 @@ public class IME extends InputMethodService { mMetaKeyManager.getAlt(), "..", "#?", "#!")); symStateView.setText(getStringForMetaKey( mMetaKeyManager.getSym(), "..", "þπ", "ÞΩ")); + languageButton.setText(mKeymapManager.getShortLabel(mCurrentLanguage)); } private String getStringForMetaKey(MetaKeyManager.MetaKey key, String normal, String latched, String pressed) { @@ -172,6 +187,12 @@ public class IME extends InputMethodService { return normal; } + public void onInputViewLanguageClick(View v) { + mCurrentLanguage = mLanguageQueue.pop(); + mLanguageQueue.addLast(mCurrentLanguage); + updateMetaStateTextView(); + } + /** * @noinspection unused */ diff --git a/app/src/main/java/cfpi_fpsi/eu/titanboard/Keymap.java b/app/src/main/java/cfpi_fpsi/eu/titanboard/Keymap.java deleted file mode 100644 index 6878acb..0000000 --- a/app/src/main/java/cfpi_fpsi/eu/titanboard/Keymap.java +++ /dev/null @@ -1,95 +0,0 @@ -/* - * 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 . - * - */ - -package cfpi_fpsi.eu.titanboard; - -import org.xmlpull.v1.XmlPullParser; -import org.xmlpull.v1.XmlPullParserException; - -import java.io.IOException; -import java.util.HashMap; - -public class Keymap extends HashMap { - public Keymap(XmlPullParser parser) { - int code = 0; - String none = null, shift = null, alt = null, sym = null, shiftSym = null; - - try { - while (parser.getEventType() != XmlPullParser.END_DOCUMENT) { - int type = parser.getEventType(); - if (type == XmlPullParser.START_TAG && parser.getName().equals("key")) { - for (int i = 0; i < parser.getAttributeCount(); ++i) { - String attr = parser.getAttributeName(i); - switch (attr) { - case "code": - code = Integer.parseInt(parser.getAttributeValue(i)); - break; - case "none": - none = parser.getAttributeValue(i); - break; - case "shift": - shift = parser.getAttributeValue(i); - break; - case "alt": - alt = parser.getAttributeValue(i); - break; - case "sym": - sym = parser.getAttributeValue(i); - break; - case "shiftSym": - shiftSym = parser.getAttributeValue(i); - break; - } - } - } else if (type == XmlPullParser.END_TAG && parser.getName().equals("key")) { - put(code, new String[]{none, shift, alt, sym, shiftSym}); - } - - parser.next(); - } - } catch (XmlPullParserException | IOException e) { - throw new RuntimeException(e); - } - } - - public String getKey(int keyCode) { - String[] values = get(keyCode); - return values != null ? values[0] : null; - } - - public String getKeyShift(int keyCode) { - String[] values = get(keyCode); - return values != null ? values[1] : null; - } - - public String getKeyAlt(int keyCode) { - String[] values = get(keyCode); - return values != null ? values[2] : null; - } - - public String getKeySym(int keyCode) { - String[] values = get(keyCode); - return values != null ? values[3] : null; - } - - public String getKeyShiftSym(int keyCode) { - String[] values = get(keyCode); - return values != null ? values[4] : null; - } -} diff --git a/app/src/main/java/cfpi_fpsi/eu/titanboard/KeymapManager.java b/app/src/main/java/cfpi_fpsi/eu/titanboard/KeymapManager.java index 1eab85f..e646b2b 100644 --- a/app/src/main/java/cfpi_fpsi/eu/titanboard/KeymapManager.java +++ b/app/src/main/java/cfpi_fpsi/eu/titanboard/KeymapManager.java @@ -19,5 +19,172 @@ package cfpi_fpsi.eu.titanboard; +import org.xmlpull.v1.XmlPullParser; +import org.xmlpull.v1.XmlPullParserException; + +import java.io.IOException; +import java.util.HashMap; + public class KeymapManager { + // Yeah... I know this is a little wacky. + private final HashMap mKeymaps = new HashMap<>(); + + public KeymapManager(XmlPullParser parser) { + Keymap keymap = null; + String lang = null, shortLabel = null, label = null; + int code = 0; + String none = null, shift = null, alt = null, sym = null, shiftSym = null; + + try { + while (parser.getEventType() != XmlPullParser.END_DOCUMENT) { + int type = parser.getEventType(); + + if (type == XmlPullParser.START_TAG && parser.getName().equals("keymap")) { + keymap = new Keymap(); + for (int i = 0; i < parser.getAttributeCount(); ++i) { + switch (parser.getAttributeName(i)) { + case "lang": + lang = parser.getAttributeValue(i); + break; + case "short-label": + shortLabel = parser.getAttributeValue(i); + break; + case "label": + label = parser.getAttributeValue(i); + break; + } + } + } else if (type == XmlPullParser.END_TAG && parser.getName().equals("keymap")) { + keymap.mShortLabel = shortLabel; + keymap.mLabel = label; + mKeymaps.put(lang, keymap); + } + + if (type == XmlPullParser.START_TAG && parser.getName().equals("key")) { + for (int i = 0; i < parser.getAttributeCount(); ++i) { + String attr = parser.getAttributeName(i); + switch (attr) { + case "code": + code = Integer.parseInt(parser.getAttributeValue(i)); + break; + case "none": + none = parser.getAttributeValue(i); + break; + case "shift": + shift = parser.getAttributeValue(i); + break; + case "alt": + alt = parser.getAttributeValue(i); + break; + case "sym": + sym = parser.getAttributeValue(i); + break; + case "shiftSym": + shiftSym = parser.getAttributeValue(i); + break; + } + } + } else if (type == XmlPullParser.END_TAG && parser.getName().equals("key")) { + keymap.put(code, new Key(none, shift, alt, sym, shiftSym)); + } + + parser.next(); + } + } catch (XmlPullParserException | IOException e) { + throw new RuntimeException(e); + } + } + + public String[] getAvailableLanguages() { + return mKeymaps.keySet().toArray(new String[0]); + } + + public String getShortLabel(String lang) { + Keymap keymap = mKeymaps.get(lang); + if (keymap != null) { + return keymap.mShortLabel; + } else { + return null; + } + } + + public String getKeyNone(String lang, int keyCode) { + Key key = getKey(lang, keyCode); + if (key != null) { + return key.mNone; + } else { + return null; + } + } + + public String getKeyShift(String lang, int keyCode) { + Key key = getKey(lang, keyCode); + if (key != null) { + return key.mShift; + } else { + return null; + } + } + + public String getKeyAlt(String lang, int keyCode) { + Key key = getKey(lang, keyCode); + if (key != null) { + return key.mAlt; + } else { + return null; + } + } + + public String getKeySym(String lang, int keyCode) { + Key key = getKey(lang, keyCode); + if (key != null) { + return key.mSym; + } else { + return null; + } + } + + public String getKeyShiftSym(String lang, int keyCode) { + Key key = getKey(lang, keyCode); + if (key != null) { + return key.mShiftSym; + } else { + return null; + } + } + + public Key getKey(String lang, int keyCode) { + HashMap keymap = mKeymaps.get(lang); + if (keymap != null) { + Key key = keymap.get(keyCode); + if (key != null) { + return key; + } else { + return null; + } + } else { + return null; + } + } + + private static class Keymap extends HashMap { + public String mShortLabel; + public String mLabel; + } + + public static class Key { + public String mNone; + public String mShift; + public String mAlt; + public String mSym; + public String mShiftSym; + + public Key(String none, String shift, String alt, String sym, String shiftSym) { + mNone = none; + mShift = shift; + mAlt = alt; + mSym = sym; + mShiftSym = shiftSym; + } + } } diff --git a/app/src/main/res/layout/input.xml b/app/src/main/res/layout/input.xml index 5131b13..37516ed 100644 --- a/app/src/main/res/layout/input.xml +++ b/app/src/main/res/layout/input.xml @@ -37,9 +37,10 @@ tools:ignore="HardcodedText" />