Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

new pinned toolbar & history view keys long press functions #691

Merged
merged 10 commits into from
May 1, 2024
Merged
Original file line number Diff line number Diff line change
Expand Up @@ -16,6 +16,7 @@
import android.view.View;
import android.view.inputmethod.EditorInfo;
import android.view.inputmethod.InputMethodSubtype;
import android.widget.HorizontalScrollView;
import android.widget.LinearLayout;

import androidx.annotation.NonNull;
Expand Down Expand Up @@ -49,6 +50,7 @@ public final class KeyboardSwitcher implements KeyboardState.SwitchActions {
private EmojiPalettesView mEmojiPalettesView;
private View mEmojiTabStripView;
private LinearLayout mClipboardStripView;
private HorizontalScrollView mClipboardStripScrollView;
private View mSuggestionStripView;
private ClipboardHistoryView mClipboardHistoryView;
private LatinIME mLatinIME;
Expand Down Expand Up @@ -280,7 +282,7 @@ private void setMainKeyboardFrame(
mEmojiPalettesView.setVisibility(View.GONE);
mEmojiPalettesView.stopEmojiPalettes();
mEmojiTabStripView.setVisibility(View.GONE);
mClipboardStripView.setVisibility(View.GONE);
mClipboardStripScrollView.setVisibility(View.GONE);
mSuggestionStripView.setVisibility(View.VISIBLE);
mClipboardHistoryView.setVisibility(View.GONE);
mClipboardHistoryView.stopClipboardHistory();
Expand All @@ -299,7 +301,7 @@ public void setEmojiKeyboard() {
// @see LatinIME#onComputeInset(android.inputmethodservice.InputMethodService.Insets)
mKeyboardView.setVisibility(View.GONE);
mSuggestionStripView.setVisibility(View.GONE);
mClipboardStripView.setVisibility(View.GONE);
mClipboardStripScrollView.setVisibility(View.GONE);
mEmojiTabStripView.setVisibility(View.VISIBLE);
mClipboardHistoryView.setVisibility(View.GONE);
mEmojiPalettesView.startEmojiPalettes(
Expand All @@ -322,7 +324,8 @@ public void setClipboardKeyboard() {
mKeyboardView.setVisibility(View.GONE);
mEmojiTabStripView.setVisibility(View.GONE);
mSuggestionStripView.setVisibility(View.GONE);
mClipboardStripView.setVisibility(View.VISIBLE);
mClipboardStripScrollView.post(() -> mClipboardStripScrollView.fullScroll(HorizontalScrollView.FOCUS_RIGHT));
mClipboardStripScrollView.setVisibility(View.VISIBLE);
mEmojiPalettesView.setVisibility(View.GONE);
mClipboardHistoryView.startClipboardHistory(
mLatinIME.getClipboardHistoryManager(),
Expand Down Expand Up @@ -571,6 +574,7 @@ public View onCreateInputView(@NonNull Context displayContext, final boolean isH
mClipboardHistoryView.setKeyboardActionListener(mLatinIME.mKeyboardActionListener);
mEmojiTabStripView = mCurrentInputView.findViewById(R.id.emoji_tab_strip);
mClipboardStripView = mCurrentInputView.findViewById(R.id.clipboard_strip);
mClipboardStripScrollView = mCurrentInputView.findViewById(R.id.clipboard_strip_scroll_view);
mSuggestionStripView = mCurrentInputView.findViewById(R.id.suggestion_strip_view);

return mCurrentInputView;
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -28,13 +28,14 @@ import helium314.keyboard.latin.utils.ResourceUtils
import helium314.keyboard.latin.utils.ToolbarKey
import helium314.keyboard.latin.utils.createToolbarKey
import helium314.keyboard.latin.utils.getCodeForToolbarKey
import helium314.keyboard.latin.utils.getCodeForToolbarKeyLongClick

class ClipboardHistoryView @JvmOverloads constructor(
context: Context,
attrs: AttributeSet?,
defStyle: Int = R.attr.clipboardHistoryViewStyle
) : LinearLayout(context, attrs, defStyle), View.OnTouchListener, View.OnClickListener,
ClipboardHistoryManager.OnHistoryChangeListener, OnKeyEventListener {
ClipboardHistoryManager.OnHistoryChangeListener, OnKeyEventListener, View.OnLongClickListener {

private val clipboardLayoutParams = ClipboardLayoutParams(context.resources)
private val pinIconId: Int
Expand Down Expand Up @@ -69,7 +70,7 @@ class ClipboardHistoryView @JvmOverloads constructor(
// even when state is activated, the not activated color is set
// in suggestionStripView the same thing works correctly, wtf?
// need to properly fix it (and maybe undo the inverted isActivated) when adding a toggle key
listOf(ToolbarKey.LEFT, ToolbarKey.RIGHT, ToolbarKey.COPY, ToolbarKey.CUT, ToolbarKey.CLEAR_CLIPBOARD, ToolbarKey.SELECT_WORD, ToolbarKey.SELECT_ALL, ToolbarKey.CLOSE_HISTORY)
listOf(ToolbarKey.ONE_HANDED, ToolbarKey.UNDO, ToolbarKey.UP, ToolbarKey.DOWN, ToolbarKey.LEFT, ToolbarKey.RIGHT, ToolbarKey.CLEAR_CLIPBOARD, ToolbarKey.COPY, ToolbarKey.CUT, ToolbarKey.SELECT_WORD, ToolbarKey.CLOSE_HISTORY)
.forEach { toolbarKeys.add(createToolbarKey(context, keyboardAttr, it)) }
keyboardAttr.recycle()
}
Expand Down Expand Up @@ -121,6 +122,7 @@ class ClipboardHistoryView @JvmOverloads constructor(
clipboardStrip.addView(it)
it.setOnTouchListener(this@ClipboardHistoryView)
it.setOnClickListener(this@ClipboardHistoryView)
it.setOnLongClickListener(this@ClipboardHistoryView)
colors.setColor(it, ColorType.TOOL_BAR_KEY)
colors.setBackground(it, ColorType.STRIP_BACKGROUND)
}
Expand Down Expand Up @@ -240,6 +242,22 @@ class ClipboardHistoryView @JvmOverloads constructor(
}
}

override fun onLongClick(view: View): Boolean {
val tag = view.tag
if (tag is ToolbarKey) {
val longClickCode = getCodeForToolbarKeyLongClick(tag)
if (longClickCode != KeyCode.UNSPECIFIED) {
keyboardActionListener?.onCodeInput(
longClickCode,
Constants.SUGGESTION_STRIP_COORDINATE,
Constants.SUGGESTION_STRIP_COORDINATE,
codokie marked this conversation as resolved.
Show resolved Hide resolved
false
)
}
}
return true
codokie marked this conversation as resolved.
Show resolved Hide resolved
}

override fun onKeyDown(clipId: Long) {
keyboardActionListener?.onPressKey(KeyCode.NOT_SPECIFIED, 0, true)
}
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -131,6 +131,9 @@ object KeyCode {
const val ACTION_PREVIOUS = -10007
// Code value representing the code is not specified.
const val NOT_SPECIFIED = -10008 // todo: not sure if there is need to have the "old" unspecified keyCode different, just test it and maybe merge
const val CLIPBOARD_COPY_ALL = -10009
const val MOVE_PAGE_UP = -10010
const val MOVE_PAGE_DOWN = -10011
codokie marked this conversation as resolved.
Show resolved Hide resolved

/** to make sure a FlorisBoard code works when reading a JSON layout */
fun Int.checkAndConvertCode(): Int = if (this > 0) this else when (this) {
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -670,6 +670,16 @@ public void copyText() {
cm.setPrimaryClip(ClipData.newPlainText("copied text", text));
}

public void copyAllText() {
final CharSequence beforeText = getTextBeforeCursor(Integer.MAX_VALUE, InputConnection.GET_TEXT_WITH_STYLES);
final CharSequence afterText = getTextAfterCursor(Integer.MAX_VALUE, InputConnection.GET_TEXT_WITH_STYLES);
if (beforeText == null || afterText == null) return;
final String allText = beforeText + afterText.toString();
if (allText.isEmpty()) return;
final ClipboardManager cm = (ClipboardManager) mParent.getSystemService(Context.CLIPBOARD_SERVICE);
cm.setPrimaryClip(ClipData.newPlainText("copied text", allText));
}

public void commitCorrection(final CorrectionInfo correctionInfo) {
if (DEBUG_BATCH_NESTING) checkBatchEdit();
if (DEBUG_PREVIOUS_TEXT) checkConsistencyForDebug();
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -636,6 +636,21 @@ private void handleConsumedEvent(final Event event, final InputTransaction input
}
}

/**
* Handles the action of pasting content from the clipboard.
* Retrieves content from the clipboard history manager and commits it to the input connection.
* Sets a flag in the input transaction to indicate that the operation has affected the input contents.
*
* @param inputTransaction The transaction in progress.
*/
private void handleClipboardPaste(final InputTransaction inputTransaction) {
final CharSequence clipboardContent = mLatinIME.getClipboardHistoryManager().retrieveClipboardContent();
if (!TextUtils.isEmpty(clipboardContent)) {
mConnection.commitText(clipboardContent, 1);
inputTransaction.setDidAffectContents();
}
}

/**
* Handle a functional key event.
* <p>
Expand Down Expand Up @@ -685,14 +700,12 @@ private void handleFunctionalEvent(final Event event, final InputTransaction inp
// is being handled in {@link KeyboardState#onEvent(Event,int)}.
// If disabled, current clipboard content is committed.
if (!inputTransaction.getMSettingsValues().mClipboardHistoryEnabled) {
final CharSequence content = mLatinIME.getClipboardHistoryManager()
.retrieveClipboardContent();
if (!TextUtils.isEmpty(content)) {
mConnection.commitText(content, 1);
inputTransaction.setDidAffectContents();
}
handleClipboardPaste(inputTransaction);
}
break;
case KeyCode.CLIPBOARD_PASTE:
handleClipboardPaste(inputTransaction);
break;
case KeyCode.SHIFT_ENTER:
final Event tmpEvent = Event.createSoftwareKeypressEvent(Constants.CODE_ENTER,
event.getMKeyCode(), event.getMX(), event.getMY(), event.isKeyRepeat());
Expand All @@ -716,6 +729,9 @@ private void handleFunctionalEvent(final Event event, final InputTransaction inp
case KeyCode.CLIPBOARD_COPY:
mConnection.copyText();
break;
case KeyCode.CLIPBOARD_COPY_ALL:
mConnection.copyAllText();
break;
case KeyCode.CLIPBOARD_CUT:
if (mConnection.hasSelection()) {
mConnection.copyText();
Expand Down Expand Up @@ -750,6 +766,12 @@ private void handleFunctionalEvent(final Event event, final InputTransaction inp
case KeyCode.MOVE_END_OF_LINE:
sendDownUpKeyEvent(KeyEvent.KEYCODE_MOVE_END);
break;
case KeyCode.MOVE_PAGE_UP:
sendDownUpKeyEvent(KeyEvent.KEYCODE_PAGE_UP);
break;
case KeyCode.MOVE_PAGE_DOWN:
sendDownUpKeyEvent(KeyEvent.KEYCODE_PAGE_DOWN);
break;
case KeyCode.VOICE_INPUT:
// switching to shortcut IME, shift state, keyboard,... is handled by LatinIME,
// {@link KeyboardSwitcher#onEvent(Event)}, or {@link #onPressKey(int,int,boolean)} and {@link #onReleaseKey(int,boolean)}.
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -10,8 +10,6 @@

import android.annotation.SuppressLint;
import android.app.KeyguardManager;
import android.content.ClipData;
import android.content.ClipboardManager;
import android.content.Context;
import android.content.SharedPreferences;
import android.content.res.Resources;
Expand Down Expand Up @@ -375,10 +373,13 @@ public boolean onLongClick(final View view) {
}

private void onLongClickToolKey(final View view) {
if (ToolbarKey.CLIPBOARD == view.getTag() && view.getParent() == mPinnedKeys) {
onLongClickClipboardKey(); // long click pinned clipboard key
final ToolbarKey tag = (ToolbarKey) view.getTag();
codokie marked this conversation as resolved.
Show resolved Hide resolved
if (view.getParent() == mPinnedKeys) {
final int longClickCode = getCodeForToolbarKeyLongClick(tag);
if (longClickCode != KeyCode.UNSPECIFIED) {
mListener.onCodeInput(longClickCode, Constants.SUGGESTION_STRIP_COORDINATE, Constants.SUGGESTION_STRIP_COORDINATE, false);
}
} else if (view.getParent() == mToolbar) {
final ToolbarKey tag = (ToolbarKey) view.getTag();
final View pinnedKeyView = mPinnedKeys.findViewWithTag(tag);
if (pinnedKeyView == null) {
addKeyToPinnedKeys(tag);
Expand All @@ -392,22 +393,6 @@ private void onLongClickToolKey(final View view) {
}
}

private void onLongClickClipboardKey() {
ClipboardManager clipboardManager = (ClipboardManager) getContext().getSystemService(Context.CLIPBOARD_SERVICE);
ClipData clipData = clipboardManager.getPrimaryClip();
Log.d(TAG, "long click clipboard key");
if (clipData != null && clipData.getItemCount() > 0 && clipData.getItemAt(0) != null) {
String clipString = clipData.getItemAt(0).coerceToText(getContext()).toString();
if (clipString.length() == 1) {
mListener.onTextInput(clipString);
} else if (clipString.length() > 1) {
//awkward workaround
mListener.onTextInput(clipString.substring(0, clipString.length() - 1));
mListener.onTextInput(clipString.substring(clipString.length() - 1));
}
}
}

@SuppressLint("ClickableViewAccessibility") // no need for View#performClick, we return false mostly anyway
private boolean onLongClickSuggestion(final TextView wordView) {
boolean showIcon = true;
Expand Down
13 changes: 13 additions & 0 deletions app/src/main/java/helium314/keyboard/latin/utils/ToolbarUtils.kt
Original file line number Diff line number Diff line change
Expand Up @@ -60,6 +60,19 @@ fun getCodeForToolbarKey(key: ToolbarKey) = when (key) {
CLOSE_HISTORY -> KeyCode.ALPHA
}

fun getCodeForToolbarKeyLongClick(key: ToolbarKey) = when (key) {
RIGHT -> KeyCode.MOVE_END_OF_LINE
LEFT -> KeyCode.MOVE_START_OF_LINE
UP -> KeyCode.MOVE_PAGE_UP
DOWN -> KeyCode.MOVE_PAGE_DOWN
UNDO -> KeyCode.REDO
REDO -> KeyCode.UNDO
COPY -> KeyCode.CLIPBOARD_COPY_ALL
SELECT_WORD -> KeyCode.CLIPBOARD_SELECT_ALL
CLIPBOARD -> KeyCode.CLIPBOARD_PASTE
else -> KeyCode.UNSPECIFIED
}

private fun getStyleableIconId(key: ToolbarKey) = when (key) {
VOICE -> R.styleable.Keyboard_iconShortcutKey
SETTINGS -> R.styleable.Keyboard_iconSettingsKey
Expand Down
25 changes: 15 additions & 10 deletions app/src/main/res/layout/strip_container.xml
Original file line number Diff line number Diff line change
Expand Up @@ -24,16 +24,21 @@
android:layout_width="match_parent"
android:layout_height="match_parent"
style="?attr/suggestionStripViewStyle" />
<LinearLayout
android:id="@+id/clipboard_strip"
android:orientation="horizontal"
<HorizontalScrollView
android:id="@+id/clipboard_strip_scroll_view"
android:layout_width="match_parent"
android:layout_height="match_parent"
style="?attr/suggestionStripViewStyle" >
<!-- empty view to move buttons to the right -->
<View
android:layout_width="0dp"
android:layout_height="0dp"
android:layout_weight="1" />
</LinearLayout>
android:scrollbarThumbHorizontal="@color/toolbar_scrollbar" >
<LinearLayout
android:id="@+id/clipboard_strip"
android:layout_width="wrap_content"
android:layout_height="match_parent"
style="?attr/suggestionStripViewStyle" >
<!-- empty view to move buttons to the right -->
<View
android:layout_width="0dp"
android:layout_height="0dp"
android:layout_weight="1" />
</LinearLayout>
</HorizontalScrollView>
</FrameLayout>