add more keys to clipboard toolbar

This commit is contained in:
Helium314 2023-12-21 21:57:53 +01:00
parent 461eb2a551
commit dfa3a568be
4 changed files with 117 additions and 101 deletions

View file

@ -15,6 +15,7 @@ import android.view.LayoutInflater;
import android.view.View;
import android.view.inputmethod.EditorInfo;
import android.view.inputmethod.InputMethodSubtype;
import android.widget.LinearLayout;
import androidx.annotation.NonNull;
@ -47,7 +48,7 @@ public final class KeyboardSwitcher implements KeyboardState.SwitchActions {
private MainKeyboardView mKeyboardView;
private EmojiPalettesView mEmojiPalettesView;
private View mEmojiTabStripView;
private View mClipboardStripView;
private LinearLayout mClipboardStripView;
private View mSuggestionStripView;
private ClipboardHistoryView mClipboardHistoryView;
private LatinIME mLatinIME;
@ -530,7 +531,7 @@ public final class KeyboardSwitcher implements KeyboardState.SwitchActions {
return mEmojiTabStripView;
}
public View getClipboardStrip() {
public LinearLayout getClipboardStrip() {
return mClipboardStripView;
}

View file

@ -24,6 +24,13 @@ import org.dslul.openboard.inputmethod.latin.common.ColorType
import org.dslul.openboard.inputmethod.latin.common.Constants
import org.dslul.openboard.inputmethod.latin.settings.Settings
import org.dslul.openboard.inputmethod.latin.utils.ResourceUtils
import org.dslul.openboard.inputmethod.latin.utils.TAG_CLEAR_CLIPBOARD
import org.dslul.openboard.inputmethod.latin.utils.TAG_COPY
import org.dslul.openboard.inputmethod.latin.utils.TAG_LEFT
import org.dslul.openboard.inputmethod.latin.utils.TAG_RIGHT
import org.dslul.openboard.inputmethod.latin.utils.TAG_SELECT_ALL
import org.dslul.openboard.inputmethod.latin.utils.createToolbarKey
import org.dslul.openboard.inputmethod.latin.utils.getCodeForTag
class ClipboardHistoryView @JvmOverloads constructor(
context: Context,
@ -41,7 +48,7 @@ class ClipboardHistoryView @JvmOverloads constructor(
private lateinit var clipboardRecyclerView: ClipboardHistoryRecyclerView
private lateinit var placeholderView: TextView
private lateinit var alphabetKey: TextView
private lateinit var clearKey: ImageButton
private val toolbarKeys = mutableListOf<ImageButton>()
private lateinit var clipboardAdapter: ClipboardAdapter
private lateinit var spacebar: View
private lateinit var deleteKey: ImageButton
@ -57,8 +64,12 @@ class ClipboardHistoryView @JvmOverloads constructor(
val keyboardViewAttr = context.obtainStyledAttributes(attrs, R.styleable.KeyboardView, defStyle, R.style.KeyboardView)
keyBackgroundId = keyboardViewAttr.getResourceId(R.styleable.KeyboardView_keyBackground, 0)
functionalKeyBackgroundId = keyboardViewAttr.getResourceId(R.styleable.KeyboardView_functionalKeyBackground, keyBackgroundId)
spacebarBackground = Settings.getInstance().current.mColors.selectAndColorDrawable(keyboardViewAttr, ColorType.SPACE_BAR_BACKGROUND);
spacebarBackground = Settings.getInstance().current.mColors.selectAndColorDrawable(keyboardViewAttr, ColorType.SPACE_BAR_BACKGROUND)
keyboardViewAttr.recycle()
val keyboardAttr = context.obtainStyledAttributes(attrs, R.styleable.Keyboard, defStyle, R.style.SuggestionStripView)
val toolbarKeyTags = listOf(TAG_LEFT, TAG_RIGHT, TAG_COPY, TAG_SELECT_ALL, TAG_CLEAR_CLIPBOARD)
toolbarKeyTags.forEach { toolbarKeys.add(createToolbarKey(context, keyboardAttr, it)) }
keyboardAttr.recycle()
}
override fun onMeasure(widthMeasureSpec: Int, heightMeasureSpec: Int) {
@ -104,12 +115,14 @@ class ClipboardHistoryView @JvmOverloads constructor(
spacebar.setOnClickListener(this)
// todo: add more buttons, like select all, arrow keys, copy, clear (and maybe start/end select?)
val clipboardStrip = KeyboardSwitcher.getInstance().clipboardStrip
colors.setBackground(clipboardStrip, ColorType.EMOJI_CATEGORY_BACKGROUND) // todo: choose a color
clearKey = clipboardStrip.findViewById(R.id.clipboard_clear)
clearKey.setOnTouchListener(this@ClipboardHistoryView)
clearKey.setOnClickListener(this@ClipboardHistoryView)
colors.setColor(clearKey, ColorType.CLEAR_CLIPBOARD_HISTORY_KEY)
colors.setBackground(clearKey, ColorType.CLEAR_CLIPBOARD_HISTORY_KEY)
toolbarKeys.forEach {
clipboardStrip.addView(it)
it.setOnTouchListener(this@ClipboardHistoryView)
it.setOnClickListener(this@ClipboardHistoryView)
colors.setColor(it, ColorType.CLEAR_CLIPBOARD_HISTORY_KEY)
colors.setBackground(it, ColorType.CLEAR_CLIPBOARD_HISTORY_KEY)
}
colors.setBackground(clipboardStrip, ColorType.BACKGROUND)
}
private fun setupAlphabetKey(key: TextView, label: String, params: KeyDrawParams) {
@ -139,9 +152,10 @@ class ClipboardHistoryView @JvmOverloads constructor(
}
}
private fun setupClearKey(iconSet: KeyboardIconsSet) {
val resId = iconSet.getIconResourceId(KeyboardIconsSet.NAME_CLEAR_CLIPBOARD_KEY)
clearKey.setImageResource(resId)
private fun setupToolbarKeys() {
// set layout params
val toolbarKeyLayoutParams = LayoutParams(getResources().getDimensionPixelSize(R.dimen.config_suggestions_strip_edge_key_width), LayoutParams.MATCH_PARENT)
toolbarKeys.forEach { it.layoutParams = toolbarKeyLayoutParams }
}
fun setHardwareAcceleratedDrawingEnabled(enabled: Boolean) {
@ -156,6 +170,7 @@ class ClipboardHistoryView @JvmOverloads constructor(
keyVisualAttr: KeyVisualAttributes?,
iconSet: KeyboardIconsSet
) {
setupToolbarKeys()
historyManager.prepareClipboardHistory()
historyManager.setHistoryChangeListener(this)
clipboardHistoryManager = historyManager
@ -169,7 +184,6 @@ class ClipboardHistoryView @JvmOverloads constructor(
setupAlphabetKey(alphabetKey, switchToAlphaLabel, params)
setupDeleteKey(deleteKey, iconSet.getIconResourceId(KeyboardIconsSet.NAME_DELETE_KEY))
setupClipKey(params)
setupClearKey(iconSet)
placeholderView.apply {
typeface = params.mTypeface
@ -197,7 +211,6 @@ class ClipboardHistoryView @JvmOverloads constructor(
}
when (view) {
alphabetKey, spacebar, deleteKey -> keyboardActionListener?.onPressKey(view.tag as Int, 0, true)
clearKey -> keyboardActionListener?.onPressKey(Constants.CODE_UNSPECIFIED, 0, true)
}
// It's important to return false here. Otherwise, {@link #onClick} and touch-down visual
// feedback stop working.
@ -211,10 +224,16 @@ class ClipboardHistoryView @JvmOverloads constructor(
Constants.NOT_A_COORDINATE, Constants.NOT_A_COORDINATE, false)
keyboardActionListener?.onReleaseKey(view.tag as Int, false)
}
clearKey -> {
clipboardHistoryManager?.clearHistory()
keyboardActionListener?.onReleaseKey(Constants.CODE_UNSPECIFIED, false)
}
val tag = view.tag
if (tag is String) {
val code = getCodeForTag(tag)
if (code != null) {
keyboardActionListener?.onCodeInput(code, Constants.NOT_A_COORDINATE, Constants.NOT_A_COORDINATE, false)
return
}
if (tag == TAG_CLEAR_CLIPBOARD)
clipboardHistoryManager?.clearHistory()
}
}

View file

@ -6,6 +6,8 @@
package org.dslul.openboard.inputmethod.latin.suggestions;
import static org.dslul.openboard.inputmethod.latin.utils.ToolbarUtilsKt.*;
import android.annotation.SuppressLint;
import android.app.KeyguardManager;
import android.content.ClipData;
@ -34,7 +36,6 @@ import android.view.ViewGroup;
import android.view.ViewParent;
import android.view.accessibility.AccessibilityEvent;
import android.widget.ImageButton;
import android.widget.ImageView;
import android.widget.LinearLayout;
import android.widget.RelativeLayout;
import android.widget.TextView;
@ -76,18 +77,6 @@ public final class SuggestionStripView extends RelativeLayout implements OnClick
public static boolean DEBUG_SUGGESTIONS;
private static final float DEBUG_INFO_TEXT_SIZE_IN_DIP = 6.5f;
private static final String TAG_VOICE = "voice_key";
private static final String TAG_CLIPBOARD = "clipboard_key";
private static final String TAG_SETTINGS = "settings_key";
private static final String TAG_SELECT_ALL = "select_all_key";
private static final String TAG_COPY = "copy_key";
private static final String TAG_ONE_HANDED = "one_handed_key";
private static final String TAG_LEFT = "left_key";
private static final String TAG_RIGHT = "right_key";
private static final String TAG_UP = "up_key";
private static final String TAG_DOWN = "down_key";
private static final String TAG_REDO = "undo";
private static final String TAG_UNDO = "redo";
// tags of keys to be added to toolbar, in order (all tags must be considered in getStyleableIconId)
private static final String[] toolbarKeyTags = new String[] {TAG_VOICE, TAG_CLIPBOARD,
TAG_SELECT_ALL, TAG_COPY, TAG_UNDO, TAG_REDO, TAG_ONE_HANDED, TAG_SETTINGS,
@ -151,8 +140,7 @@ public final class SuggestionStripView extends RelativeLayout implements OnClick
this(context, attrs, R.attr.suggestionStripViewStyle);
}
public SuggestionStripView(final Context context, final AttributeSet attrs,
final int defStyle) {
public SuggestionStripView(final Context context, final AttributeSet attrs, final int defStyle) {
super(context, attrs, defStyle);
final Colors colors = Settings.getInstance().getCurrent().mColors;
DEBUG_SUGGESTIONS = DeviceProtectedUtils.getSharedPreferences(context).getBoolean(DebugSettings.PREF_SHOW_SUGGESTION_INFOS, false);
@ -203,18 +191,8 @@ public final class SuggestionStripView extends RelativeLayout implements OnClick
LinearLayout.LayoutParams.MATCH_PARENT
);
for (final String tag : toolbarKeyTags) {
final ImageButton button = new ImageButton(getContext(), null, R.attr.suggestionWordStyle);
button.setScaleType(ImageView.ScaleType.CENTER);
final ImageButton button = createToolbarKey(context, keyboardAttr, tag);
button.setLayoutParams(toolbarKeyLayoutParams);
button.setTag(tag);
final Drawable icon = keyboardAttr.getDrawable(getStyleableIconId(tag));
if (tag.equals(TAG_LEFT) || tag.equals(TAG_RIGHT) || tag.equals(TAG_UP) || tag.equals(TAG_DOWN)) {
// arrows look a little awkward when not scaled
button.setScaleX(1.2f);
button.setScaleY(1.2f);
}
button.setImageDrawable(icon);
setupKey(button, colors);
mToolbar.addView(button);
}
keyboardAttr.recycle();
@ -625,45 +603,10 @@ public final class SuggestionStripView extends RelativeLayout implements OnClick
AudioAndHapticFeedbackManager.getInstance().performHapticAndAudioFeedback(Constants.CODE_UNSPECIFIED, this);
final Object tag = view.getTag();
if (tag instanceof String) {
switch ((String) tag) {
case TAG_VOICE:
mListener.onCodeInput(Constants.CODE_SHORTCUT, Constants.SUGGESTION_STRIP_COORDINATE, Constants.SUGGESTION_STRIP_COORDINATE, false);
return;
case TAG_CLIPBOARD:
mListener.onCodeInput(Constants.CODE_CLIPBOARD, Constants.SUGGESTION_STRIP_COORDINATE, Constants.SUGGESTION_STRIP_COORDINATE, false);
return;
case TAG_SELECT_ALL:
mListener.onCodeInput(Constants.CODE_SELECT_ALL, Constants.SUGGESTION_STRIP_COORDINATE, Constants.SUGGESTION_STRIP_COORDINATE, false);
return;
case TAG_COPY:
mListener.onCodeInput(Constants.CODE_COPY, Constants.SUGGESTION_STRIP_COORDINATE, Constants.SUGGESTION_STRIP_COORDINATE, false);
return;
case TAG_ONE_HANDED:
final boolean oneHandedEnabled = Settings.getInstance().getCurrent().mOneHandedModeEnabled;
mListener.onCodeInput(oneHandedEnabled ? Constants.CODE_STOP_ONE_HANDED_MODE : Constants.CODE_START_ONE_HANDED_MODE,
Constants.SUGGESTION_STRIP_COORDINATE, Constants.SUGGESTION_STRIP_COORDINATE, false);
return;
case TAG_SETTINGS:
mListener.onCodeInput(Constants.CODE_SETTINGS, Constants.SUGGESTION_STRIP_COORDINATE, Constants.SUGGESTION_STRIP_COORDINATE, false);
return;
case TAG_LEFT:
mListener.onCodeInput(Constants.CODE_LEFT, Constants.SUGGESTION_STRIP_COORDINATE, Constants.SUGGESTION_STRIP_COORDINATE, false);
return;
case TAG_RIGHT:
mListener.onCodeInput(Constants.CODE_RIGHT, Constants.SUGGESTION_STRIP_COORDINATE, Constants.SUGGESTION_STRIP_COORDINATE, false);
return;
case TAG_UP:
mListener.onCodeInput(Constants.CODE_UP, Constants.SUGGESTION_STRIP_COORDINATE, Constants.SUGGESTION_STRIP_COORDINATE, false);
return;
case TAG_DOWN:
mListener.onCodeInput(Constants.CODE_DOWN, Constants.SUGGESTION_STRIP_COORDINATE, Constants.SUGGESTION_STRIP_COORDINATE, false);
return;
case TAG_UNDO:
mListener.onCodeInput(Constants.CODE_UNDO, Constants.SUGGESTION_STRIP_COORDINATE, Constants.SUGGESTION_STRIP_COORDINATE, false);
return;
case TAG_REDO:
mListener.onCodeInput(Constants.CODE_REDO, Constants.SUGGESTION_STRIP_COORDINATE, Constants.SUGGESTION_STRIP_COORDINATE, false);
return;
final Integer code = getCodeForTag((String) tag);
if (code != null) {
mListener.onCodeInput(code, Constants.SUGGESTION_STRIP_COORDINATE, Constants.SUGGESTION_STRIP_COORDINATE, false);
return;
}
}
if (view == mToolbarKey) {
@ -730,22 +673,4 @@ public final class SuggestionStripView extends RelativeLayout implements OnClick
colors.setColor(view, ColorType.TOOL_BAR_KEY);
colors.setBackground(view, ColorType.SUGGESTION_BACKGROUND);
}
private int getStyleableIconId(final String buttonTag) {
return switch (buttonTag) {
case TAG_VOICE -> R.styleable.Keyboard_iconShortcutKey;
case TAG_SETTINGS -> R.styleable.Keyboard_iconSettingsKey;
case TAG_CLIPBOARD -> R.styleable.Keyboard_iconClipboardNormalKey;
case TAG_SELECT_ALL -> R.styleable.Keyboard_iconSelectAll;
case TAG_COPY -> R.styleable.Keyboard_iconCopyKey;
case TAG_ONE_HANDED -> R.styleable.Keyboard_iconStartOneHandedMode;
case TAG_LEFT -> R.styleable.Keyboard_iconArrowLeft;
case TAG_RIGHT -> R.styleable.Keyboard_iconArrowRight;
case TAG_UP -> R.styleable.Keyboard_iconArrowUp;
case TAG_DOWN -> R.styleable.Keyboard_iconArrowDown;
case TAG_UNDO -> R.styleable.Keyboard_iconUndo;
case TAG_REDO -> R.styleable.Keyboard_iconRedo;
default -> throw (new IllegalArgumentException("no styleable id for " + buttonTag));
};
}
}

View file

@ -0,0 +1,71 @@
package org.dslul.openboard.inputmethod.latin.utils
import android.content.Context
import android.content.res.TypedArray
import android.widget.ImageButton
import android.widget.ImageView
import org.dslul.openboard.inputmethod.latin.R
import org.dslul.openboard.inputmethod.latin.common.Constants.*
import org.dslul.openboard.inputmethod.latin.settings.Settings
fun createToolbarKey(context: Context, keyboardAttr: TypedArray, tag: String): ImageButton {
val button = ImageButton(context, null, R.attr.suggestionWordStyle)
button.scaleType = ImageView.ScaleType.CENTER
button.tag = tag
val icon = keyboardAttr.getDrawable(getStyleableIconId(tag))
if (tag == TAG_LEFT || tag == TAG_RIGHT || tag == TAG_UP || tag == TAG_DOWN) {
// arrows look a little awkward when not scaled
button.scaleX = 1.2f
button.scaleY = 1.2f
}
button.setImageDrawable(icon)
return button
}
fun getCodeForTag(tag: String) = when (tag) {
TAG_VOICE -> CODE_SHORTCUT
TAG_SETTINGS -> CODE_SETTINGS
TAG_CLIPBOARD -> CODE_CLIPBOARD
TAG_SELECT_ALL -> CODE_SELECT_ALL
TAG_COPY -> CODE_COPY
TAG_ONE_HANDED -> if (Settings.getInstance().current.mOneHandedModeEnabled) CODE_START_ONE_HANDED_MODE else CODE_STOP_ONE_HANDED_MODE
TAG_LEFT -> CODE_LEFT
TAG_RIGHT -> CODE_RIGHT
TAG_UP -> CODE_UP
TAG_DOWN -> CODE_DOWN
TAG_UNDO -> CODE_UNDO
TAG_REDO -> CODE_REDO
TAG_CLEAR_CLIPBOARD -> null // not managed via code input
else -> null
}
private fun getStyleableIconId(tag: String) = when (tag) {
TAG_VOICE -> R.styleable.Keyboard_iconShortcutKey
TAG_SETTINGS -> R.styleable.Keyboard_iconSettingsKey
TAG_CLIPBOARD -> R.styleable.Keyboard_iconClipboardNormalKey
TAG_SELECT_ALL -> R.styleable.Keyboard_iconSelectAll
TAG_COPY -> R.styleable.Keyboard_iconCopyKey
TAG_ONE_HANDED -> R.styleable.Keyboard_iconStartOneHandedMode
TAG_LEFT -> R.styleable.Keyboard_iconArrowLeft
TAG_RIGHT -> R.styleable.Keyboard_iconArrowRight
TAG_UP -> R.styleable.Keyboard_iconArrowUp
TAG_DOWN -> R.styleable.Keyboard_iconArrowDown
TAG_UNDO -> R.styleable.Keyboard_iconUndo
TAG_REDO -> R.styleable.Keyboard_iconRedo
TAG_CLEAR_CLIPBOARD -> R.styleable.Keyboard_iconClearClipboardKey
else -> throw IllegalArgumentException("no styleable id for $tag")
}
const val TAG_VOICE = "voice_key"
const val TAG_CLIPBOARD = "clipboard_key"
const val TAG_CLEAR_CLIPBOARD = "clear_clipboard"
const val TAG_SETTINGS = "settings_key"
const val TAG_SELECT_ALL = "select_all_key"
const val TAG_COPY = "copy_key"
const val TAG_ONE_HANDED = "one_handed_key"
const val TAG_LEFT = "left_key"
const val TAG_RIGHT = "right_key"
const val TAG_UP = "up_key"
const val TAG_DOWN = "down_key"
const val TAG_REDO = "undo"
const val TAG_UNDO = "redo"