Interface code improvements
This commit is contained in:
@@ -25,13 +25,10 @@ import android.content.ClipboardManager;
|
||||
import android.content.Context;
|
||||
import android.os.Build;
|
||||
|
||||
import java.util.ArrayList;
|
||||
|
||||
@TargetApi(Build.VERSION_CODES.HONEYCOMB)
|
||||
public class ClipboardHandler implements ClipboardManager.OnPrimaryClipChangedListener {
|
||||
private final static int MAX_CLIPS = 4;
|
||||
private final ArrayList<ClipData> mClips = new ArrayList<>();
|
||||
private final ClipboardManager mClipboardManager;
|
||||
private ClipData mCurrentClip;
|
||||
|
||||
public ClipboardHandler(Context ctx) {
|
||||
mClipboardManager = (ClipboardManager) ctx.getSystemService(Context.CLIPBOARD_SERVICE);
|
||||
@@ -39,6 +36,10 @@ public class ClipboardHandler implements ClipboardManager.OnPrimaryClipChangedLi
|
||||
|
||||
@Override
|
||||
public void onPrimaryClipChanged() {
|
||||
ClipData newClip = mClipboardManager.getPrimaryClip();
|
||||
mCurrentClip = mClipboardManager.getPrimaryClip();
|
||||
}
|
||||
|
||||
public ClipData getCurrentClip() {
|
||||
return mCurrentClip;
|
||||
}
|
||||
}
|
||||
|
||||
@@ -45,6 +45,7 @@ public class InputMethod extends InputMethodService {
|
||||
public MetaKeyManager mMetaKeyManager;
|
||||
public KeymapManager mKeymapManager;
|
||||
public PreferenceHolder mPreferenceHolder;
|
||||
private ClipboardHandler mClipboardHandler;
|
||||
private InputView mInputView;
|
||||
private int mCurrentCursorPosition;
|
||||
private Handler mHandler;
|
||||
@@ -58,6 +59,7 @@ public class InputMethod extends InputMethodService {
|
||||
mVibrator = (Vibrator) getSystemService(VIBRATOR_SERVICE);
|
||||
mMetaKeyManager = new MetaKeyManager(mVibrator);
|
||||
mKeymapManager = new KeymapManager(this);
|
||||
mClipboardHandler = new ClipboardHandler(this);
|
||||
mHandler = new Handler(Looper.getMainLooper());
|
||||
mSymbolCycler = new SymbolCycler();
|
||||
mKeymapManager.cycleKeymaps(mPreferenceHolder.getSelectedKeymaps());
|
||||
|
||||
@@ -25,10 +25,8 @@ import android.graphics.Paint;
|
||||
import android.graphics.Typeface;
|
||||
import android.os.Build;
|
||||
import android.util.AttributeSet;
|
||||
import android.util.TypedValue;
|
||||
import android.view.ContextThemeWrapper;
|
||||
import android.view.Gravity;
|
||||
import android.widget.Button;
|
||||
import android.widget.HorizontalScrollView;
|
||||
import android.widget.LinearLayout;
|
||||
import android.widget.RelativeLayout;
|
||||
import android.widget.TextView;
|
||||
@@ -40,13 +38,32 @@ import java.util.ArrayList;
|
||||
|
||||
public class InputView extends RelativeLayout {
|
||||
private final InputMethod mInputMethod;
|
||||
private final LinearLayout.LayoutParams mSymbolLayout;
|
||||
private final LinearLayout.LayoutParams mCandidateLayout;
|
||||
private LinearLayout mSymbolList;
|
||||
private LinearLayout mCandidateList;
|
||||
private Button mStateButton;
|
||||
private Button mClipboardButton;
|
||||
|
||||
public InputView(Context context, AttributeSet attrs) {
|
||||
super(context, attrs, 0);
|
||||
mInputMethod = (InputMethod) context;
|
||||
mSymbolLayout = new LinearLayout.LayoutParams(
|
||||
getResources().getDimensionPixelSize(R.dimen.symbol_width),
|
||||
LinearLayout.LayoutParams.MATCH_PARENT, 0);
|
||||
mCandidateLayout = new LinearLayout.LayoutParams(
|
||||
LinearLayout.LayoutParams.WRAP_CONTENT,
|
||||
LinearLayout.LayoutParams.MATCH_PARENT, 0);
|
||||
|
||||
mSymbolLayout.setMargins(0, 0,
|
||||
getResources().getDimensionPixelSize(R.dimen.default_space), 0);
|
||||
mCandidateLayout.setMargins(0, 0,
|
||||
getResources().getDimensionPixelSize(R.dimen.default_space), 0);
|
||||
|
||||
if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.JELLY_BEAN_MR1) {
|
||||
mSymbolLayout.setMarginEnd(getResources().getDimensionPixelSize(R.dimen.default_space));
|
||||
mCandidateLayout.setMarginEnd(getResources().getDimensionPixelSize(R.dimen.default_space));
|
||||
}
|
||||
}
|
||||
|
||||
@Override
|
||||
@@ -55,6 +72,10 @@ public class InputView extends RelativeLayout {
|
||||
mSymbolList = findViewById(R.id.symbol_list);
|
||||
mCandidateList = findViewById(R.id.candidate_list);
|
||||
mStateButton = findViewById(R.id.state_button);
|
||||
mClipboardButton = (Button) inflate(this.getContext(), R.layout.candidate, null);
|
||||
mClipboardButton.setTag(0);
|
||||
mClipboardButton.setLayoutParams(mCandidateLayout);
|
||||
mCandidateList.addView(mClipboardButton);
|
||||
|
||||
mStateButton.setOnClickListener(button -> {
|
||||
MetaKeyManager metaManager = mInputMethod.mMetaKeyManager;
|
||||
@@ -127,27 +148,13 @@ public class InputView extends RelativeLayout {
|
||||
* @param strings the strings to be displayed in the CyclerView
|
||||
*/
|
||||
public void prepareSymbols(ArrayList<String> strings) {
|
||||
ContextThemeWrapper ctw = new ContextThemeWrapper(this.getContext(), R.style.InputViewCandidate);
|
||||
LinearLayout.LayoutParams lp = new LinearLayout.LayoutParams(
|
||||
getResources().getDimensionPixelSize(R.dimen.view_symbol_width),
|
||||
LinearLayout.LayoutParams.MATCH_PARENT, 0);
|
||||
|
||||
lp.setMargins(0, 0,
|
||||
getResources().getDimensionPixelSize(R.dimen.view_default_space), 0);
|
||||
|
||||
if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.JELLY_BEAN_MR1) {
|
||||
lp.setMarginEnd(getResources().getDimensionPixelSize(R.dimen.view_default_space));
|
||||
}
|
||||
|
||||
for (int i = 0; i < strings.size(); ++i) {
|
||||
TextView tv = (TextView) mSymbolList.getChildAt(i);
|
||||
|
||||
if (tv == null) {
|
||||
tv = new TextView(ctw, null, 0);
|
||||
tv.setGravity(Gravity.CENTER);
|
||||
tv.setTextSize(TypedValue.COMPLEX_UNIT_PX,
|
||||
getResources().getDimensionPixelSize(R.dimen.view_default_text_size));
|
||||
tv.setLayoutParams(lp);
|
||||
tv = (TextView) inflate(this.getContext(), R.layout.symbol, null);
|
||||
tv.setTag(i);
|
||||
tv.setLayoutParams(mSymbolLayout);
|
||||
mSymbolList.addView(tv);
|
||||
}
|
||||
|
||||
@@ -165,8 +172,17 @@ public class InputView extends RelativeLayout {
|
||||
TextView tv = (TextView) mSymbolList.getChildAt(i);
|
||||
|
||||
if (i == index) {
|
||||
HorizontalScrollView hsw = findViewById(R.id.symbol_list_container);
|
||||
tv.setPressed(true);
|
||||
tv.setTypeface(null, Typeface.BOLD);
|
||||
// This, if the symbol list is larger than the scroll view, scrolls it just to show
|
||||
// the selected symbol at the very end. It isn't really necessary, as it's a rarity
|
||||
// that a key has more than five symbols, but perhaps someone will want to add a
|
||||
// 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
|
||||
- hsw.getRight(), 0);
|
||||
} else {
|
||||
tv.setPressed(false);
|
||||
tv.setTypeface(null, Typeface.NORMAL);
|
||||
|
||||
@@ -0,0 +1,29 @@
|
||||
<?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/>.
|
||||
~
|
||||
-->
|
||||
|
||||
<Button xmlns:android="http://schemas.android.com/apk/res/android"
|
||||
style="@style/InputViewCandidate"
|
||||
android:drawablePadding="@dimen/candidate_side_padding"
|
||||
android:ellipsize="end"
|
||||
android:maxWidth="@dimen/candidate_max_width"
|
||||
android:paddingLeft="@dimen/candidate_side_padding"
|
||||
android:paddingRight="@dimen/candidate_side_padding"
|
||||
android:singleLine="true">
|
||||
|
||||
</Button>
|
||||
@@ -22,20 +22,20 @@
|
||||
android:layout_width="match_parent"
|
||||
android:layout_height="wrap_content"
|
||||
android:layout_gravity="bottom"
|
||||
android:paddingLeft="@dimen/view_default_space"
|
||||
android:paddingTop="@dimen/view_default_space"
|
||||
android:paddingRight="@dimen/view_default_space">
|
||||
android:paddingLeft="@dimen/default_space"
|
||||
android:paddingTop="@dimen/default_space"
|
||||
android:paddingRight="@dimen/default_space">
|
||||
|
||||
<HorizontalScrollView
|
||||
android:id="@+id/symbol_list_container"
|
||||
android:layout_width="match_parent"
|
||||
android:layout_height="@dimen/view_container_height"
|
||||
android:layout_height="@dimen/container_height"
|
||||
android:layout_alignTop="@id/state_button"
|
||||
android:layout_marginEnd="@dimen/view_default_space"
|
||||
android:layout_marginRight="@dimen/view_default_space"
|
||||
android:layout_marginEnd="@dimen/default_space"
|
||||
android:layout_marginRight="@dimen/default_space"
|
||||
android:layout_marginBottom="0dp"
|
||||
android:layout_toStartOf="@+id/state_button"
|
||||
android:layout_toLeftOf="@+id/state_button"
|
||||
android:layout_toLeftOf="@id/state_button"
|
||||
android:visibility="gone">
|
||||
|
||||
<LinearLayout
|
||||
@@ -50,14 +50,13 @@
|
||||
<HorizontalScrollView
|
||||
android:id="@+id/candidate_list_container"
|
||||
android:layout_width="match_parent"
|
||||
android:layout_height="@dimen/view_container_height"
|
||||
android:layout_height="@dimen/container_height"
|
||||
android:layout_alignTop="@id/state_button"
|
||||
android:layout_marginEnd="@dimen/view_default_space"
|
||||
android:layout_marginRight="@dimen/view_default_space"
|
||||
android:layout_marginEnd="@dimen/default_space"
|
||||
android:layout_marginRight="@dimen/default_space"
|
||||
android:layout_marginBottom="0dp"
|
||||
android:layout_toStartOf="@+id/state_button"
|
||||
android:layout_toLeftOf="@+id/state_button"
|
||||
android:visibility="visible">
|
||||
android:layout_toLeftOf="@id/state_button">
|
||||
|
||||
<LinearLayout
|
||||
android:id="@+id/candidate_list"
|
||||
@@ -69,11 +68,11 @@
|
||||
<Button
|
||||
android:id="@+id/state_button"
|
||||
style="@style/InputViewButton"
|
||||
android:layout_width="@dimen/view_button_width"
|
||||
android:layout_height="@dimen/view_button_height"
|
||||
android:layout_width="@dimen/button_width"
|
||||
android:layout_height="@dimen/button_height"
|
||||
android:layout_alignParentEnd="true"
|
||||
android:layout_alignParentRight="true"
|
||||
android:text="@string/state_button_default"
|
||||
android:textSize="@dimen/view_default_text_size" />
|
||||
android:textSize="@dimen/default_text_size" />
|
||||
|
||||
</cfpi_fpsi.eu.titanboard.InputView>
|
||||
@@ -0,0 +1,25 @@
|
||||
<?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/>.
|
||||
~
|
||||
-->
|
||||
|
||||
<TextView xmlns:android="http://schemas.android.com/apk/res/android"
|
||||
style="@style/InputViewCandidate"
|
||||
android:gravity="center"
|
||||
android:textSize="@dimen/default_text_size">
|
||||
|
||||
</TextView>
|
||||
@@ -19,6 +19,7 @@
|
||||
|
||||
<resources>
|
||||
<string-array name="preferences_keymap_labels">
|
||||
<item>Test</item>
|
||||
<item>English</item>
|
||||
<item>German</item>
|
||||
<item>French</item>
|
||||
@@ -31,6 +32,7 @@
|
||||
</string-array>
|
||||
|
||||
<string-array name="preferences_keymaps">
|
||||
<item>tt</item>
|
||||
<item>en</item>
|
||||
<item>de</item>
|
||||
<item>fr</item>
|
||||
|
||||
@@ -18,10 +18,12 @@
|
||||
-->
|
||||
|
||||
<resources>
|
||||
<dimen name="view_default_space">8dp</dimen>
|
||||
<dimen name="view_container_height">56dp</dimen>
|
||||
<dimen name="view_button_width">48dp</dimen>
|
||||
<dimen name="view_button_height">48dp</dimen>
|
||||
<dimen name="view_symbol_width">40dp</dimen>
|
||||
<dimen name="view_default_text_size">18sp</dimen>
|
||||
<dimen name="default_space">8dp</dimen>
|
||||
<dimen name="container_height">56dp</dimen>
|
||||
<dimen name="button_width">48dp</dimen>
|
||||
<dimen name="button_height">48dp</dimen>
|
||||
<dimen name="candidate_max_width">196dp</dimen>
|
||||
<dimen name="candidate_side_padding">12dp</dimen>
|
||||
<dimen name="symbol_width">40dp</dimen>
|
||||
<dimen name="default_text_size">18sp</dimen>
|
||||
</resources>
|
||||
@@ -18,6 +18,27 @@
|
||||
-->
|
||||
|
||||
<device-keymap-list>
|
||||
<!-- Test keymap -->
|
||||
<keymap
|
||||
name="tt"
|
||||
latched-name="Tt"
|
||||
locked-name="TT">
|
||||
<key code="29">
|
||||
<base value="a" />
|
||||
<base value="b" />
|
||||
<base value="c" />
|
||||
<base value="d" />
|
||||
<base value="e" />
|
||||
<base value="f" />
|
||||
<base value="g" />
|
||||
<base value="h" />
|
||||
<base value="i" />
|
||||
<base value="j" />
|
||||
<base value="k" />
|
||||
<base value="l" />
|
||||
<base value="o" />
|
||||
</key>
|
||||
</keymap>
|
||||
<!-- English -->
|
||||
<keymap
|
||||
name="en"
|
||||
|
||||
Reference in New Issue
Block a user