mirror of
https://github.com/darkrenaissance/darkfi.git
synced 2026-01-08 22:28:12 -05:00
app: reduce JNI overhead when adjusting a selection by creating a special setSelection() fn so we dont have to pass the entire state over the bridge.
This commit is contained in:
@@ -45,7 +45,6 @@ import androidx.core.view.WindowInsetsCompat;
|
|||||||
import textinput.GameTextInput.Pair;
|
import textinput.GameTextInput.Pair;
|
||||||
|
|
||||||
public class InputConnection extends BaseInputConnection implements View.OnKeyListener {
|
public class InputConnection extends BaseInputConnection implements View.OnKeyListener {
|
||||||
private static final String TAG = "gti.InputConnection";
|
|
||||||
private final InputMethodManager imm;
|
private final InputMethodManager imm;
|
||||||
private final View targetView;
|
private final View targetView;
|
||||||
private final Settings settings;
|
private final Settings settings;
|
||||||
@@ -53,6 +52,10 @@ public class InputConnection extends BaseInputConnection implements View.OnKeyLi
|
|||||||
private Listener listener;
|
private Listener listener;
|
||||||
private boolean mSoftKeyboardActive;
|
private boolean mSoftKeyboardActive;
|
||||||
|
|
||||||
|
private void log(String text) {
|
||||||
|
//Log.d("darkfi", text);
|
||||||
|
}
|
||||||
|
|
||||||
/*
|
/*
|
||||||
* This class filters EOL characters from the input. For details of how InputFilter.filter
|
* This class filters EOL characters from the input. For details of how InputFilter.filter
|
||||||
* function works, refer to its documentation. If the suggested change is accepted without
|
* function works, refer to its documentation. If the suggested change is accepted without
|
||||||
@@ -100,7 +103,7 @@ public class InputConnection extends BaseInputConnection implements View.OnKeyLi
|
|||||||
*/
|
*/
|
||||||
public InputConnection(Context ctx, View targetView, Settings settings) {
|
public InputConnection(Context ctx, View targetView, Settings settings) {
|
||||||
super(targetView, settings.mEditorInfo.inputType != 0);
|
super(targetView, settings.mEditorInfo.inputType != 0);
|
||||||
Log.d(TAG, "InputConnection created");
|
log("InputConnection created");
|
||||||
|
|
||||||
this.targetView = targetView;
|
this.targetView = targetView;
|
||||||
this.settings = settings;
|
this.settings = settings;
|
||||||
@@ -143,7 +146,7 @@ public class InputConnection extends BaseInputConnection implements View.OnKeyLi
|
|||||||
* https://developer.android.com/reference/android/view/inputmethod/InputMethodManager#showSoftInput(android.view.View,%20int)
|
* https://developer.android.com/reference/android/view/inputmethod/InputMethodManager#showSoftInput(android.view.View,%20int)
|
||||||
*/
|
*/
|
||||||
public final void setSoftKeyboardActive(boolean active, int flags) {
|
public final void setSoftKeyboardActive(boolean active, int flags) {
|
||||||
Log.d(TAG, "setSoftKeyboardActive, active: " + active);
|
log("setSoftKeyboardActive, active: " + active);
|
||||||
|
|
||||||
this.mSoftKeyboardActive = active;
|
this.mSoftKeyboardActive = active;
|
||||||
if (active) {
|
if (active) {
|
||||||
@@ -171,7 +174,7 @@ public class InputConnection extends BaseInputConnection implements View.OnKeyLi
|
|||||||
* @param editorInfo The EditorInfo to use
|
* @param editorInfo The EditorInfo to use
|
||||||
*/
|
*/
|
||||||
public final void setEditorInfo(EditorInfo editorInfo) {
|
public final void setEditorInfo(EditorInfo editorInfo) {
|
||||||
Log.d(TAG, "setEditorInfo");
|
log("setEditorInfo");
|
||||||
settings.mEditorInfo = editorInfo;
|
settings.mEditorInfo = editorInfo;
|
||||||
|
|
||||||
// Depending on the multiline state, we might need a different set of filters.
|
// Depending on the multiline state, we might need a different set of filters.
|
||||||
@@ -195,7 +198,7 @@ public class InputConnection extends BaseInputConnection implements View.OnKeyLi
|
|||||||
public final void setState(State state) {
|
public final void setState(State state) {
|
||||||
if (state == null)
|
if (state == null)
|
||||||
return;
|
return;
|
||||||
Log.d(TAG,
|
log(
|
||||||
"setState: '" + state.text + "', selection=(" + state.selectionStart + ","
|
"setState: '" + state.text + "', selection=(" + state.selectionStart + ","
|
||||||
+ state.selectionEnd + "), composing region=(" + state.composingRegionStart + ","
|
+ state.selectionEnd + "), composing region=(" + state.composingRegionStart + ","
|
||||||
+ state.composingRegionEnd + ")");
|
+ state.composingRegionEnd + ")");
|
||||||
@@ -232,7 +235,7 @@ public class InputConnection extends BaseInputConnection implements View.OnKeyLi
|
|||||||
// From View.OnKeyListener
|
// From View.OnKeyListener
|
||||||
@Override
|
@Override
|
||||||
public boolean onKey(View view, int i, KeyEvent keyEvent) {
|
public boolean onKey(View view, int i, KeyEvent keyEvent) {
|
||||||
Log.d(TAG, "onKey: " + keyEvent);
|
log("onKey: " + keyEvent);
|
||||||
if (!getSoftKeyboardActive()) {
|
if (!getSoftKeyboardActive()) {
|
||||||
return false;
|
return false;
|
||||||
}
|
}
|
||||||
@@ -251,22 +254,22 @@ public class InputConnection extends BaseInputConnection implements View.OnKeyLi
|
|||||||
// From BaseInputConnection
|
// From BaseInputConnection
|
||||||
@Override
|
@Override
|
||||||
public Editable getEditable() {
|
public Editable getEditable() {
|
||||||
Log.d(TAG, "getEditable");
|
log("getEditable");
|
||||||
return mEditable;
|
return mEditable;
|
||||||
}
|
}
|
||||||
|
|
||||||
// From BaseInputConnection
|
// From BaseInputConnection
|
||||||
@Override
|
@Override
|
||||||
public boolean setSelection(int start, int end) {
|
public boolean setSelection(int start, int end) {
|
||||||
Log.d(TAG, "setSelection: " + start + ":" + end);
|
log("setSelection: " + start + ":" + end);
|
||||||
return super.setSelection(start, end);
|
return super.setSelection(start, end);
|
||||||
}
|
}
|
||||||
|
|
||||||
// From BaseInputConnection
|
// From BaseInputConnection
|
||||||
@Override
|
@Override
|
||||||
public boolean setComposingText(CharSequence text, int newCursorPosition) {
|
public boolean setComposingText(CharSequence text, int newCursorPosition) {
|
||||||
Log.d(
|
log(
|
||||||
TAG, String.format("setComposingText='%s' newCursorPosition=%d", text, newCursorPosition));
|
"setComposingText='" + text + "' newCursorPosition=" + newCursorPosition);
|
||||||
if (text == null) {
|
if (text == null) {
|
||||||
return false;
|
return false;
|
||||||
}
|
}
|
||||||
@@ -275,40 +278,40 @@ public class InputConnection extends BaseInputConnection implements View.OnKeyLi
|
|||||||
|
|
||||||
@Override
|
@Override
|
||||||
public boolean setComposingRegion(int start, int end) {
|
public boolean setComposingRegion(int start, int end) {
|
||||||
Log.d(TAG, "setComposingRegion: " + start + ":" + end);
|
log("setComposingRegion: " + start + ":" + end);
|
||||||
return super.setComposingRegion(start, end);
|
return super.setComposingRegion(start, end);
|
||||||
}
|
}
|
||||||
|
|
||||||
// From BaseInputConnection
|
// From BaseInputConnection
|
||||||
@Override
|
@Override
|
||||||
public boolean finishComposingText() {
|
public boolean finishComposingText() {
|
||||||
Log.d(TAG, "finishComposingText");
|
log("finishComposingText");
|
||||||
return super.finishComposingText();
|
return super.finishComposingText();
|
||||||
}
|
}
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
public boolean endBatchEdit() {
|
public boolean endBatchEdit() {
|
||||||
Log.d(TAG, "endBatchEdit");
|
log("endBatchEdit");
|
||||||
stateUpdated();
|
stateUpdated();
|
||||||
return super.endBatchEdit();
|
return super.endBatchEdit();
|
||||||
}
|
}
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
public boolean commitCompletion(CompletionInfo text) {
|
public boolean commitCompletion(CompletionInfo text) {
|
||||||
Log.d(TAG, "commitCompletion");
|
log("commitCompletion");
|
||||||
return super.commitCompletion(text);
|
return super.commitCompletion(text);
|
||||||
}
|
}
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
public boolean commitCorrection(CorrectionInfo text) {
|
public boolean commitCorrection(CorrectionInfo text) {
|
||||||
Log.d(TAG, "commitCompletion");
|
log("commitCompletion");
|
||||||
return super.commitCorrection(text);
|
return super.commitCorrection(text);
|
||||||
}
|
}
|
||||||
|
|
||||||
// From BaseInputConnection
|
// From BaseInputConnection
|
||||||
@Override
|
@Override
|
||||||
public boolean commitText(CharSequence text, int newCursorPosition) {
|
public boolean commitText(CharSequence text, int newCursorPosition) {
|
||||||
Log.d(TAG,
|
log(
|
||||||
(new StringBuilder())
|
(new StringBuilder())
|
||||||
.append("commitText: ")
|
.append("commitText: ")
|
||||||
.append(text)
|
.append(text)
|
||||||
@@ -321,21 +324,21 @@ public class InputConnection extends BaseInputConnection implements View.OnKeyLi
|
|||||||
// From BaseInputConnection
|
// From BaseInputConnection
|
||||||
@Override
|
@Override
|
||||||
public boolean deleteSurroundingText(int beforeLength, int afterLength) {
|
public boolean deleteSurroundingText(int beforeLength, int afterLength) {
|
||||||
Log.d(TAG, "deleteSurroundingText: " + beforeLength + ":" + afterLength);
|
log("deleteSurroundingText: " + beforeLength + ":" + afterLength);
|
||||||
return super.deleteSurroundingText(beforeLength, afterLength);
|
return super.deleteSurroundingText(beforeLength, afterLength);
|
||||||
}
|
}
|
||||||
|
|
||||||
// From BaseInputConnection
|
// From BaseInputConnection
|
||||||
@Override
|
@Override
|
||||||
public boolean deleteSurroundingTextInCodePoints(int beforeLength, int afterLength) {
|
public boolean deleteSurroundingTextInCodePoints(int beforeLength, int afterLength) {
|
||||||
Log.d(TAG, "deleteSurroundingTextInCodePoints: " + beforeLength + ":" + afterLength);
|
log("deleteSurroundingTextInCodePoints: " + beforeLength + ":" + afterLength);
|
||||||
return super.deleteSurroundingTextInCodePoints(beforeLength, afterLength);
|
return super.deleteSurroundingTextInCodePoints(beforeLength, afterLength);
|
||||||
}
|
}
|
||||||
|
|
||||||
// From BaseInputConnection
|
// From BaseInputConnection
|
||||||
@Override
|
@Override
|
||||||
public boolean sendKeyEvent(KeyEvent event) {
|
public boolean sendKeyEvent(KeyEvent event) {
|
||||||
Log.d(TAG, "sendKeyEvent: " + event);
|
log("sendKeyEvent: " + event);
|
||||||
return super.sendKeyEvent(event);
|
return super.sendKeyEvent(event);
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -346,16 +349,16 @@ public class InputConnection extends BaseInputConnection implements View.OnKeyLi
|
|||||||
if (result == null) {
|
if (result == null) {
|
||||||
result = "";
|
result = "";
|
||||||
}
|
}
|
||||||
Log.d(TAG, "getSelectedText: " + flags + ", result: " + result);
|
log("getSelectedText: " + flags + ", result: " + result);
|
||||||
return result;
|
return result;
|
||||||
}
|
}
|
||||||
|
|
||||||
// From BaseInputConnection
|
// From BaseInputConnection
|
||||||
@Override
|
@Override
|
||||||
public CharSequence getTextAfterCursor(int length, int flags) {
|
public CharSequence getTextAfterCursor(int length, int flags) {
|
||||||
Log.d(TAG, "getTextAfterCursor: " + length + ":" + flags);
|
log("getTextAfterCursor: " + length + ":" + flags);
|
||||||
if (length < 0) {
|
if (length < 0) {
|
||||||
Log.i(TAG, "getTextAfterCursor: returning null to due to an invalid length=" + length);
|
Log.i("darkfi", "getTextAfterCursor: returning null to due to an invalid length=" + length);
|
||||||
return null;
|
return null;
|
||||||
}
|
}
|
||||||
return super.getTextAfterCursor(length, flags);
|
return super.getTextAfterCursor(length, flags);
|
||||||
@@ -364,9 +367,9 @@ public class InputConnection extends BaseInputConnection implements View.OnKeyLi
|
|||||||
// From BaseInputConnection
|
// From BaseInputConnection
|
||||||
@Override
|
@Override
|
||||||
public CharSequence getTextBeforeCursor(int length, int flags) {
|
public CharSequence getTextBeforeCursor(int length, int flags) {
|
||||||
Log.d(TAG, "getTextBeforeCursor: " + length + ", flags=" + flags);
|
log("getTextBeforeCursor: " + length + ", flags=" + flags);
|
||||||
if (length < 0) {
|
if (length < 0) {
|
||||||
Log.i(TAG, "getTextBeforeCursor: returning null to due to an invalid length=" + length);
|
Log.i("darkfi", "getTextBeforeCursor: returning null to due to an invalid length=" + length);
|
||||||
return null;
|
return null;
|
||||||
}
|
}
|
||||||
return super.getTextBeforeCursor(length, flags);
|
return super.getTextBeforeCursor(length, flags);
|
||||||
@@ -375,39 +378,39 @@ public class InputConnection extends BaseInputConnection implements View.OnKeyLi
|
|||||||
// From BaseInputConnection
|
// From BaseInputConnection
|
||||||
@Override
|
@Override
|
||||||
public boolean requestCursorUpdates(int cursorUpdateMode) {
|
public boolean requestCursorUpdates(int cursorUpdateMode) {
|
||||||
Log.d(TAG, "Request cursor updates: " + cursorUpdateMode);
|
log("Request cursor updates: " + cursorUpdateMode);
|
||||||
return super.requestCursorUpdates(cursorUpdateMode);
|
return super.requestCursorUpdates(cursorUpdateMode);
|
||||||
}
|
}
|
||||||
|
|
||||||
// From BaseInputConnection
|
// From BaseInputConnection
|
||||||
@Override
|
@Override
|
||||||
public void closeConnection() {
|
public void closeConnection() {
|
||||||
Log.d(TAG, "closeConnection");
|
log("closeConnection");
|
||||||
super.closeConnection();
|
super.closeConnection();
|
||||||
}
|
}
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
public boolean setImeConsumesInput(boolean imeConsumesInput) {
|
public boolean setImeConsumesInput(boolean imeConsumesInput) {
|
||||||
Log.d(TAG, "setImeConsumesInput: " + imeConsumesInput);
|
log("setImeConsumesInput: " + imeConsumesInput);
|
||||||
return super.setImeConsumesInput(imeConsumesInput);
|
return super.setImeConsumesInput(imeConsumesInput);
|
||||||
}
|
}
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
public ExtractedText getExtractedText(ExtractedTextRequest request, int flags) {
|
public ExtractedText getExtractedText(ExtractedTextRequest request, int flags) {
|
||||||
Log.d(TAG, "getExtractedText");
|
log("getExtractedText");
|
||||||
return super.getExtractedText(request, flags);
|
return super.getExtractedText(request, flags);
|
||||||
}
|
}
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
public boolean performPrivateCommand(String action, Bundle data) {
|
public boolean performPrivateCommand(String action, Bundle data) {
|
||||||
Log.d(TAG, "performPrivateCommand");
|
log("performPrivateCommand");
|
||||||
return super.performPrivateCommand(action, data);
|
return super.performPrivateCommand(action, data);
|
||||||
}
|
}
|
||||||
|
|
||||||
private void immUpdateSelection() {
|
private void immUpdateSelection() {
|
||||||
Pair selection = this.getSelection();
|
Pair selection = this.getSelection();
|
||||||
Pair cr = this.getComposingRegion();
|
Pair cr = this.getComposingRegion();
|
||||||
Log.d(TAG,
|
log(
|
||||||
"immUpdateSelection: " + selection.first + "," + selection.second + ". " + cr.first + ","
|
"immUpdateSelection: " + selection.first + "," + selection.second + ". " + cr.first + ","
|
||||||
+ cr.second);
|
+ cr.second);
|
||||||
settings.mEditorInfo.initialSelStart = selection.first;
|
settings.mEditorInfo.initialSelStart = selection.first;
|
||||||
@@ -428,8 +431,8 @@ public class InputConnection extends BaseInputConnection implements View.OnKeyLi
|
|||||||
return false;
|
return false;
|
||||||
}
|
}
|
||||||
int keyCode = event.getKeyCode();
|
int keyCode = event.getKeyCode();
|
||||||
Log.d(
|
log(
|
||||||
TAG, String.format("processKeyEvent(key=%d) text=%s", keyCode, this.mEditable.toString()));
|
"processKeyEvent(key=" + keyCode + ") text=" + this.mEditable.toString());
|
||||||
// Filter out Enter keys if multi-line mode is disabled.
|
// Filter out Enter keys if multi-line mode is disabled.
|
||||||
if ((settings.mEditorInfo.inputType & EditorInfo.TYPE_TEXT_FLAG_MULTI_LINE) == 0
|
if ((settings.mEditorInfo.inputType & EditorInfo.TYPE_TEXT_FLAG_MULTI_LINE) == 0
|
||||||
&& (keyCode == KeyEvent.KEYCODE_ENTER || keyCode == KeyEvent.KEYCODE_NUMPAD_ENTER)
|
&& (keyCode == KeyEvent.KEYCODE_ENTER || keyCode == KeyEvent.KEYCODE_NUMPAD_ENTER)
|
||||||
@@ -503,7 +506,7 @@ public class InputConnection extends BaseInputConnection implements View.OnKeyLi
|
|||||||
}
|
}
|
||||||
|
|
||||||
if (selection.first != selection.second) {
|
if (selection.first != selection.second) {
|
||||||
Log.d(TAG, String.format("processKeyEvent: deleting selection"));
|
log("processKeyEvent: deleting selection");
|
||||||
this.mEditable.delete(selection.first, selection.second);
|
this.mEditable.delete(selection.first, selection.second);
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -525,7 +528,7 @@ public class InputConnection extends BaseInputConnection implements View.OnKeyLi
|
|||||||
this.setComposingRegion(composingRegion.first, composingRegion.second);
|
this.setComposingRegion(composingRegion.first, composingRegion.second);
|
||||||
int new_cursor = selection.first + charsToInsert.length();
|
int new_cursor = selection.first + charsToInsert.length();
|
||||||
setSelection(new_cursor, new_cursor);
|
setSelection(new_cursor, new_cursor);
|
||||||
Log.d(TAG, String.format("processKeyEvent: exit, text=%s", this.mEditable.toString()));
|
log("processKeyEvent: exit, text=" + this.mEditable.toString());
|
||||||
return true;
|
return true;
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -594,7 +597,7 @@ public class InputConnection extends BaseInputConnection implements View.OnKeyLi
|
|||||||
*/
|
*/
|
||||||
@Override
|
@Override
|
||||||
public boolean performEditorAction(int action) {
|
public boolean performEditorAction(int action) {
|
||||||
Log.d(TAG, "performEditorAction, action=" + action);
|
log("performEditorAction, action=" + action);
|
||||||
if (action == IME_ACTION_UNSPECIFIED) {
|
if (action == IME_ACTION_UNSPECIFIED) {
|
||||||
// Super emulates Enter key press/release
|
// Super emulates Enter key press/release
|
||||||
return super.performEditorAction(action);
|
return super.performEditorAction(action);
|
||||||
|
|||||||
@@ -173,8 +173,11 @@ impl GameTextInput {
|
|||||||
let mut new_focus = state.lock();
|
let mut new_focus = state.lock();
|
||||||
// Mark new state as active
|
// Mark new state as active
|
||||||
new_focus.is_active = true;
|
new_focus.is_active = true;
|
||||||
|
let new_state = new_focus.state.clone();
|
||||||
|
drop(new_focus);
|
||||||
|
|
||||||
// Push changes to the Java side
|
// Push changes to the Java side
|
||||||
self.push_update(&new_focus.state);
|
self.push_update(&new_state);
|
||||||
}
|
}
|
||||||
|
|
||||||
pub fn push_update(&self, state: &AndroidTextInputState) {
|
pub fn push_update(&self, state: &AndroidTextInputState) {
|
||||||
@@ -192,6 +195,21 @@ impl GameTextInput {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
pub fn set_select(&self, start: i32, end: i32) -> Result<(), ()> {
|
||||||
|
let Some(input_connection) = *self.input_connection.read() else {
|
||||||
|
w!("push_update() - no input_connection set");
|
||||||
|
return Err(())
|
||||||
|
};
|
||||||
|
let is_success = unsafe {
|
||||||
|
let env = android::attach_jni_env();
|
||||||
|
call_bool_method!(env, input_connection, "setSelection", "(II)Z", start, end)
|
||||||
|
};
|
||||||
|
if is_success == 0u8 {
|
||||||
|
return Err(())
|
||||||
|
}
|
||||||
|
Ok(())
|
||||||
|
}
|
||||||
|
|
||||||
pub fn set_input_connection(&self, input_connection: ndk_sys::jobject) {
|
pub fn set_input_connection(&self, input_connection: ndk_sys::jobject) {
|
||||||
unsafe {
|
unsafe {
|
||||||
let env = android::attach_jni_env();
|
let env = android::attach_jni_env();
|
||||||
|
|||||||
@@ -87,4 +87,22 @@ impl AndroidTextInput {
|
|||||||
gti.push_update(&state);
|
gti.push_update(&state);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
pub fn set_select(&self, select_start: usize, select_end: usize) {
|
||||||
|
//t!("set_select({select_start}, {select_end})");
|
||||||
|
// Always update our own state.
|
||||||
|
let mut ours = self.state.lock();
|
||||||
|
let state = &mut ours.state;
|
||||||
|
assert!(select_start <= state.text.len());
|
||||||
|
assert!(select_end <= state.text.len());
|
||||||
|
state.select = (select_start, select_end);
|
||||||
|
let is_active = ours.is_active;
|
||||||
|
drop(ours);
|
||||||
|
|
||||||
|
// Only update java state when this input is active
|
||||||
|
if is_active {
|
||||||
|
let gti = GAME_TEXT_INPUT.get().unwrap();
|
||||||
|
gti.set_select(select_start as i32, select_end as i32).unwrap();
|
||||||
|
}
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -1559,15 +1559,21 @@ pub async fn make(
|
|||||||
let atom = &mut render_api.make_guard(gfxtag!("edit select task"));
|
let atom = &mut render_api.make_guard(gfxtag!("edit select task"));
|
||||||
if editz_select_text.is_null(0).unwrap() {
|
if editz_select_text.is_null(0).unwrap() {
|
||||||
info!(target: "app::chat", "selection changed: null");
|
info!(target: "app::chat", "selection changed: null");
|
||||||
|
// Avoid triggering unecessary redraws
|
||||||
|
if actions_is_visible.get() {
|
||||||
actions_is_visible.set(atom, false);
|
actions_is_visible.set(atom, false);
|
||||||
pasta_is_visible2.set(atom, false);
|
pasta_is_visible2.set(atom, false);
|
||||||
|
}
|
||||||
} else {
|
} else {
|
||||||
let select_text = editz_select_text.get_str(0).unwrap();
|
let select_text = editz_select_text.get_str(0).unwrap();
|
||||||
info!(target: "app::chat", "selection changed: {select_text}");
|
info!(target: "app::chat", "selection changed: {select_text}");
|
||||||
|
// Avoid triggering unecessary redraws
|
||||||
|
if !actions_is_visible.get() {
|
||||||
actions_is_visible.set(atom, true);
|
actions_is_visible.set(atom, true);
|
||||||
pasta_is_visible2.set(atom, false);
|
pasta_is_visible2.set(atom, false);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
}
|
||||||
});
|
});
|
||||||
app.tasks.lock().unwrap().push(editz_select_task);
|
app.tasks.lock().unwrap().push(editz_select_task);
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -529,15 +529,23 @@ pub async fn make(app: &App, window: SceneNodePtr, i18n_fish: &I18nBabelFish) {
|
|||||||
|
|
||||||
let chatdb_path = get_chatdb_path();
|
let chatdb_path = get_chatdb_path();
|
||||||
let db = sled::open(chatdb_path).expect("cannot open sleddb");
|
let db = sled::open(chatdb_path).expect("cannot open sleddb");
|
||||||
//for channel in CHANNELS {
|
for channel in CHANNELS {
|
||||||
chat::make(app, content.clone(), "dev", &db, i18n_fish, emoji_meshes.clone(), is_first_time)
|
chat::make(
|
||||||
|
app,
|
||||||
|
content.clone(),
|
||||||
|
channel,
|
||||||
|
&db,
|
||||||
|
i18n_fish,
|
||||||
|
emoji_meshes.clone(),
|
||||||
|
is_first_time,
|
||||||
|
)
|
||||||
.await;
|
.await;
|
||||||
//}
|
}
|
||||||
//menu::make(app, content.clone(), i18n_fish).await;
|
menu::make(app, content.clone(), i18n_fish).await;
|
||||||
|
|
||||||
// @@@ Debug stuff @@@
|
// @@@ Debug stuff @@@
|
||||||
let chatview_node = app.sg_root.lookup_node("/window/content/dev_chat_layer").unwrap();
|
//let chatview_node = app.sg_root.lookup_node("/window/content/dev_chat_layer").unwrap();
|
||||||
chatview_node.set_property_bool(atom, Role::App, "is_visible", true).unwrap();
|
//chatview_node.set_property_bool(atom, Role::App, "is_visible", true).unwrap();
|
||||||
//let menu_node = app.sg_root.lookup_node("/window/content/menu_layer").unwrap();
|
//let menu_node = app.sg_root.lookup_node("/window/content/menu_layer").unwrap();
|
||||||
//menu_node.set_property_bool(atom, Role::App, "is_visible", false).unwrap();
|
//menu_node.set_property_bool(atom, Role::App, "is_visible", false).unwrap();
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -132,9 +132,10 @@ impl Editor {
|
|||||||
let cursor_idx = cursor.index();
|
let cursor_idx = cursor.index();
|
||||||
t!(" move_to_pos: {cursor_idx}");
|
t!(" move_to_pos: {cursor_idx}");
|
||||||
assert!(cursor_idx <= self.state.text.len());
|
assert!(cursor_idx <= self.state.text.len());
|
||||||
|
assert_eq!(self.state.text, self.text.get());
|
||||||
self.state.select = (cursor_idx, cursor_idx);
|
self.state.select = (cursor_idx, cursor_idx);
|
||||||
self.state.compose = None;
|
self.state.compose = None;
|
||||||
self.input.set_state(self.state.clone());
|
self.input.set_select(cursor_idx, cursor_idx);
|
||||||
}
|
}
|
||||||
|
|
||||||
pub async fn select_word_at_point(&mut self, pos: Point) {
|
pub async fn select_word_at_point(&mut self, pos: Point) {
|
||||||
@@ -216,10 +217,12 @@ impl Editor {
|
|||||||
parley::Selection::new(anchor, focus)
|
parley::Selection::new(anchor, focus)
|
||||||
}
|
}
|
||||||
pub async fn set_selection(&mut self, select_start: usize, select_end: usize) {
|
pub async fn set_selection(&mut self, select_start: usize, select_end: usize) {
|
||||||
self.state.text = self.text.get();
|
assert!(select_start <= self.state.text.len());
|
||||||
|
assert!(select_end <= self.state.text.len());
|
||||||
|
assert_eq!(self.state.text, self.text.get());
|
||||||
self.state.select = (select_start, select_end);
|
self.state.select = (select_start, select_end);
|
||||||
self.state.compose = None;
|
self.state.compose = None;
|
||||||
self.input.set_state(self.state.clone());
|
self.input.set_select(select_start, select_end);
|
||||||
}
|
}
|
||||||
|
|
||||||
#[allow(dead_code)]
|
#[allow(dead_code)]
|
||||||
|
|||||||
@@ -1363,16 +1363,17 @@ impl UIObject for BaseEdit {
|
|||||||
fn init(&self) {
|
fn init(&self) {
|
||||||
let mut guard = self.editor.lock_blocking();
|
let mut guard = self.editor.lock_blocking();
|
||||||
assert!(guard.is_none());
|
assert!(guard.is_none());
|
||||||
let mut editor = Editor::new(
|
let editor = Editor::new(
|
||||||
self.text.clone(),
|
self.text.clone(),
|
||||||
self.font_size.clone(),
|
self.font_size.clone(),
|
||||||
self.text_color.clone(),
|
self.text_color.clone(),
|
||||||
self.window_scale.clone(),
|
self.window_scale.clone(),
|
||||||
self.lineheight.clone(),
|
self.lineheight.clone(),
|
||||||
);
|
);
|
||||||
let atom = &mut PropertyAtomicGuard::none();
|
// For Android you can do this:
|
||||||
self.text.set(atom, "the quick brown fox jumped over the");
|
//let atom = &mut PropertyAtomicGuard::none();
|
||||||
smol::block_on(editor.on_text_prop_changed());
|
//self.text.set(atom, "the quick brown fox jumped over the");
|
||||||
|
//smol::block_on(editor.on_text_prop_changed());
|
||||||
*guard = Some(editor);
|
*guard = Some(editor);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|||||||
Reference in New Issue
Block a user