abouttreesummaryrefslogcommitdiff
path: root/srcs
diff options
context:
space:
mode:
authorJules Aguillon2026-02-01 23:25:38 +0100
committerGitHub2026-02-01 23:25:38 +0100
commit2ecf93d9904544ee73159e9f0ee74b49057bca6c (patch)
treeb574489e776a9ca665c7cc97b75f127527e59cd1 /srcs
parentb9072daaf62d5decb3377beeb281790a7512ae02 (diff)
downloadunexpected-keyboard-2ecf93d9904544ee73159e9f0ee74b49057bca6c.tar.gz
unexpected-keyboard-2ecf93d9904544ee73159e9f0ee74b49057bca6c.zip
Candidates view improvements (#1168)
* Refactor: Create subpackage 'suggestions' * Candidates view: Status message when no dictionary installed Show a message on the candidates view instead of leaving it empty. A button points to the dictionary installation activity. * Add an option to disable the suggestions * Refactor: Remove Config.should_show_candidates_view This was moved to EditorConfig. * Don't disable text suggestions in some text boxes * Suggestion text size matching settings The candidates view height is based on the height of keyboard rows and the suggestion text size is based on the size of labels on the keys. This is influenced by symbol size and keyboard height options.
Diffstat (limited to 'srcs')
-rw-r--r--srcs/juloo.keyboard2/Config.java13
-rw-r--r--srcs/juloo.keyboard2/CurrentlyTypedWord.java5
-rw-r--r--srcs/juloo.keyboard2/EditorConfig.java2
-rw-r--r--srcs/juloo.keyboard2/KeyEventHandler.java3
-rw-r--r--srcs/juloo.keyboard2/Keyboard2.java9
-rw-r--r--srcs/juloo.keyboard2/Logs.java2
-rw-r--r--srcs/juloo.keyboard2/Theme.java12
-rw-r--r--srcs/juloo.keyboard2/suggestions/CandidatesView.java (renamed from srcs/juloo.keyboard2/CandidatesView.java)67
-rw-r--r--srcs/juloo.keyboard2/suggestions/Suggestions.java (renamed from srcs/juloo.keyboard2/Suggestions.java)4
9 files changed, 89 insertions, 28 deletions
diff --git a/srcs/juloo.keyboard2/Config.java b/srcs/juloo.keyboard2/Config.java
index 5719bd9..16a92ef 100644
--- a/srcs/juloo.keyboard2/Config.java
+++ b/srcs/juloo.keyboard2/Config.java
@@ -42,6 +42,7 @@ public final class Config
public boolean number_row_symbols;
public float swipe_dist_px;
public float slide_step_px;
+ public boolean suggestions_enabled;
// Let the system handle vibration when false.
public boolean vibrate_custom;
// Control the vibration if [vibrate_custom] is true.
@@ -50,7 +51,7 @@ public final class Config
public long longPressInterval;
public boolean keyrepeat_enabled;
public float margin_bottom;
- public int keyboardHeightPercent;
+ public int keyboard_rows_height_pixels;
public int screenHeightPixels;
public float horizontal_margin;
public float key_vertical_margin;
@@ -75,7 +76,6 @@ public final class Config
// Dynamically set
/** Configuration options implied by the connected editor. */
public EditorConfig editor_config;
- public boolean should_show_candidates_view;
public boolean shouldOfferVoiceTyping;
public ExtraKeys extra_keys_subtype;
public Map<KeyValue, KeyboardData.PreferredPos> extra_keys_param;
@@ -102,7 +102,6 @@ public final class Config
// from prefs
refresh(res, foldableUnfolded);
// initialized later
- should_show_candidates_view = false;
shouldOfferVoiceTyping = false;
extra_keys_subtype = null;
handler = h;
@@ -120,6 +119,7 @@ public final class Config
float characterSizeScale = 1.f;
String show_numpad_s = _prefs.getString("show_numpad", "never");
show_numpad = "always".equals(show_numpad_s);
+ int keyboardHeightPercent;
if (orientation_landscape)
{
if ("landscape".equals(show_numpad_s))
@@ -136,6 +136,7 @@ public final class Config
String number_row = _prefs.getString("number_row", "no_number_row");
add_number_row = !number_row.equals("no_number_row");
number_row_symbols = number_row.equals("symbols");
+ suggestions_enabled = _prefs.getBoolean("suggestions", true);
// The baseline for the swipe distance correspond to approximately the
// width of a key in portrait mode, as most layouts have 10 columns.
// Multipled by the DPI ratio because most swipes are made in the diagonals.
@@ -165,6 +166,12 @@ public final class Config
customBorderRadius = _prefs.getInt("custom_border_radius", 0) / 100.f;
customBorderLineWidth = get_dip_pref(dm, "custom_border_line_width", 0);
screenHeightPixels = dm.heightPixels;
+ // Rows height is proportional to the screen height, meaning it doesn't
+ // change for layouts with more or less rows. 3.95 is the usual height of
+ // a layout in KeyboardData unit. The keyboard will be higher if the layout
+ // has more rows and smaller if it has less because rows stay the same
+ // height.
+ keyboard_rows_height_pixels = screenHeightPixels * keyboardHeightPercent / 395;
horizontal_margin =
get_dip_pref_oriented(dm, "horizontal_margin", 3, 28);
double_tap_lock_shift = _prefs.getBoolean("lock_double_tap", false);
diff --git a/srcs/juloo.keyboard2/CurrentlyTypedWord.java b/srcs/juloo.keyboard2/CurrentlyTypedWord.java
index 87a1cf1..8685fb1 100644
--- a/srcs/juloo.keyboard2/CurrentlyTypedWord.java
+++ b/srcs/juloo.keyboard2/CurrentlyTypedWord.java
@@ -113,12 +113,9 @@ public final class CurrentlyTypedWord
/** Refresh the current word by immediately querying the editor. */
void set_current_word(CharSequence text_before_cursor)
{
+ _w.setLength(0);
if (text_before_cursor == null)
- {
- _enabled = false;
return;
- }
- _w.setLength(0);
int saved_cursor = _cursor;
type_chars(text_before_cursor.toString());
_cursor = saved_cursor;
diff --git a/srcs/juloo.keyboard2/EditorConfig.java b/srcs/juloo.keyboard2/EditorConfig.java
index 2bfbcef..67b7799 100644
--- a/srcs/juloo.keyboard2/EditorConfig.java
+++ b/srcs/juloo.keyboard2/EditorConfig.java
@@ -5,7 +5,7 @@ import android.os.Build.VERSION;
import android.text.InputType;
import android.text.TextUtils;
import android.view.inputmethod.EditorInfo;
-import juloo.keyboard2.CandidatesView;
+import juloo.keyboard2.suggestions.CandidatesView;
public final class EditorConfig
{
diff --git a/srcs/juloo.keyboard2/KeyEventHandler.java b/srcs/juloo.keyboard2/KeyEventHandler.java
index a0487d7..18e0592 100644
--- a/srcs/juloo.keyboard2/KeyEventHandler.java
+++ b/srcs/juloo.keyboard2/KeyEventHandler.java
@@ -1,14 +1,15 @@
package juloo.keyboard2;
import android.annotation.SuppressLint;
-import android.os.Looper;
import android.os.Handler;
+import android.os.Looper;
import android.view.KeyCharacterMap;
import android.view.KeyEvent;
import android.view.inputmethod.ExtractedText;
import android.view.inputmethod.ExtractedTextRequest;
import android.view.inputmethod.InputConnection;
import java.util.Iterator;
+import juloo.keyboard2.suggestions.Suggestions;
public final class KeyEventHandler
implements Config.IKeyEventHandler,
diff --git a/srcs/juloo.keyboard2/Keyboard2.java b/srcs/juloo.keyboard2/Keyboard2.java
index 4d008d9..25af0d0 100644
--- a/srcs/juloo.keyboard2/Keyboard2.java
+++ b/srcs/juloo.keyboard2/Keyboard2.java
@@ -24,6 +24,7 @@ import java.util.HashSet;
import java.util.List;
import java.util.Set;
import juloo.keyboard2.prefs.LayoutsPreference;
+import juloo.keyboard2.suggestions.CandidatesView;
public class Keyboard2 extends InputMethodService
implements SharedPreferences.OnSharedPreferenceChangeListener
@@ -164,7 +165,11 @@ public class Keyboard2 extends InputMethodService
private void refresh_candidates_view()
{
- boolean should_show = _config.editor_config.should_show_candidates_view;
+ boolean should_show =
+ _config.suggestions_enabled
+ && _config.editor_config.should_show_candidates_view;
+ if (should_show)
+ _candidates_view.refresh_config(_config);
_candidates_view.setVisibility(should_show ? View.VISIBLE : View.GONE);
}
@@ -185,6 +190,7 @@ public class Keyboard2 extends InputMethodService
// Set keyboard background opacity
_container_view.getBackground().setAlpha(_config.keyboardOpacity);
_keyboardView.reset();
+ refresh_candidates_view();
}
private KeyboardData refresh_special_layout()
@@ -205,7 +211,6 @@ public class Keyboard2 extends InputMethodService
{
_config.editor_config.refresh(info, getResources());
refresh_config();
- refresh_candidates_view();
_currentSpecialLayout = refresh_special_layout();
_keyboardView.setKeyboard(current_layout());
_keyeventhandler.started(_config);
diff --git a/srcs/juloo.keyboard2/Logs.java b/srcs/juloo.keyboard2/Logs.java
index a956305..1bef51c 100644
--- a/srcs/juloo.keyboard2/Logs.java
+++ b/srcs/juloo.keyboard2/Logs.java
@@ -26,8 +26,6 @@ public final class Logs
_debug_logs.println("swapEnterActionKey: "
+conf.editor_config.swapEnterActionKey);
_debug_logs.println("actionLabel: "+conf.editor_config.actionLabel);
- _debug_logs.println("should_show_candidates_view: "
- +conf.should_show_candidates_view);
}
public static void debug_config_migration(int from_version, int to_version)
diff --git a/srcs/juloo.keyboard2/Theme.java b/srcs/juloo.keyboard2/Theme.java
index 9af0d01..f291f36 100644
--- a/srcs/juloo.keyboard2/Theme.java
+++ b/srcs/juloo.keyboard2/Theme.java
@@ -102,14 +102,10 @@ public class Theme
public Computed(Theme theme, Config config, float keyWidth, KeyboardData layout)
{
- // Rows height is proportional to the keyboard height, meaning it doesn't
- // change for layouts with more or less rows. 3.95 is the usual height of
- // a layout in KeyboardData unit. The keyboard will be higher if the
- // layout has more rows and smaller if it has less because rows stay the
- // same height.
- row_height = Math.min(
- config.screenHeightPixels * config.keyboardHeightPercent / 100 / 3.95f,
- config.screenHeightPixels / layout.keysHeight);
+ // Make sure that the layout isn't higher than the screen. Take the
+ // height of the candidates view into account.
+ row_height = Math.min(config.keyboard_rows_height_pixels,
+ (config.screenHeightPixels - config.keyboard_rows_height_pixels) / layout.keysHeight);
vertical_margin = config.key_vertical_margin * row_height;
horizontal_margin = config.key_horizontal_margin * keyWidth;
// Add half of the key margin on the left and on the top as it's also
diff --git a/srcs/juloo.keyboard2/CandidatesView.java b/srcs/juloo.keyboard2/suggestions/CandidatesView.java
index 232ed23..259db35 100644
--- a/srcs/juloo.keyboard2/CandidatesView.java
+++ b/srcs/juloo.keyboard2/suggestions/CandidatesView.java
@@ -1,21 +1,23 @@
-package juloo.keyboard2;
+package juloo.keyboard2.suggestions;
import android.content.Context;
import android.text.InputType;
import android.util.AttributeSet;
+import android.util.TypedValue;
import android.view.View;
+import android.view.ViewGroup;
import android.view.inputmethod.EditorInfo;
import android.widget.LinearLayout;
import android.widget.TextView;
import java.util.ArrayList;
import java.util.List;
+import juloo.keyboard2.Config;
+import juloo.keyboard2.R;
public class CandidatesView extends LinearLayout
{
static final int NUM_CANDIDATES = 3;
- Config _config;
-
/** Candidates currently visible. Entries can be [null] when there are less
than [NUM_CANDIDATES] suggestions. */
String[] _items = new String[NUM_CANDIDATES];
@@ -24,10 +26,13 @@ public class CandidatesView extends LinearLayout
set to [GONE] when there are less than [NUM_CANDIDATES] suggestions. */
TextView[] _item_views = new TextView[NUM_CANDIDATES];
+ /** Optional view showing a message to the user. Visible when no candidates
+ are shown. Might be [null]. */
+ View _status_no_dict = null; // Dictionary not installed
+
public CandidatesView(Context context, AttributeSet attrs)
{
super(context, attrs);
- _config = Config.globalConfig();
}
@Override
@@ -42,6 +47,9 @@ public class CandidatesView extends LinearLayout
public void set_candidates(List<String> suggestions)
{
int s_count = suggestions.size();
+ // Hide the status message when showing candidates.
+ if (s_count != 0 && _status_no_dict != null)
+ _status_no_dict.setVisibility(View.GONE);
for (int i = 0; i < _item_views.length; i++)
{
TextView v = _item_views[i];
@@ -60,6 +68,54 @@ public class CandidatesView extends LinearLayout
}
}
+ public void refresh_config(Config config)
+ {
+ set_candidates(Suggestions.NO_SUGGESTIONS);
+ // The status message indicates whether the dictionaries should be
+ // installed.
+ _status_no_dict = inflate_and_show(_status_no_dict,
+ true,
+ R.layout.candidates_status_no_dict);
+ set_height(config);
+ }
+
+ void set_height(Config config)
+ {
+ // Make the candidates view about as high as a keyboard row.
+ int height = (int)(config.keyboard_rows_height_pixels * (1 - config.key_vertical_margin));
+ // Match the size of labels on the keyboard, increased by 15%.
+ float text_size = height * config.characterSize * config.labelTextSize * 1.15f;
+ for (int i = 0; i < NUM_CANDIDATES; i++)
+ {
+ TextView v = _item_views[i];
+ ViewGroup.MarginLayoutParams p =
+ (ViewGroup.MarginLayoutParams)v.getLayoutParams();
+ p.height = height;
+ v.setLayoutParams(p);
+ v.setTextSize(TypedValue.COMPLEX_UNIT_PX, text_size);
+ }
+ }
+
+ /** Show or hide a status view and inflate it if needed. */
+ View inflate_and_show(View v, boolean show, int layout_id)
+ {
+ if (!show)
+ {
+ if (v != null)
+ v.setVisibility(View.GONE);
+ }
+ else
+ {
+ if (v == null)
+ {
+ v = View.inflate(getContext(), layout_id, null);
+ addView(v);
+ }
+ v.setVisibility(View.VISIBLE);
+ }
+ return v;
+ }
+
private void setup_item_view(final int item_index, int item_id)
{
TextView v = (TextView)findViewById(item_id);
@@ -70,13 +126,14 @@ public class CandidatesView extends LinearLayout
{
String it = _items[item_index];
if (it != null)
- _config.handler.suggestion_entered(it);
+ Config.globalConfig().handler.suggestion_entered(it);
}
});
v.setVisibility(View.GONE);
_item_views[item_index] = v;
}
+ /** Whether the candidates view should be shown for a given editor. */
public static boolean should_show(EditorInfo info)
{
int variation = info.inputType & InputType.TYPE_MASK_VARIATION;
diff --git a/srcs/juloo.keyboard2/Suggestions.java b/srcs/juloo.keyboard2/suggestions/Suggestions.java
index 4c0c97a..50c64e0 100644
--- a/srcs/juloo.keyboard2/Suggestions.java
+++ b/srcs/juloo.keyboard2/suggestions/Suggestions.java
@@ -1,7 +1,7 @@
-package juloo.keyboard2;
+package juloo.keyboard2.suggestions;
-import java.util.List;
import java.util.Arrays;
+import java.util.List;
/** Keep track of the word being typed and provide suggestions for
[CandidatesView]. */