Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
66 changes: 66 additions & 0 deletions app/src/main/assets/layouts/main/hcesar.json
Original file line number Diff line number Diff line change
@@ -0,0 +1,66 @@
[
[
{ "label": "h" },
{ "label": "c" },
{ "label": "e" },
{ "label": "s" },
{ "label": "a" },
{ "label": "r" },
{ "label": "o" },
{ "label": "p" },
{ "label": "z" },
{ "$": "shift_state_selector",
"shifted": { "label": "«" },
"default": {
"label": ",",
"popup": {
"relevant": [
{ "label": "}"},
{ "label": "0" },
{ "label": ";" },
{ "label": "!" },
{ "label": "!fixedColumnOrder!4" }
]
}
}
}
],
[
{ "label": "q" },
{ "label": "t" },
{ "label": "d" },
{ "label": "i" },
{ "label": "n" },
{ "label": "u" },
{ "label": "l" },
{ "label": "m" },
{ "label": "x" },
{ "$": "shift_state_selector",
"shifted": { "label": "»" },
"default": {
"label": ".",
"popup": {
"relevant": [
{ "label": "/" },
{ "label": ":" },
{"label": "?" },
{ "label": "!fixedColumnOrder!3" }
]
}
}
}
],
[
{ "label": "ç" },
{ "label": "j" },
{ "label": "b" },
{ "label": "f" },
{ "label": "v" },
{ "label": "g" },
{ "label": "k" }
],
[
{ "label": "y" },
{ "label": "w" }
]
]
Original file line number Diff line number Diff line change
Expand Up @@ -331,8 +331,9 @@ public boolean isImeSuppressedByHardwareKeyboard(
private void setMainKeyboardFrame(
@NonNull final SettingsValues settingsValues,
@NonNull final KeyboardSwitchState toggleState) {
final int visibility = isImeSuppressedByHardwareKeyboard(settingsValues, toggleState) ? View.GONE
: View.VISIBLE;
final boolean suppressKeyboard = isImeSuppressedByHardwareKeyboard(settingsValues, toggleState)
|| (settingsValues.mShowOnlyToolbarWithHardwareKeyboard && settingsValues.mHasHardwareKeyboard);
final int visibility = suppressKeyboard ? View.GONE : View.VISIBLE;
final int stripVisibility = settingsValues.mToolbarMode == ToolbarMode.HIDDEN ? View.GONE : View.VISIBLE;
mStripContainer.setVisibility(stripVisibility);
PointerTracker.switchTo(mKeyboardView);
Expand Down
132 changes: 103 additions & 29 deletions app/src/main/java/helium314/keyboard/keyboard/TouchpadView.java
Original file line number Diff line number Diff line change
Expand Up @@ -9,6 +9,8 @@
import android.view.MotionEvent;
import android.view.LayoutInflater;
import android.view.View;
import android.os.Handler;
import android.os.Looper;
import android.widget.LinearLayout;

import helium314.keyboard.keyboard.internal.keyboard_parser.floris.KeyCode;
Expand Down Expand Up @@ -59,6 +61,29 @@ public interface TouchpadListener {

private static final int SCROLL_THRESHOLD = 40;

// Edge-scroll acceleration constants (mirrors HeliBoard's TouchpadHandler)
private static final float EDGE_THRESHOLD_PERCENTAGE = 0.1f;
private static final float EDGE_ACCELERATION_FACTOR = 0.95f;
private static final int MIN_EDGE_ACCELERATION_DELAY = 20;

// Edge-scroll state
private final Handler mEdgeScrollHandler = new Handler(Looper.getMainLooper());
private boolean mIsEdgeScrolling = false;
private int mEdgeScrollDirection = KeyCode.UNSPECIFIED;
private long mEdgeScrollDelay = 200;

private final Runnable mEdgeScrollRunnable = new Runnable() {
@Override
public void run() {
if (mIsEdgeScrolling && mListener != null) {
mListener.onCursorMove(mEdgeScrollDirection, mSelectionMode);
mEdgeScrollDelay = Math.max(MIN_EDGE_ACCELERATION_DELAY,
(long) (mEdgeScrollDelay * EDGE_ACCELERATION_FACTOR));
mEdgeScrollHandler.postDelayed(this, mEdgeScrollDelay);
}
}
};

public TouchpadView(Context context) {
super(context);
init(context);
Expand Down Expand Up @@ -187,42 +212,54 @@ private void setupTouchSurface() {
mScrollAccY += SCROLL_THRESHOLD;
}
} else if (mIsDragging && pointerCount == 1) {
float deltaX = event.getX() - mLastTouchX;
float deltaY = event.getY() - mLastTouchY;
mLastTouchX = event.getX();
mLastTouchY = event.getY();

mAccX += deltaX;
mAccY += deltaY;

int sensitivity = Settings.getValues().mTouchpadSensitivity;
// Base threshold is 110 for normal slow cursor, but 70 for fast selection
int baseThreshold = mSelectionMode ? 70 : 110;
int threshold = baseThreshold - (int) (sensitivity * 0.6f);
if (threshold < 10) threshold = 10;

while (mAccX >= threshold) {
if (mListener != null) mListener.onCursorMove(KeyCode.ARROW_RIGHT, mSelectionMode);
mAccX -= threshold;
}
while (mAccX <= -threshold) {
if (mListener != null) mListener.onCursorMove(KeyCode.ARROW_LEFT, mSelectionMode);
mAccX += threshold;
}
while (mAccY >= threshold) {
if (mListener != null) mListener.onCursorMove(KeyCode.ARROW_DOWN, mSelectionMode);
mAccY -= threshold;
}
while (mAccY <= -threshold) {
if (mListener != null) mListener.onCursorMove(KeyCode.ARROW_UP, mSelectionMode);
mAccY += threshold;
float x = event.getX();
float y = event.getY();
float deltaX = x - mLastTouchX;
float deltaY = y - mLastTouchY;
mLastTouchX = x;
mLastTouchY = y;

// Edge-scroll acceleration: when pref enabled and touch is near an edge,
// start a repeating accelerating cursor-move instead of normal tracking.
if (Settings.getValues().mTouchpadEdgeScroll && handleEdgeScrolling(x, y)) {
mAccX = 0;
mAccY = 0;
} else {
stopEdgeScrolling();

mAccX += deltaX;
mAccY += deltaY;

int sensitivity = Settings.getValues().mTouchpadSensitivity;
// Base threshold is 110 for normal slow cursor, but 70 for fast selection
int baseThreshold = mSelectionMode ? 70 : 110;
int threshold = baseThreshold - (int) (sensitivity * 0.6f);
if (threshold < 10) threshold = 10;

while (mAccX >= threshold) {
if (mListener != null) mListener.onCursorMove(KeyCode.ARROW_RIGHT, mSelectionMode);
mAccX -= threshold;
}
while (mAccX <= -threshold) {
if (mListener != null) mListener.onCursorMove(KeyCode.ARROW_LEFT, mSelectionMode);
mAccX += threshold;
}
while (mAccY >= threshold) {
if (mListener != null) mListener.onCursorMove(KeyCode.ARROW_DOWN, mSelectionMode);
mAccY -= threshold;
}
while (mAccY <= -threshold) {
if (mListener != null) mListener.onCursorMove(KeyCode.ARROW_UP, mSelectionMode);
mAccY += threshold;
}
}
}
return true;

case MotionEvent.ACTION_UP:
case MotionEvent.ACTION_CANCEL:
mIsDragging = false;
stopEdgeScrolling();
mIsTwoFingerScroll = false;
mIsTwoFingerTap = false;
if (mSelectionMode) {
Expand All @@ -244,4 +281,41 @@ private void setupTouchSurface() {
return true;
});
}

/** Returns true and starts/continues edge scrolling if (x, y) is within the edge threshold. */
private boolean handleEdgeScrolling(float x, float y) {
int w = mTouchpadSurface.getWidth();
int h = mTouchpadSurface.getHeight();
int thresholdX = (int) (w * EDGE_THRESHOLD_PERCENTAGE);
int thresholdY = (int) (h * EDGE_THRESHOLD_PERCENTAGE);

int direction;
if (y <= thresholdY) {
direction = KeyCode.ARROW_UP;
} else if (y >= h - thresholdY) {
direction = KeyCode.ARROW_DOWN;
} else if (x <= thresholdX) {
direction = KeyCode.ARROW_LEFT;
} else if (x >= w - thresholdX) {
direction = KeyCode.ARROW_RIGHT;
} else {
return false;
}

if (mIsEdgeScrolling && mEdgeScrollDirection == direction) {
return true; // already running in this direction
}
stopEdgeScrolling();
mEdgeScrollDirection = direction;
mIsEdgeScrolling = true;
int sensitivity = Settings.getValues().mTouchpadSensitivity;
mEdgeScrollDelay = 300L - (long) (sensitivity * 2.5f);
mEdgeScrollHandler.post(mEdgeScrollRunnable);
return true;
}

private void stopEdgeScrolling() {
mIsEdgeScrolling = false;
mEdgeScrollHandler.removeCallbacks(mEdgeScrollRunnable);
}
}
5 changes: 5 additions & 0 deletions app/src/main/java/helium314/keyboard/latin/LatinIME.java
Original file line number Diff line number Diff line change
Expand Up @@ -1799,6 +1799,11 @@ public void removeExternalSuggestions() {
mHandler.postResumeSuggestions(false);
}

@Override
public void onSwipeDownOnToolbar() {
requestHideSelf(0);
}

private void loadKeyboard() {
// Since we are switching languages, the most urgent thing is to let the
// keyboard graphics
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -180,6 +180,7 @@ object Defaults {
const val PREF_SPACE_TO_CHANGE_LANG = true
const val PREF_LANGUAGE_SWIPE_DISTANCE = 5
const val PREF_TOUCHPAD_SENSITIVITY = 50
const val PREF_TOUCHPAD_EDGE_SCROLL = false
const val PREF_FORCE_AUTO_CAPS = false
const val PREF_OFFLINE_TEMP = 0.1f // Lower for faster, more deterministic proofreading
const val PREF_OFFLINE_TOP_P = 0.5f // Lower for faster token sampling
Expand Down Expand Up @@ -214,6 +215,8 @@ object Defaults {
const val PREF_AUTO_HIDE_TOOLBAR = true
const val PREF_AUTO_HIDE_PINNED_KEYS = true
const val PREF_REMEMBER_TOOLBAR_STATE = false
const val PREF_TOOLBAR_SWIPE_DOWN_TO_HIDE = false
const val PREF_SHOW_ONLY_TOOLBAR_WITH_HARDWARE_KEYBOARD = false
const val PREF_TOOLBAR_EXPANDED = false
val PREF_CLIPBOARD_TOOLBAR_KEYS = defaultClipboardToolbarPref
const val PREF_ABC_AFTER_EMOJI = false
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -209,6 +209,7 @@ public final class Settings implements SharedPreferences.OnSharedPreferenceChang
public static final String PREF_SPACE_TO_CHANGE_LANG = "prefs_long_press_keyboard_to_change_lang";
public static final String PREF_LANGUAGE_SWIPE_DISTANCE = "language_swipe_distance";
public static final String PREF_TOUCHPAD_SENSITIVITY = "touchpad_sensitivity";
public static final String PREF_TOUCHPAD_EDGE_SCROLL = "touchpad_edge_scroll";
public static final String PREF_PERSIST_FLOATING_KEYBOARD = "persist_floating_keyboard";
public static final String PREF_FORCE_AUTO_CAPS = "force_auto_caps";
public static final String PREF_OFFLINE_TEMP = "offline_temp";
Expand Down Expand Up @@ -257,6 +258,8 @@ public final class Settings implements SharedPreferences.OnSharedPreferenceChang
public static final String PREF_TOOLBAR_MODE = "toolbar_mode";
public static final String PREF_TOOLBAR_HIDING_GLOBAL = "toolbar_hiding_global";
public static final String PREF_SPLIT_TOOLBAR = "split_toolbar";
public static final String PREF_TOOLBAR_SWIPE_DOWN_TO_HIDE = "toolbar_swipe_down_to_hide";
public static final String PREF_SHOW_ONLY_TOOLBAR_WITH_HARDWARE_KEYBOARD = "only_toolbar_with_hw_keyboard";

// Emoji
public static final String PREF_EMOJI_MAX_SDK = "emoji_max_sdk";
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -82,6 +82,7 @@ public class SettingsValues {
public final int mSpaceSwipeVertical;
public final int mLanguageSwipeDistance;
public final int mTouchpadSensitivity;
public final boolean mTouchpadEdgeScroll;
public final boolean mForceAutoCaps;
public final boolean mDeleteSwipeEnabled;
public final boolean mShortcutRowsEnabled;
Expand Down Expand Up @@ -171,6 +172,8 @@ public class SettingsValues {
public final boolean mAutoHideToolbar;
public final boolean mAutoHidePinnedKeys;
public final boolean mRememberToolbarState;
public final boolean mToolbarSwipeDownToHide;
public final boolean mShowOnlyToolbarWithHardwareKeyboard;
public final boolean mAlphaAfterEmojiInEmojiView;
public final boolean mAlphaAfterClipHistoryEntry;
public final boolean mAlphaAfterSymbolAndSpace;
Expand Down Expand Up @@ -426,6 +429,8 @@ public SettingsValues(final Context context, final SharedPreferences prefs, fina
Defaults.PREF_LANGUAGE_SWIPE_DISTANCE);
mTouchpadSensitivity = prefs.getInt(Settings.PREF_TOUCHPAD_SENSITIVITY,
Defaults.PREF_TOUCHPAD_SENSITIVITY);
mTouchpadEdgeScroll = prefs.getBoolean(Settings.PREF_TOUCHPAD_EDGE_SCROLL,
Defaults.PREF_TOUCHPAD_EDGE_SCROLL);
mForceAutoCaps = prefs.getBoolean(Settings.PREF_FORCE_AUTO_CAPS, Defaults.PREF_FORCE_AUTO_CAPS);
mDeleteSwipeEnabled = prefs.getBoolean(Settings.PREF_DELETE_SWIPE, Defaults.PREF_DELETE_SWIPE);
mShortcutRowsEnabled = prefs.getBoolean(Settings.PREF_SHORTCUT_ROWS, Defaults.PREF_SHORTCUT_ROWS);
Expand Down Expand Up @@ -505,6 +510,11 @@ public SettingsValues(final Context context, final SharedPreferences prefs, fina
&& prefs.getBoolean(Settings.PREF_AUTO_HIDE_PINNED_KEYS, Defaults.PREF_AUTO_HIDE_PINNED_KEYS);
mRememberToolbarState = prefs.getBoolean(Settings.PREF_REMEMBER_TOOLBAR_STATE,
Defaults.PREF_REMEMBER_TOOLBAR_STATE);
mToolbarSwipeDownToHide = prefs.getBoolean(Settings.PREF_TOOLBAR_SWIPE_DOWN_TO_HIDE,
Defaults.PREF_TOOLBAR_SWIPE_DOWN_TO_HIDE);
mShowOnlyToolbarWithHardwareKeyboard = prefs.getBoolean(
Settings.PREF_SHOW_ONLY_TOOLBAR_WITH_HARDWARE_KEYBOARD,
Defaults.PREF_SHOW_ONLY_TOOLBAR_WITH_HARDWARE_KEYBOARD);
// Migration: clear any old saved value and reset to default
if (!prefs.contains(Settings.PREF_AUTO_HIDE_PINNED_KEYS)) {
prefs.edit().putBoolean(Settings.PREF_AUTO_HIDE_PINNED_KEYS, Defaults.PREF_AUTO_HIDE_PINNED_KEYS).apply();
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -66,6 +66,7 @@ import helium314.keyboard.latin.utils.setToolbarButtonsActivatedState
import helium314.keyboard.latin.utils.setToolbarButtonsActivatedStateOnPrefChange
import helium314.keyboard.settings.SettingsWithoutKey
import java.util.concurrent.atomic.AtomicBoolean
import kotlin.math.abs
import kotlin.math.min

@SuppressLint("InflateParams")
Expand All @@ -82,6 +83,7 @@ class SuggestionStripView(context: Context, attrs: AttributeSet?, defStyle: Int)
fun removeExternalSuggestions()
fun addToDictionary(word: String)
fun blockWord(word: String)
fun onSwipeDownOnToolbar()
}

private val moreSuggestionsContainer: View
Expand Down Expand Up @@ -293,6 +295,11 @@ class SuggestionStripView(context: Context, attrs: AttributeSet?, defStyle: Int)
override fun onScroll(down: MotionEvent?, me: MotionEvent, deltaX: Float, deltaY: Float): Boolean {
if (down == null) return false
val dy = me.y - down.y
val dx = me.x - down.x
if (Settings.getValues().mToolbarSwipeDownToHide && dy > 50.dpToPx(resources) && abs(dy) > abs(dx)) {
listener.onSwipeDownOnToolbar()
return true
}
return if (toolbarContainer.visibility != VISIBLE && deltaY > 0 && dy < (-10).dpToPx(resources)) showMoreSuggestions()
else false
}
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -72,6 +72,7 @@ fun GestureTypingScreen(
add(Settings.PREF_SPACE_HORIZONTAL_SWIPE)
add(Settings.PREF_SPACE_VERTICAL_SWIPE)
add(Settings.PREF_TOUCHPAD_SENSITIVITY)
add(Settings.PREF_TOUCHPAD_EDGE_SCROLL)
add(Settings.PREF_DELETE_SWIPE)
add(Settings.PREF_SHORTCUT_ROWS)
if (prefs.getBoolean(Settings.PREF_SHORTCUT_ROWS, Defaults.PREF_SHORTCUT_ROWS)) {
Expand Down Expand Up @@ -169,6 +170,9 @@ fun createGestureTypingSettings(context: Context) = listOf(
description = { value -> value.toInt().toString() }
)
},
Setting(context, Settings.PREF_TOUCHPAD_EDGE_SCROLL, R.string.touchpad_edge_scroll, R.string.touchpad_edge_scroll_summary) {
SwitchPreference(it, Defaults.PREF_TOUCHPAD_EDGE_SCROLL)
},
Setting(context, Settings.PREF_DELETE_SWIPE, R.string.delete_swipe, R.string.delete_swipe_summary) {
SwitchPreference(it, Defaults.PREF_DELETE_SWIPE)
},
Expand Down
Loading
Loading