Strict inspection warnings fixed, slight restructurings
This commit is contained in:
@@ -1,3 +1,4 @@
|
||||
<!--suppress IncorrectFormatting, LongLine -->
|
||||
<profile version="1.0">
|
||||
<option name="myName" value="Very strict" />
|
||||
<inspection_tool class="AbsoluteAlignmentInUserInterface" enabled="true" level="WARNING" enabled_by_default="true" />
|
||||
|
||||
+3
-2
@@ -11,14 +11,15 @@ android {
|
||||
minSdk 3
|
||||
targetSdk 35
|
||||
versionCode 30
|
||||
versionName "0.3"
|
||||
versionName '0.3'
|
||||
}
|
||||
|
||||
buildTypes {
|
||||
release {
|
||||
minifyEnabled true
|
||||
shrinkResources true
|
||||
proguardFiles getDefaultProguardFile('proguard-android-optimize.txt'), 'proguard-rules.pro'
|
||||
proguardFiles getDefaultProguardFile('proguard-android-optimize.txt'),
|
||||
'proguard-rules.pro'
|
||||
}
|
||||
|
||||
debug {
|
||||
|
||||
@@ -1,5 +1,4 @@
|
||||
<?xml version="1.0" encoding="utf-8"?>
|
||||
<!--
|
||||
<?xml version="1.0" encoding="utf-8"?><!--
|
||||
~ An input method for physical keyboard phones
|
||||
~ Copyright (C) 2024 Emil Kosz
|
||||
~
|
||||
@@ -48,7 +47,7 @@
|
||||
</service>
|
||||
|
||||
<activity
|
||||
android:name=".PreferenceActivity"
|
||||
android:name=".SettingsActivity"
|
||||
android:exported="false"
|
||||
android:label="@string/preferences_name">
|
||||
<intent-filter>
|
||||
|
||||
@@ -27,15 +27,17 @@ import android.os.Build;
|
||||
import java.util.ArrayList;
|
||||
|
||||
@TargetApi(Build.VERSION_CODES.HONEYCOMB)
|
||||
public class ClipManager extends ArrayList<ClipData.Item>
|
||||
implements ClipboardManager.OnPrimaryClipChangedListener {
|
||||
public class ClipManager implements ClipboardManager.OnPrimaryClipChangedListener {
|
||||
private final InputMethod mInputMethod;
|
||||
private final ClipboardManager mClipboardManager;
|
||||
private final ArrayList<ClipData.Item> mClips;
|
||||
private long mLastCallbackTimestamp;
|
||||
|
||||
public ClipManager(Context context) {
|
||||
mInputMethod = (InputMethod) context;
|
||||
mClipboardManager = (ClipboardManager) mInputMethod.getSystemService(Context.CLIPBOARD_SERVICE);
|
||||
mClips = new ArrayList<>(mInputMethod.mPreferenceHolder.getClipboardSize());
|
||||
mClipboardManager = (ClipboardManager)
|
||||
mInputMethod.getSystemService(Context.CLIPBOARD_SERVICE);
|
||||
mClipboardManager.addPrimaryClipChangedListener(this);
|
||||
}
|
||||
|
||||
@@ -43,29 +45,38 @@ public class ClipManager extends ArrayList<ClipData.Item>
|
||||
public void onPrimaryClipChanged() {
|
||||
// The callback can be launched several times at once, so we have to check if it isn't the
|
||||
// same clipboard data.
|
||||
if (System.currentTimeMillis() - mLastCallbackTimestamp < 100) {
|
||||
return;
|
||||
}
|
||||
if (System.currentTimeMillis() - mLastCallbackTimestamp >= 100) {
|
||||
mLastCallbackTimestamp = System.currentTimeMillis();
|
||||
ClipData clip = mClipboardManager.getPrimaryClip();
|
||||
|
||||
mLastCallbackTimestamp = System.currentTimeMillis();
|
||||
ClipData clip = mClipboardManager.getPrimaryClip();
|
||||
if (clip != null) {
|
||||
int itemCount = clip.getItemCount();
|
||||
for (int i = 0; i < itemCount; ++i) {
|
||||
ClipData.Item item = clip.getItemAt(i);
|
||||
// We do not support non-text clips for now, so all we add are text clips.
|
||||
if (item.getText() != null) {
|
||||
mClips.add(0, item);
|
||||
}
|
||||
|
||||
if (clip == null) {
|
||||
return;
|
||||
}
|
||||
if (mClips.size() > mInputMethod.mPreferenceHolder.getClipboardSize()) {
|
||||
mClips.remove(mClips.size() - 1);
|
||||
}
|
||||
}
|
||||
|
||||
for (int i = 0; i < clip.getItemCount(); ++i) {
|
||||
ClipData.Item item = clip.getItemAt(i);
|
||||
// We do not support non-text clips for now, so all we add are text clips.
|
||||
if (item.getText() != null) {
|
||||
add(0, item);
|
||||
}
|
||||
|
||||
if (size() > mInputMethod.mPreferenceHolder.getClipboardSize()) {
|
||||
remove(size() - 1);
|
||||
mInputMethod.mInputView.setClips(mClips);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
mInputMethod.mInputView.setClips(this);
|
||||
public boolean isEmpty() {
|
||||
return mClips.isEmpty();
|
||||
}
|
||||
|
||||
public void removeItem(ClipData.Item item) {
|
||||
mClips.remove(item);
|
||||
}
|
||||
|
||||
public ClipData.Item getItemAt(int index) {
|
||||
return mClips.get(index);
|
||||
}
|
||||
}
|
||||
|
||||
@@ -20,10 +20,14 @@ package eur.cfpifpsi.titanboard;
|
||||
|
||||
import java.util.ArrayList;
|
||||
|
||||
/**
|
||||
* @noinspection AbstractClassWithOnlyOneDirectInheritor
|
||||
*/
|
||||
public abstract class Cycler implements Runnable {
|
||||
private ArrayList<?> mList = new ArrayList<>();
|
||||
private boolean mHasCycled = false;
|
||||
private int mIndex = 0;
|
||||
private static final int LIST_INITIAL_SIZE = 10;
|
||||
private ArrayList<?> mList = new ArrayList<>(LIST_INITIAL_SIZE);
|
||||
private boolean mHasCycled;
|
||||
private int mIndex;
|
||||
|
||||
public int getIndex() {
|
||||
return mIndex;
|
||||
@@ -62,8 +66,7 @@ public abstract class Cycler implements Runnable {
|
||||
onCycle();
|
||||
}
|
||||
|
||||
public void onFirstCycle() {
|
||||
}
|
||||
public abstract void onFirstCycle();
|
||||
|
||||
public abstract void onCycle();
|
||||
}
|
||||
@@ -34,12 +34,6 @@ import java.util.ArrayList;
|
||||
|
||||
// TODO: Implement device recognition and a keymap picking based on it.
|
||||
|
||||
// UI: clicking on the text field shows the UI near the cursor (or in the center of the screen on
|
||||
// older APIs. From that UI
|
||||
|
||||
// The candidates view, while not needing any inset computation, is really buggy, so I instead opt
|
||||
// for using the input view and computing insets accordingly.
|
||||
|
||||
public class InputMethod extends InputMethodService {
|
||||
public MetaKeyManager mMetaKeyManager;
|
||||
public KeymapManager mKeymapManager;
|
||||
@@ -47,8 +41,8 @@ public class InputMethod extends InputMethodService {
|
||||
public ClipManager mClipManager;
|
||||
public InputView mInputView;
|
||||
public Vibrator mVibrator;
|
||||
private int mCurrentCursorPosition;
|
||||
private Handler mHandler;
|
||||
int mCurrentCursorPosition;
|
||||
Handler mHandler;
|
||||
private Cycler mSymbolCycler;
|
||||
|
||||
@Override
|
||||
@@ -61,7 +55,7 @@ public class InputMethod extends InputMethodService {
|
||||
mClipManager = new ClipManager(this);
|
||||
mHandler = new Handler(Looper.getMainLooper());
|
||||
mSymbolCycler = new SymbolCycler();
|
||||
mKeymapManager.cycleKeymaps(mPreferenceHolder.getSelectedKeymaps());
|
||||
mKeymapManager.nextKeymap(mPreferenceHolder.getSelectedKeymaps());
|
||||
}
|
||||
|
||||
@SuppressLint("InflateParams")
|
||||
@@ -84,6 +78,9 @@ public class InputMethod extends InputMethodService {
|
||||
return false;
|
||||
}
|
||||
|
||||
/**
|
||||
* @noinspection FeatureEnvy
|
||||
*/
|
||||
@Override
|
||||
public boolean onKeyDown(int keyCode, KeyEvent event) {
|
||||
mMetaKeyManager.updateMetaStateDown(keyCode);
|
||||
@@ -152,9 +149,9 @@ public class InputMethod extends InputMethodService {
|
||||
}
|
||||
|
||||
@Override
|
||||
public void onStartInput(EditorInfo info, boolean restarting) {
|
||||
super.onStartInput(info, restarting);
|
||||
mKeymapManager.checkCurrentKeymap(mPreferenceHolder.getSelectedKeymaps());
|
||||
public void onStartInput(EditorInfo attribute, boolean restarting) {
|
||||
super.onStartInput(attribute, restarting);
|
||||
mKeymapManager.adjustCurrentKeymap(mPreferenceHolder.getSelectedKeymaps());
|
||||
mInputView.updateStateText();
|
||||
|
||||
if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.LOLLIPOP) {
|
||||
@@ -170,7 +167,7 @@ public class InputMethod extends InputMethodService {
|
||||
|
||||
// Cyclers & runnables
|
||||
|
||||
private class SymbolCycler extends Cycler {
|
||||
class SymbolCycler extends Cycler {
|
||||
@Override
|
||||
public void onCycle() {
|
||||
mVibrator.vibrate(10);
|
||||
@@ -183,7 +180,7 @@ public class InputMethod extends InputMethodService {
|
||||
}
|
||||
}
|
||||
|
||||
@SuppressWarnings("unchecked")
|
||||
@SuppressWarnings("unchecked") //NON-NLS
|
||||
@Override
|
||||
public void onFirstCycle() {
|
||||
mInputView.setSymbolsVisible(true);
|
||||
|
||||
@@ -26,6 +26,7 @@ import android.graphics.Paint;
|
||||
import android.graphics.Typeface;
|
||||
import android.os.Build;
|
||||
import android.util.AttributeSet;
|
||||
import android.view.ViewGroup;
|
||||
import android.widget.Button;
|
||||
import android.widget.HorizontalScrollView;
|
||||
import android.widget.ImageButton;
|
||||
@@ -40,9 +41,8 @@ import java.util.ArrayList;
|
||||
// TODO: programmatically scroll if current selected symbol is outside the visible space of the
|
||||
// scrollview
|
||||
|
||||
public class InputView extends RelativeLayout {
|
||||
protected final int[] BUTTON_STATE_TOGGLED = {R.attr.state_toggled};
|
||||
|
||||
public final class InputView extends RelativeLayout {
|
||||
private final int[] buttonStateToggled = {R.attr.state_toggled};
|
||||
private final InputMethod mInputMethod;
|
||||
private final LinearLayout.LayoutParams mSymbolLayout;
|
||||
private final LinearLayout.LayoutParams mClipLayout;
|
||||
@@ -57,10 +57,10 @@ public class InputView extends RelativeLayout {
|
||||
mInputMethod = (InputMethod) context;
|
||||
mSymbolLayout = new LinearLayout.LayoutParams(
|
||||
getResources().getDimensionPixelSize(R.dimen.symbol_width),
|
||||
LinearLayout.LayoutParams.MATCH_PARENT, 0);
|
||||
ViewGroup.LayoutParams.MATCH_PARENT, 0);
|
||||
mClipLayout = new LinearLayout.LayoutParams(
|
||||
LinearLayout.LayoutParams.MATCH_PARENT,
|
||||
LinearLayout.LayoutParams.WRAP_CONTENT, 0);
|
||||
ViewGroup.LayoutParams.MATCH_PARENT,
|
||||
ViewGroup.LayoutParams.WRAP_CONTENT, 0);
|
||||
|
||||
mSymbolLayout.setMargins(0, 0,
|
||||
getResources().getDimensionPixelSize(R.dimen.default_space), 0);
|
||||
@@ -78,7 +78,7 @@ public class InputView extends RelativeLayout {
|
||||
mSymbolList = findViewById(R.id.symbol_list);
|
||||
mStateButton = findViewById(R.id.state_button);
|
||||
mClipboardButton = findViewById(R.id.clipboard_button);
|
||||
ScrollView mClipboardView = (ScrollView) inflate(this.getContext(), R.layout.clipboard, null);
|
||||
ScrollView mClipboardView = (ScrollView) inflate(getContext(), R.layout.clipboard, null);
|
||||
mClipList = mClipboardView.findViewById(R.id.clip_list);
|
||||
mClipboardPopup = new PopupWindow(mClipboardView,
|
||||
getResources().getDimensionPixelSize(R.dimen.clipboard_popup_width),
|
||||
@@ -90,13 +90,14 @@ public class InputView extends RelativeLayout {
|
||||
if (metaManager.getAlt().isActive()) {
|
||||
metaManager.getAlt().resetState();
|
||||
} else {
|
||||
mInputMethod.mKeymapManager.cycleKeymaps(mInputMethod.mPreferenceHolder.getSelectedKeymaps());
|
||||
mInputMethod.mKeymapManager
|
||||
.nextKeymap(mInputMethod.mPreferenceHolder.getSelectedKeymaps());
|
||||
}
|
||||
updateStateText();
|
||||
});
|
||||
|
||||
mStateButton.setOnLongClickListener(button -> {
|
||||
Intent intent = new Intent(getContext(), PreferenceActivity.class);
|
||||
Intent intent = new Intent(getContext(), SettingsActivity.class);
|
||||
intent.setFlags(Intent.FLAG_ACTIVITY_NEW_TASK);
|
||||
getContext().startActivity(intent);
|
||||
// For some reason, this vibrates by default, so we don't need to call the vibrator.
|
||||
@@ -106,7 +107,7 @@ public class InputView extends RelativeLayout {
|
||||
mClipboardButton.setOnClickListener(button -> {
|
||||
mClipboardPopup.showAsDropDown(mClipboardButton,
|
||||
-(mClipboardPopup.getWidth() - mClipboardButton.getWidth()) / 2, 0);
|
||||
mClipboardButton.setImageState(BUTTON_STATE_TOGGLED, true);
|
||||
mClipboardButton.setImageState(buttonStateToggled, true);
|
||||
});
|
||||
|
||||
mClipboardButton.setOnLongClickListener(button -> {
|
||||
@@ -114,13 +115,16 @@ public class InputView extends RelativeLayout {
|
||||
if (!mInputMethod.mClipManager.isEmpty()
|
||||
&& Build.VERSION.SDK_INT >= Build.VERSION_CODES.HONEYCOMB) {
|
||||
mInputMethod.getCurrentInputConnection()
|
||||
.commitText(mInputMethod.mClipManager.get(0).getText(), 1);
|
||||
.commitText(mInputMethod.mClipManager.getItemAt(0).getText(), 1);
|
||||
}
|
||||
|
||||
return true;
|
||||
});
|
||||
}
|
||||
|
||||
/**
|
||||
* @noinspection FeatureEnvy
|
||||
*/
|
||||
public void updateStateText() {
|
||||
MetaKeyManager metaManager = mInputMethod.mMetaKeyManager;
|
||||
KeymapManager keymapManager = mInputMethod.mKeymapManager;
|
||||
@@ -142,26 +146,27 @@ public class InputView extends RelativeLayout {
|
||||
}
|
||||
|
||||
if (metaManager.getShift().isPressed() || metaManager.getShift().isLocked()) {
|
||||
mStateButton.setText(keymapManager.getCurrentKeymap().getLockedCode());
|
||||
mStateButton.setText(keymapManager.getCurrentLockedLabel());
|
||||
return;
|
||||
}
|
||||
|
||||
if (metaManager.getShift().isLatched()) {
|
||||
mStateButton.setText(keymapManager.getCurrentKeymap().getLatchedCode());
|
||||
mStateButton.setText(keymapManager.getCurrentLatchedLabel());
|
||||
return;
|
||||
}
|
||||
|
||||
mStateButton.setText(keymapManager.getCurrentKeymap().getCode());
|
||||
mStateButton.setText(keymapManager.getCurrentLabel());
|
||||
}
|
||||
|
||||
@TargetApi(Build.VERSION_CODES.HONEYCOMB)
|
||||
public void setClips(ArrayList<ClipData.Item> items) {
|
||||
for (int i = 0; i < items.size(); ++i) {
|
||||
public void setClips(ArrayList<? extends ClipData.Item> items) {
|
||||
int size = items.size();
|
||||
for (int i = 0; i < size; ++i) {
|
||||
ClipData.Item item = items.get(i);
|
||||
LinearLayout clipView = (LinearLayout) mClipList.getChildAt(i);
|
||||
|
||||
if (clipView == null) {
|
||||
clipView = (LinearLayout) inflate(this.getContext(), R.layout.clip, null);
|
||||
clipView = (LinearLayout) inflate(getContext(), R.layout.clip, null);
|
||||
clipView.setTag(i);
|
||||
clipView.setLayoutParams(mClipLayout);
|
||||
mClipList.addView(clipView);
|
||||
@@ -169,15 +174,13 @@ public class InputView extends RelativeLayout {
|
||||
|
||||
Button pasteButton = clipView.findViewById(R.id.paste_button);
|
||||
pasteButton.setText(item.getText());
|
||||
// Required for marquee to work.
|
||||
pasteButton.setSelected(true);
|
||||
pasteButton.setOnClickListener(button -> mInputMethod.getCurrentInputConnection()
|
||||
.commitText(item.getText(), 1));
|
||||
|
||||
LinearLayout finalClipView = clipView;
|
||||
clipView.findViewById(R.id.button_delete).setOnClickListener(button -> {
|
||||
mClipList.removeView(finalClipView);
|
||||
mInputMethod.mClipManager.remove(item);
|
||||
mInputMethod.mClipManager.removeItem(item);
|
||||
});
|
||||
}
|
||||
}
|
||||
@@ -186,12 +189,16 @@ public class InputView extends RelativeLayout {
|
||||
mSymbolList.setVisibility(state ? VISIBLE : GONE);
|
||||
}
|
||||
|
||||
/**
|
||||
* @noinspection MethodWithMultipleLoops
|
||||
*/
|
||||
public void setSymbols(ArrayList<String> strings) {
|
||||
for (int i = 0; i < strings.size(); ++i) {
|
||||
int size = strings.size();
|
||||
for (int i = 0; i < size; ++i) {
|
||||
TextView tv = (TextView) mSymbolList.getChildAt(i);
|
||||
|
||||
if (tv == null) {
|
||||
tv = (TextView) inflate(this.getContext(), R.layout.symbol, null);
|
||||
tv = (TextView) inflate(getContext(), R.layout.symbol, null);
|
||||
tv.setTag(i);
|
||||
tv.setLayoutParams(mSymbolLayout);
|
||||
mSymbolList.addView(tv);
|
||||
@@ -201,13 +208,15 @@ public class InputView extends RelativeLayout {
|
||||
tv.setVisibility(VISIBLE);
|
||||
}
|
||||
|
||||
for (int i = strings.size(); i < mSymbolList.getChildCount(); ++i) {
|
||||
int childCount = mSymbolList.getChildCount();
|
||||
for (int i = size; i < childCount; ++i) {
|
||||
mSymbolList.getChildAt(i).setVisibility(GONE);
|
||||
}
|
||||
}
|
||||
|
||||
public void setSelectedSymbol(int index) {
|
||||
for (int i = 0; i < mSymbolList.getChildCount(); ++i) {
|
||||
int childCount = mSymbolList.getChildCount();
|
||||
for (int i = 0; i < childCount; ++i) {
|
||||
TextView tv = (TextView) mSymbolList.getChildAt(i);
|
||||
|
||||
if (i == index) {
|
||||
@@ -220,7 +229,7 @@ public class InputView extends RelativeLayout {
|
||||
// keymap that has a lot of symbols under one key, and also this is a safeguard for
|
||||
// smaller screen sizes.
|
||||
hsw.smoothScrollTo(tv.getRight()
|
||||
+ getResources().getDimensionPixelSize(R.dimen.default_space) * 2
|
||||
+ (getResources().getDimensionPixelSize(R.dimen.default_space) << 1)
|
||||
- hsw.getRight(), 0);
|
||||
} else {
|
||||
tv.setPressed(false);
|
||||
|
||||
@@ -26,98 +26,129 @@ import org.xmlpull.v1.XmlPullParserException;
|
||||
import java.io.IOException;
|
||||
import java.util.ArrayList;
|
||||
import java.util.HashMap;
|
||||
import java.util.Objects;
|
||||
import java.util.List;
|
||||
|
||||
public class KeymapManager {
|
||||
private static final String TAG_KEY = "key"; //NON-NLS
|
||||
private static final String TAG_KEYMAP = "keymap"; //NON-NLS
|
||||
private static final String TAG_BASE = "base"; //NON-NLS
|
||||
private static final String TAG_ALT = "alt"; //NON-NLS
|
||||
private static final String TAG_SHIFT = "shift"; //NON-NLS
|
||||
private static final String ATTR_CODE = "code"; //NON-NLS
|
||||
private static final String ATTR_VALUE = "value"; //NON-NLS
|
||||
private static final String ATTR_LABEL = "label"; //NON-NLS
|
||||
private static final String ATTR_LATCHED_LABEL = "latched-label"; //NON-NLS
|
||||
private static final String ATTR_LOCKED_LABEL = "locked-label"; //NON-NLS
|
||||
|
||||
private final Context mContext;
|
||||
private final HashMap<String, Keymap> mKeymaps = new HashMap<>();
|
||||
public Keymap mCurrentKeymap;
|
||||
private final HashMap<String, Keymap> mKeymaps;
|
||||
private Keymap mCurrentKeymap;
|
||||
|
||||
public KeymapManager(Context context) {
|
||||
mContext = context;
|
||||
mKeymaps = new HashMap<>(context.getResources()
|
||||
.getStringArray(R.array.preferences_keymaps).length);
|
||||
loadDeviceKeymaps(context.getResources().getXml(R.xml.keymaps_titan));
|
||||
}
|
||||
|
||||
/**
|
||||
* @noinspection BreakStatement
|
||||
*/
|
||||
private void loadDeviceKeymaps(XmlPullParser parser) {
|
||||
Keymap keymap = null;
|
||||
int code = 0;
|
||||
String name = null, latchedName = null, lockedName = null;
|
||||
String label = null, latchedLabel = null, lockedLabel = null;
|
||||
Key key = null;
|
||||
|
||||
try {
|
||||
while (parser.getEventType() != XmlPullParser.END_DOCUMENT) {
|
||||
int type = parser.getEventType();
|
||||
while (true) {
|
||||
int eventType;
|
||||
|
||||
// We encounter a new keymap.
|
||||
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 "name":
|
||||
name = parser.getAttributeValue(i);
|
||||
break;
|
||||
case "latched-name":
|
||||
latchedName = parser.getAttributeValue(i);
|
||||
break;
|
||||
case "locked-name":
|
||||
lockedName = parser.getAttributeValue(i);
|
||||
break;
|
||||
}
|
||||
try {
|
||||
eventType = parser.getEventType();
|
||||
} catch (XmlPullParserException e) {
|
||||
break;
|
||||
}
|
||||
|
||||
if (eventType == XmlPullParser.END_DOCUMENT) break;
|
||||
|
||||
// We encounter a new keymap.
|
||||
if (eventType == XmlPullParser.START_TAG && parser.getName().equals(TAG_KEYMAP)) {
|
||||
keymap = new Keymap();
|
||||
int attributeCount = parser.getAttributeCount();
|
||||
for (int i = 0; i < attributeCount; ++i) {
|
||||
switch (parser.getAttributeName(i)) {
|
||||
case ATTR_LABEL:
|
||||
label = parser.getAttributeValue(i);
|
||||
break;
|
||||
case ATTR_LATCHED_LABEL:
|
||||
latchedLabel = parser.getAttributeValue(i);
|
||||
break;
|
||||
case ATTR_LOCKED_LABEL:
|
||||
lockedLabel = parser.getAttributeValue(i);
|
||||
break;
|
||||
}
|
||||
} else if (type == XmlPullParser.END_TAG && parser.getName().equals("keymap")
|
||||
&& keymap != null) {
|
||||
keymap.setStrings(name, latchedName, lockedName);
|
||||
mKeymaps.put(name, keymap);
|
||||
}
|
||||
} else if (eventType == XmlPullParser.END_TAG && parser.getName().equals(TAG_KEYMAP)
|
||||
&& keymap != null) {
|
||||
keymap.code = label;
|
||||
keymap.latchedCode = latchedLabel;
|
||||
keymap.lockedCode = lockedLabel;
|
||||
mKeymaps.put(label, keymap);
|
||||
}
|
||||
|
||||
// We got a new key.
|
||||
if (type == XmlPullParser.START_TAG && parser.getName().equals("key")) {
|
||||
key = new Key();
|
||||
for (int i = 0; i < parser.getAttributeCount(); ++i) {
|
||||
if (parser.getAttributeName(i).equals("code")) {
|
||||
code = Integer.parseInt(parser.getAttributeValue(i));
|
||||
}
|
||||
// We got a new key.
|
||||
if (eventType == XmlPullParser.START_TAG && parser.getName().equals(TAG_KEY)) {
|
||||
key = new Key();
|
||||
int attributeCount = parser.getAttributeCount();
|
||||
for (int i = 0; i < attributeCount; ++i) {
|
||||
if (parser.getAttributeName(i).equals(ATTR_CODE)) {
|
||||
code = Integer.parseInt(parser.getAttributeValue(i));
|
||||
}
|
||||
} else if (type == XmlPullParser.END_TAG && parser.getName().equals("key")
|
||||
&& keymap != null) {
|
||||
keymap.put(code, key);
|
||||
}
|
||||
} else if (eventType == XmlPullParser.END_TAG && parser.getName().equals(TAG_KEY)
|
||||
&& keymap != null) {
|
||||
keymap.put(code, key);
|
||||
}
|
||||
|
||||
// We encountered a base value.
|
||||
if (type == XmlPullParser.START_TAG && parser.getName().equals("base")) {
|
||||
for (int i = 0; i < parser.getAttributeCount(); ++i) {
|
||||
if (parser.getAttributeName(i).startsWith("value") && key != null) {
|
||||
key.getSymbolsBase().add(parser.getAttributeValue(i));
|
||||
}
|
||||
// We encountered a base value.
|
||||
if (eventType == XmlPullParser.START_TAG && parser.getName().equals(TAG_BASE)) {
|
||||
int attributeCount = parser.getAttributeCount();
|
||||
for (int i = 0; i < attributeCount; ++i) {
|
||||
if (parser.getAttributeName(i).startsWith(ATTR_VALUE) && key != null) {
|
||||
key.symbolsBase.add(parser.getAttributeValue(i));
|
||||
}
|
||||
}
|
||||
// We encountered a shift value.
|
||||
if (type == XmlPullParser.START_TAG && parser.getName().equals("shift")) {
|
||||
for (int i = 0; i < parser.getAttributeCount(); ++i) {
|
||||
if (parser.getAttributeName(i).startsWith("value") && key != null) {
|
||||
key.getSymbolsShift().add(parser.getAttributeValue(i));
|
||||
}
|
||||
}
|
||||
// We encountered a shift value.
|
||||
if (eventType == XmlPullParser.START_TAG && parser.getName().equals(TAG_SHIFT)) {
|
||||
int attributeCount = parser.getAttributeCount();
|
||||
for (int i = 0; i < attributeCount; ++i) {
|
||||
if (parser.getAttributeName(i).startsWith(ATTR_VALUE) && key != null) {
|
||||
key.symbolsShift.add(parser.getAttributeValue(i));
|
||||
}
|
||||
}
|
||||
// We encountered an alt value.
|
||||
if (type == XmlPullParser.START_TAG && parser.getName().equals("alt")) {
|
||||
for (int i = 0; i < parser.getAttributeCount(); ++i) {
|
||||
if (parser.getAttributeName(i).startsWith("value") && key != null) {
|
||||
key.getSymbolsAlt().add(parser.getAttributeValue(i));
|
||||
}
|
||||
}
|
||||
// We encountered an alt value.
|
||||
if (eventType == XmlPullParser.START_TAG && parser.getName().equals(TAG_ALT)) {
|
||||
int attributeCount = parser.getAttributeCount();
|
||||
for (int i = 0; i < attributeCount; ++i) {
|
||||
if (parser.getAttributeName(i).startsWith(ATTR_VALUE) && key != null) {
|
||||
key.symbolsAlt.add(parser.getAttributeValue(i));
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
try {
|
||||
parser.next();
|
||||
} catch (XmlPullParserException | IOException e) {
|
||||
break;
|
||||
}
|
||||
} catch (XmlPullParserException | IOException e) {
|
||||
throw new RuntimeException(e);
|
||||
}
|
||||
}
|
||||
|
||||
public ArrayList<String> getSymbols(int keyCode, MetaKeyManager metaKeyManager) {
|
||||
ArrayList<String> alt = getCurrentKeymap().getSymbolsAlt(keyCode);
|
||||
ArrayList<String> shift = getCurrentKeymap().getSymbolsShift(keyCode);
|
||||
ArrayList<String> alt = mCurrentKeymap.getSymbolsAlt(keyCode);
|
||||
ArrayList<String> shift = mCurrentKeymap.getSymbolsShift(keyCode);
|
||||
|
||||
if (metaKeyManager.getAlt().isActive() && alt != null && !alt.isEmpty()) {
|
||||
return alt;
|
||||
@@ -127,86 +158,83 @@ public class KeymapManager {
|
||||
return shift;
|
||||
}
|
||||
|
||||
return getCurrentKeymap().getSymbolsBase(keyCode);
|
||||
return mCurrentKeymap.getSymbolsBase(keyCode);
|
||||
}
|
||||
|
||||
public void checkCurrentKeymap(ArrayList<String> selectedKeymaps) {
|
||||
if (!selectedKeymaps.contains(mCurrentKeymap.mCode)) {
|
||||
cycleKeymaps(selectedKeymaps);
|
||||
public void adjustCurrentKeymap(List<String> selectedKeymaps) {
|
||||
if (!selectedKeymaps.contains(mCurrentKeymap.code)) {
|
||||
nextKeymap(selectedKeymaps);
|
||||
}
|
||||
}
|
||||
|
||||
public void cycleKeymaps(ArrayList<String> selectedKeymaps) {
|
||||
if (selectedKeymaps.isEmpty() || mCurrentKeymap == null) {
|
||||
mCurrentKeymap = mKeymaps.get(mContext.getResources().getString(R.string.keymap_default));
|
||||
return;
|
||||
public void nextKeymap(List<String> selectedKeymaps) {
|
||||
if (!selectedKeymaps.isEmpty() && mCurrentKeymap != null) {
|
||||
int index = selectedKeymaps.indexOf(mCurrentKeymap.code);
|
||||
index++;
|
||||
|
||||
if (index == selectedKeymaps.size()) {
|
||||
index = 0;
|
||||
}
|
||||
|
||||
mCurrentKeymap = mKeymaps.get(selectedKeymaps.get(index));
|
||||
} else {
|
||||
mCurrentKeymap =
|
||||
mKeymaps.get(mContext.getResources().getString(R.string.keymap_default));
|
||||
}
|
||||
|
||||
int index = selectedKeymaps.indexOf(mCurrentKeymap.mCode);
|
||||
index++;
|
||||
|
||||
if (index == selectedKeymaps.size()) {
|
||||
index = 0;
|
||||
}
|
||||
|
||||
mCurrentKeymap = mKeymaps.get(selectedKeymaps.get(index));
|
||||
}
|
||||
|
||||
public Keymap getCurrentKeymap() {
|
||||
return mCurrentKeymap;
|
||||
public String getCurrentLabel() {
|
||||
return mCurrentKeymap.code;
|
||||
}
|
||||
|
||||
public static class Keymap extends HashMap<Integer, Key> {
|
||||
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.
|
||||
public String getCurrentLatchedLabel() {
|
||||
return mCurrentKeymap.latchedCode;
|
||||
}
|
||||
|
||||
public String getCode() {
|
||||
return mCode;
|
||||
}
|
||||
public String getCurrentLockedLabel() {
|
||||
return mCurrentKeymap.lockedCode;
|
||||
}
|
||||
|
||||
public String getLatchedCode() {
|
||||
return mLatchedCode;
|
||||
}
|
||||
|
||||
public String getLockedCode() {
|
||||
return mLockedCode;
|
||||
}
|
||||
|
||||
public void setStrings(String code, String latched, String locked) {
|
||||
mCode = code;
|
||||
mLatchedCode = latched;
|
||||
mLockedCode = locked;
|
||||
}
|
||||
static class Keymap {
|
||||
private final static int INITIAL_KEYMAP_SIZE = 64; // Enough for just about any QWERTY.
|
||||
private final HashMap<Integer, Key> mMap = new HashMap<>(INITIAL_KEYMAP_SIZE);
|
||||
String code;
|
||||
String latchedCode;
|
||||
String lockedCode;
|
||||
|
||||
/**
|
||||
* @noinspection ReturnOfNull
|
||||
*/
|
||||
public ArrayList<String> getSymbolsBase(int keyCode) {
|
||||
return get(keyCode) != null ? Objects.requireNonNull(get(keyCode)).getSymbolsBase() : null;
|
||||
Key key = mMap.get(keyCode);
|
||||
return key == null ? null : key.symbolsBase;
|
||||
}
|
||||
|
||||
/**
|
||||
* @noinspection ReturnOfNull
|
||||
*/
|
||||
public ArrayList<String> getSymbolsAlt(int keyCode) {
|
||||
return get(keyCode) != null ? Objects.requireNonNull(get(keyCode)).getSymbolsAlt() : null;
|
||||
Key key = mMap.get(keyCode);
|
||||
return key == null ? null : key.symbolsAlt;
|
||||
}
|
||||
|
||||
/**
|
||||
* @noinspection ReturnOfNull
|
||||
*/
|
||||
public ArrayList<String> getSymbolsShift(int keyCode) {
|
||||
return get(keyCode) != null ? Objects.requireNonNull(get(keyCode)).getSymbolsShift() : null;
|
||||
Key key = mMap.get(keyCode);
|
||||
return key == null ? null : key.symbolsShift;
|
||||
}
|
||||
|
||||
public void put(Integer key, Key value) {
|
||||
mMap.put(key, value);
|
||||
}
|
||||
}
|
||||
|
||||
public static class Key {
|
||||
private final ArrayList<String> mSymbolsBase = new ArrayList<>();
|
||||
private final ArrayList<String> mSymbolsShift = new ArrayList<>();
|
||||
private final ArrayList<String> mSymbolsAlt = new ArrayList<>();
|
||||
|
||||
public ArrayList<String> getSymbolsBase() {
|
||||
return mSymbolsBase;
|
||||
}
|
||||
|
||||
public ArrayList<String> getSymbolsShift() {
|
||||
return mSymbolsShift;
|
||||
}
|
||||
|
||||
public ArrayList<String> getSymbolsAlt() {
|
||||
return mSymbolsAlt;
|
||||
}
|
||||
static class Key {
|
||||
private final static int INITIAL_SIZE = 6;
|
||||
final ArrayList<String> symbolsBase = new ArrayList<>(INITIAL_SIZE);
|
||||
final ArrayList<String> symbolsShift = new ArrayList<>(INITIAL_SIZE);
|
||||
final ArrayList<String> symbolsAlt = new ArrayList<>(INITIAL_SIZE);
|
||||
}
|
||||
}
|
||||
|
||||
@@ -0,0 +1,65 @@
|
||||
package eur.cfpifpsi.titanboard;
|
||||
|
||||
import android.view.KeyEvent;
|
||||
|
||||
public class MetaKey {
|
||||
private static final long TOGGLE_DURATION = 400L;
|
||||
private boolean mPressed;
|
||||
private boolean mLatched;
|
||||
private boolean mLocked;
|
||||
private boolean mUsed;
|
||||
private long mKeyUpTime;
|
||||
|
||||
public void onDown() {
|
||||
mUsed = false;
|
||||
mPressed = true;
|
||||
// It's not true that mLocked is always true...
|
||||
//noinspection ConstantValue
|
||||
mLatched = mLocked ? mLocked : mLatched;
|
||||
mLocked = false;
|
||||
}
|
||||
|
||||
public void onUp(KeyEvent event) {
|
||||
if (event.getEventTime() - mKeyUpTime < TOGGLE_DURATION) {
|
||||
mLocked = true;
|
||||
}
|
||||
|
||||
mKeyUpTime = event.getEventTime();
|
||||
mPressed = false;
|
||||
mLatched = !mLatched && !mLocked && !mUsed;
|
||||
}
|
||||
|
||||
public void afterKeypress() {
|
||||
if (mLatched) {
|
||||
mLatched = false;
|
||||
mUsed = false;
|
||||
}
|
||||
|
||||
if (mPressed) {
|
||||
mUsed = true;
|
||||
}
|
||||
}
|
||||
|
||||
public void resetState() {
|
||||
mPressed = false;
|
||||
mLatched = false;
|
||||
mLocked = false;
|
||||
mUsed = false;
|
||||
}
|
||||
|
||||
public boolean isPressed() {
|
||||
return mPressed;
|
||||
}
|
||||
|
||||
public boolean isLatched() {
|
||||
return mLatched;
|
||||
}
|
||||
|
||||
public boolean isLocked() {
|
||||
return mLocked;
|
||||
}
|
||||
|
||||
public boolean isActive() {
|
||||
return mPressed || mLocked || mLatched;
|
||||
}
|
||||
}
|
||||
@@ -22,6 +22,7 @@ import android.os.Vibrator;
|
||||
import android.view.KeyEvent;
|
||||
|
||||
public class MetaKeyManager {
|
||||
private static final int TOGGLE_VIBRATION_TIME = 30;
|
||||
public final MetaKey mShift = new MetaKey();
|
||||
public final MetaKey mAlt = new MetaKey();
|
||||
|
||||
@@ -35,66 +36,44 @@ public class MetaKeyManager {
|
||||
switch (keyCode) {
|
||||
case KeyEvent.KEYCODE_ALT_LEFT:
|
||||
case KeyEvent.KEYCODE_ALT_RIGHT:
|
||||
updateMetaKeyDown(mAlt);
|
||||
mAlt.onDown();
|
||||
break;
|
||||
case KeyEvent.KEYCODE_SHIFT_LEFT:
|
||||
case KeyEvent.KEYCODE_SHIFT_RIGHT:
|
||||
updateMetaKeyDown(mShift);
|
||||
mShift.onDown();
|
||||
break;
|
||||
default:
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* @noinspection FeatureEnvy
|
||||
*/
|
||||
public void updateMetaStateUp(int keyCode, KeyEvent event) {
|
||||
switch (keyCode) {
|
||||
case KeyEvent.KEYCODE_ALT_LEFT:
|
||||
case KeyEvent.KEYCODE_ALT_RIGHT:
|
||||
updateMetaKeyUp(mAlt, event);
|
||||
mAlt.onUp(event);
|
||||
if (mAlt.isLocked()) {
|
||||
mVibrator.vibrate(TOGGLE_VIBRATION_TIME);
|
||||
}
|
||||
break;
|
||||
case KeyEvent.KEYCODE_SHIFT_LEFT:
|
||||
case KeyEvent.KEYCODE_SHIFT_RIGHT:
|
||||
updateMetaKeyUp(mShift, event);
|
||||
mShift.onUp(event);
|
||||
if (mShift.isLocked()) {
|
||||
mVibrator.vibrate(TOGGLE_VIBRATION_TIME);
|
||||
}
|
||||
break;
|
||||
default:
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
void updateMetaKeyDown(MetaKey key) {
|
||||
// Perhaps this function should be renamed to something...
|
||||
key.setUsed(false);
|
||||
key.setPressed(true);
|
||||
key.setLatched(key.isLocked() ? key.isLocked() : key.isLatched());
|
||||
key.setLocked(false);
|
||||
}
|
||||
|
||||
public void updateMetaKeyUp(MetaKey key, KeyEvent event) {
|
||||
if (event.getEventTime() - key.getKeyUpTime() < 400) {
|
||||
key.setLocked(true);
|
||||
mVibrator.vibrate(30);
|
||||
}
|
||||
|
||||
key.setKeyUpTime(event.getEventTime());
|
||||
key.setPressed(false);
|
||||
|
||||
key.setLatched(!key.isLatched() && !key.isLocked() && !key.isUsed());
|
||||
}
|
||||
|
||||
public void adjustMetaStateAfterKeypress() {
|
||||
adjustMetaStateHelper(mShift);
|
||||
adjustMetaStateHelper(mAlt);
|
||||
}
|
||||
|
||||
public void adjustMetaStateHelper(MetaKey key) {
|
||||
if (key.isLatched()) {
|
||||
key.setLatched(false);
|
||||
key.setUsed(false);
|
||||
}
|
||||
|
||||
if (key.isPressed()) {
|
||||
key.setUsed(true);
|
||||
}
|
||||
mShift.afterKeypress();
|
||||
mAlt.afterKeypress();
|
||||
}
|
||||
|
||||
public void resetMetaKeyState() {
|
||||
@@ -109,63 +88,4 @@ public class MetaKeyManager {
|
||||
public MetaKey getAlt() {
|
||||
return mAlt;
|
||||
}
|
||||
|
||||
public static class MetaKey {
|
||||
private boolean mPressed = false;
|
||||
private boolean mLatched = false;
|
||||
private boolean mLocked = false;
|
||||
private boolean mUsed = false;
|
||||
private long mKeyUpTime;
|
||||
|
||||
public void resetState() {
|
||||
setPressed(false);
|
||||
setLatched(false);
|
||||
setLocked(false);
|
||||
setUsed(false);
|
||||
}
|
||||
|
||||
public boolean isPressed() {
|
||||
return mPressed;
|
||||
}
|
||||
|
||||
public void setPressed(boolean state) {
|
||||
mPressed = state;
|
||||
}
|
||||
|
||||
public boolean isLatched() {
|
||||
return mLatched;
|
||||
}
|
||||
|
||||
public void setLatched(boolean state) {
|
||||
mLatched = state;
|
||||
}
|
||||
|
||||
public boolean isLocked() {
|
||||
return mLocked;
|
||||
}
|
||||
|
||||
public void setLocked(boolean state) {
|
||||
mLocked = state;
|
||||
}
|
||||
|
||||
public boolean isUsed() {
|
||||
return mUsed;
|
||||
}
|
||||
|
||||
public void setUsed(boolean state) {
|
||||
mUsed = state;
|
||||
}
|
||||
|
||||
public boolean isActive() {
|
||||
return isPressed() || isLocked() || isLatched();
|
||||
}
|
||||
|
||||
public long getKeyUpTime() {
|
||||
return mKeyUpTime;
|
||||
}
|
||||
|
||||
public void setKeyUpTime(long time) {
|
||||
mKeyUpTime = time;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
@@ -33,7 +33,7 @@ public class PreferenceHolder implements SharedPreferences.OnSharedPreferenceCha
|
||||
private final Map<String, Object> mPreferenceValues;
|
||||
private final Context mContext;
|
||||
|
||||
@SuppressWarnings("unchecked")
|
||||
@SuppressWarnings("unchecked") //NON-NLS
|
||||
public PreferenceHolder(Context context) {
|
||||
mContext = context;
|
||||
SharedPreferences mPreferences = PreferenceManager.getDefaultSharedPreferences(mContext);
|
||||
@@ -55,13 +55,6 @@ public class PreferenceHolder implements SharedPreferences.OnSharedPreferenceCha
|
||||
return value == null ? defaultValue : value;
|
||||
}
|
||||
|
||||
// --Commented out by Inspection START (05.11.2024, 10:28):
|
||||
// public boolean getFloatingInterface() {
|
||||
// return (boolean) getOrDefault(mContext.getString(R.string.preferences_key_floating_interface),
|
||||
// mContext.getResources().getBoolean(R.bool.floating_ui_default));
|
||||
// }
|
||||
// --Commented out by Inspection STOP (05.11.2024, 10:28)
|
||||
|
||||
public int getCycleSpeed() {
|
||||
return Integer.parseInt((String)
|
||||
getOrDefault(mContext.getString(R.string.preferences_key_cycle_speed),
|
||||
@@ -74,11 +67,12 @@ public class PreferenceHolder implements SharedPreferences.OnSharedPreferenceCha
|
||||
mContext.getString(R.string.clipboard_size_default)));
|
||||
}
|
||||
|
||||
@SuppressWarnings("unchecked")
|
||||
@SuppressWarnings("unchecked") //NON-NLS
|
||||
public ArrayList<String> getSelectedKeymaps() {
|
||||
Set<String> selectedKeymaps = (Set<String>)
|
||||
getOrDefault(mContext.getString(R.string.preferences_key_keymaps),
|
||||
mContext.getResources().getStringArray(R.array.preferences_keymap_defaults));
|
||||
mContext.getResources()
|
||||
.getStringArray(R.array.preferences_keymap_defaults));
|
||||
return new ArrayList<>(selectedKeymaps);
|
||||
}
|
||||
}
|
||||
|
||||
+2
-1
@@ -19,11 +19,12 @@
|
||||
package eur.cfpifpsi.titanboard;
|
||||
|
||||
import android.os.Bundle;
|
||||
import android.preference.PreferenceActivity;
|
||||
|
||||
/**
|
||||
* @noinspection deprecation
|
||||
*/
|
||||
public class PreferenceActivity extends android.preference.PreferenceActivity {
|
||||
public class SettingsActivity extends PreferenceActivity {
|
||||
@Override
|
||||
protected void onCreate(Bundle savedInstanceState) {
|
||||
super.onCreate(savedInstanceState);
|
||||
@@ -16,13 +16,11 @@
|
||||
~ along with this program. If not, see <https://www.gnu.org/licenses/>.
|
||||
-->
|
||||
|
||||
<selector xmlns:android="http://schemas.android.com/apk/res/android"
|
||||
xmlns:app="http://schemas.android.com/apk/res-auto">
|
||||
<selector xmlns:android="http://schemas.android.com/apk/res/android" xmlns:app="http://schemas.android.com/apk/res-auto">
|
||||
<item app:state_toggled="true">
|
||||
<shape android:shape="rectangle">
|
||||
<solid android:color="@color/button_toggled" />
|
||||
<corners android:bottomLeftRadius="@dimen/default_border_radius"
|
||||
android:bottomRightRadius="@dimen/default_border_radius" />
|
||||
<corners android:bottomLeftRadius="@dimen/default_border_radius" android:bottomRightRadius="@dimen/default_border_radius" />
|
||||
</shape>
|
||||
</item>
|
||||
<item android:state_pressed="false">
|
||||
|
||||
@@ -17,55 +17,68 @@
|
||||
-->
|
||||
|
||||
<layer-list xmlns:android="http://schemas.android.com/apk/res/android">
|
||||
<!-- <item android:top="11dp"-->
|
||||
<!-- android:bottom="11dp"-->
|
||||
<!-- android:right="14dp"-->
|
||||
<!-- android:left="14dp">-->
|
||||
<!-- <shape android:shape="rectangle">-->
|
||||
<!-- <solid android:color="@android:color/darker_gray" />-->
|
||||
<!-- </shape>-->
|
||||
<!-- </item>-->
|
||||
<!-- <item android:top="11dp"-->
|
||||
<!-- android:bottom="11dp"-->
|
||||
<!-- android:right="14dp"-->
|
||||
<!-- android:left="14dp">-->
|
||||
<!-- <shape android:shape="rectangle">-->
|
||||
<!-- <solid android:color="@android:color/darker_gray" />-->
|
||||
<!-- </shape>-->
|
||||
<!-- </item>-->
|
||||
|
||||
<!-- Main board -->
|
||||
<item android:top="12.5dp"
|
||||
<item
|
||||
android:bottom="11dp"
|
||||
android:left="14dp"
|
||||
android:right="14dp"
|
||||
android:bottom="11dp">
|
||||
android:top="12.5dp">
|
||||
<shape android:shape="rectangle">
|
||||
<stroke android:color="@color/text_color" android:width="2dp" />
|
||||
<stroke
|
||||
android:width="2dp"
|
||||
android:color="@color/text_color" />
|
||||
<corners android:radius="2dp" />
|
||||
</shape>
|
||||
</item>
|
||||
<!-- The clip -->
|
||||
<item android:top="11dp"
|
||||
<item
|
||||
android:bottom="32dp"
|
||||
android:left="20dp"
|
||||
android:right="20dp"
|
||||
android:left="20dp">
|
||||
android:top="11dp">
|
||||
<shape android:shape="rectangle">
|
||||
<solid android:color="@color/text_color"/>
|
||||
<solid android:color="@color/text_color" />
|
||||
<corners android:radius="2dp" />
|
||||
</shape>
|
||||
</item>
|
||||
<!-- Squiggles -->
|
||||
<item android:left="18dp"
|
||||
android:right="18dp"
|
||||
android:bottom="7dp">
|
||||
<item
|
||||
android:bottom="7dp"
|
||||
android:left="18dp"
|
||||
android:right="18dp">
|
||||
<shape android:shape="line">
|
||||
<stroke android:width="2dp" android:color="@color/text_color" />
|
||||
<stroke
|
||||
android:width="2dp"
|
||||
android:color="@color/text_color" />
|
||||
</shape>
|
||||
</item>
|
||||
<item android:left="18dp"
|
||||
<item
|
||||
android:left="18dp"
|
||||
android:right="18dp"
|
||||
android:top="2dp">
|
||||
<shape android:shape="line">
|
||||
<stroke android:width="2dp" android:color="@color/text_color" />
|
||||
<stroke
|
||||
android:width="2dp"
|
||||
android:color="@color/text_color" />
|
||||
</shape>
|
||||
</item>
|
||||
<item android:left="18dp"
|
||||
<item
|
||||
android:left="18dp"
|
||||
android:right="22dp"
|
||||
android:top="11dp">
|
||||
<shape android:shape="line">
|
||||
<stroke android:width="2dp" android:color="@color/text_color" />
|
||||
<stroke
|
||||
android:width="2dp"
|
||||
android:color="@color/text_color" />
|
||||
</shape>
|
||||
</item>
|
||||
</layer-list>
|
||||
@@ -27,9 +27,8 @@
|
||||
android:layout_height="match_parent"
|
||||
android:layout_weight="1"
|
||||
android:background="@drawable/button_transparent"
|
||||
android:ellipsize="marquee"
|
||||
android:ellipsize="end"
|
||||
android:gravity="center_vertical"
|
||||
android:marqueeRepeatLimit="marquee_forever"
|
||||
android:padding="@dimen/default_space"
|
||||
android:singleLine="true"
|
||||
android:text="@string/clip_default_text"
|
||||
|
||||
@@ -21,9 +21,9 @@
|
||||
<device-keymap-list>
|
||||
<!-- English -->
|
||||
<keymap
|
||||
name="en"
|
||||
latched-name="En"
|
||||
locked-name="EN">
|
||||
label="en"
|
||||
latched-label="En"
|
||||
locked-label="EN">
|
||||
<key code="29"> <!-- A -->
|
||||
<base value="a" />
|
||||
<shift value="A" />
|
||||
@@ -182,9 +182,9 @@
|
||||
</keymap>
|
||||
<!-- German -->
|
||||
<keymap
|
||||
name="de"
|
||||
latched-name="De"
|
||||
locked-name="DE">
|
||||
label="de"
|
||||
latched-label="De"
|
||||
locked-label="DE">
|
||||
<key code="29"> <!-- A -->
|
||||
<base value="a" />
|
||||
<base value="ä" />
|
||||
@@ -355,9 +355,9 @@
|
||||
</keymap>
|
||||
<!-- French -->
|
||||
<keymap
|
||||
name="fr"
|
||||
latched-name="Fr"
|
||||
locked-name="FR">
|
||||
label="fr"
|
||||
latched-label="Fr"
|
||||
locked-label="FR">
|
||||
<key code="29"> <!-- A -->
|
||||
<base value="a" />
|
||||
<base value="à" />
|
||||
@@ -552,9 +552,9 @@
|
||||
</keymap>
|
||||
<!-- Italian -->
|
||||
<keymap
|
||||
name="it"
|
||||
latched-name="It"
|
||||
locked-name="IT">
|
||||
label="it"
|
||||
latched-label="It"
|
||||
locked-label="IT">
|
||||
<key code="29"> <!-- A -->
|
||||
<base value="a" />
|
||||
<base value="à" />
|
||||
@@ -735,9 +735,9 @@
|
||||
</keymap>
|
||||
<!-- Spanish -->
|
||||
<keymap
|
||||
name="es"
|
||||
latched-name="Es"
|
||||
locked-name="ES">
|
||||
label="es"
|
||||
latched-label="Es"
|
||||
locked-label="ES">
|
||||
<key code="29"> <!-- A -->
|
||||
<base value="a" />
|
||||
<base value="á" />
|
||||
@@ -916,9 +916,9 @@
|
||||
</keymap>
|
||||
<!-- Polish -->
|
||||
<keymap
|
||||
name="pl"
|
||||
latched-name="Pl"
|
||||
locked-name="PL">
|
||||
label="pl"
|
||||
latched-label="Pl"
|
||||
locked-label="PL">
|
||||
<key code="29"> <!-- A -->
|
||||
<base value="a" />
|
||||
<base value="ą" />
|
||||
@@ -1098,9 +1098,9 @@
|
||||
<!-- Russian (Phonetic) -->
|
||||
<!-- https://en.wikipedia.org/wiki/Phonetic_keyboard_layout#Russian_Phonetic_Keyboard_2.0 -->
|
||||
<keymap
|
||||
name="ru"
|
||||
latched-name="Ru"
|
||||
locked-name="RU">
|
||||
label="ru"
|
||||
latched-label="Ru"
|
||||
locked-label="RU">
|
||||
<key code="29"> <!-- A -->
|
||||
<base value="a" />
|
||||
<shift value="A" />
|
||||
@@ -1278,9 +1278,9 @@
|
||||
<!-- This differs a bit from the above layout, because the Titan keyboard already has : under
|
||||
the alt key. The Q key is reused for diacritics. -->
|
||||
<keymap
|
||||
name="el"
|
||||
latched-name="El"
|
||||
locked-name="EL">
|
||||
label="el"
|
||||
latched-label="El"
|
||||
locked-label="EL">
|
||||
<key code="29"> <!-- A -->
|
||||
<base value="α" />
|
||||
<base value="ά" />
|
||||
@@ -1471,9 +1471,9 @@
|
||||
others are incomplete or not for *just* alphabetic QWERTY without extra keys. The characters
|
||||
are sorted by their frequency in the language. https://en.wikipedia.org/wiki/Arabic_letter_frequency -->
|
||||
<keymap
|
||||
name="ar"
|
||||
latched-name="Ar"
|
||||
locked-name="AR">
|
||||
label="ar"
|
||||
latched-label="Ar"
|
||||
locked-label="AR">
|
||||
<key code="29"> <!-- A -->
|
||||
<base value="ا" />
|
||||
<base value="أ" />
|
||||
|
||||
@@ -19,7 +19,7 @@
|
||||
|
||||
<input-method xmlns:android="http://schemas.android.com/apk/res/android"
|
||||
xmlns:tools="http://schemas.android.com/tools"
|
||||
android:settingsActivity="eur.cfpifpsi.titanboard.PreferenceActivity">
|
||||
android:settingsActivity="eur.cfpifpsi.titanboard.SettingsActivity">
|
||||
<!-- Needed for higher Android version so it can be the only used input method.
|
||||
None of these subtypes are actually used. -->
|
||||
<subtype
|
||||
|
||||
+1
-1
@@ -1,4 +1,4 @@
|
||||
// Top-level build file where you can add configuration options common to all sub-projects/modules.
|
||||
plugins {
|
||||
alias(libs.plugins.android.application) apply false
|
||||
alias(libs.plugins.android.application) apply false
|
||||
}
|
||||
+4
-4
@@ -2,9 +2,9 @@ pluginManagement {
|
||||
repositories {
|
||||
google {
|
||||
content {
|
||||
includeGroupByRegex("com\\.android.*")
|
||||
includeGroupByRegex("com\\.google.*")
|
||||
includeGroupByRegex("androidx.*")
|
||||
includeGroupByRegex('com\\.android.*')
|
||||
includeGroupByRegex('com\\.google.*')
|
||||
includeGroupByRegex('androidx.*')
|
||||
}
|
||||
}
|
||||
mavenCentral()
|
||||
@@ -19,5 +19,5 @@ dependencyResolutionManagement {
|
||||
}
|
||||
}
|
||||
|
||||
rootProject.name = "Titanboard"
|
||||
rootProject.name = 'Titanboard'
|
||||
include ':app'
|
||||
|
||||
Reference in New Issue
Block a user