Rewrote how input text box focus is decided
This commit is contained in:
parent
1585e0aa67
commit
8b3e321ab5
41 changed files with 317 additions and 490 deletions
2
android-project/app/proguard-rules.pro
vendored
2
android-project/app/proguard-rules.pro
vendored
|
|
@ -17,7 +17,7 @@
|
|||
#}
|
||||
|
||||
-keep,includedescriptorclasses,allowoptimization class com.erroratline0.infinipaint.InfiniPaint {
|
||||
void startTextInput();
|
||||
void startTextInput(int);
|
||||
}
|
||||
|
||||
-keep,includedescriptorclasses,allowoptimization class org.libsdl.app.SDLActivity {
|
||||
|
|
|
|||
|
|
@ -40,7 +40,19 @@ public class InfiniPaint extends SDLActivity {
|
|||
}
|
||||
|
||||
static class StartInfiniPaintTextInputTask implements Runnable {
|
||||
public StartInfiniPaintTextInputTask() {}
|
||||
public StartInfiniPaintTextInputTask(int textboxID, String str, int selectionBegin, int selectionEnd, int inputType) {
|
||||
mTextBoxID = textboxID;
|
||||
mStr = str;
|
||||
mSelectionBegin = selectionBegin;
|
||||
mSelectionEnd = selectionEnd;
|
||||
mInputType = inputType;
|
||||
}
|
||||
|
||||
int mTextBoxID;
|
||||
String mStr;
|
||||
int mSelectionBegin;
|
||||
int mSelectionEnd;
|
||||
int mInputType;
|
||||
|
||||
@Override
|
||||
public void run() {
|
||||
|
|
@ -50,9 +62,11 @@ public class InfiniPaint extends SDLActivity {
|
|||
mTextEdit = new InfiniPaintTextBoxView(getContext());
|
||||
mLayout.addView(mTextEdit, params);
|
||||
}
|
||||
else
|
||||
else {
|
||||
mTextEdit.setLayoutParams(params);
|
||||
}
|
||||
|
||||
mTextEdit.setInitialData(mTextBoxID, mStr, mSelectionBegin, mSelectionEnd, mInputType);
|
||||
mTextEdit.setVisibility(View.VISIBLE);
|
||||
mTextEdit.requestFocus();
|
||||
InputMethodManager imm = (InputMethodManager) getContext().getSystemService(Context.INPUT_METHOD_SERVICE);
|
||||
|
|
@ -63,8 +77,8 @@ public class InfiniPaint extends SDLActivity {
|
|||
}
|
||||
}
|
||||
|
||||
static public void startTextInput() {
|
||||
mSingleton.commandHandler.post(new StartInfiniPaintTextInputTask());
|
||||
static public void startTextInput(int textboxID, String str, int selectionBegin, int selectionEnd, int inputType) {
|
||||
mSingleton.commandHandler.post(new StartInfiniPaintTextInputTask(textboxID, str, selectionBegin, selectionEnd, inputType));
|
||||
}
|
||||
|
||||
static InfiniPaintTextBoxView mTextEdit;
|
||||
|
|
|
|||
|
|
@ -9,6 +9,7 @@ import android.os.Bundle;
|
|||
import android.os.CancellationSignal;
|
||||
import android.os.Handler;
|
||||
import android.text.Editable;
|
||||
import android.text.SpannableStringBuilder;
|
||||
import android.view.*;
|
||||
import android.view.inputmethod.BaseInputConnection;
|
||||
import android.view.inputmethod.CompletionInfo;
|
||||
|
|
@ -38,16 +39,25 @@ import android.widget.EditText;
|
|||
import org.libsdl.app.SDL;
|
||||
import org.libsdl.app.SDLActivity;
|
||||
|
||||
class InfiniPaintTextBoxInputConnection extends BaseInputConnection
|
||||
{
|
||||
public class InfiniPaintTextBoxInputConnection extends BaseInputConnection {
|
||||
public static native void nativeCommitText(int textboxID, String text, int newCursorPosition);
|
||||
public static native void nativeDeleteSurroundingText(int textboxID, int beforeLength, int afterLength);
|
||||
public static native void nativeSetSelection(int textboxID, int start, int end);
|
||||
|
||||
protected EditText mEditText;
|
||||
protected String mCommittedText = "";
|
||||
protected int mTextBoxID;
|
||||
|
||||
InfiniPaintTextBoxInputConnection(View targetView, boolean fullEditor) {
|
||||
super(targetView, fullEditor);
|
||||
mEditText = new EditText(SDL.getContext());
|
||||
}
|
||||
|
||||
public void setInitialData(int textboxID, String initialText, int begin, int end) {
|
||||
mTextBoxID = textboxID;
|
||||
mEditText.setText(initialText);
|
||||
mEditText.setSelection(begin, end);
|
||||
}
|
||||
|
||||
@Override
|
||||
public Editable getEditable() {
|
||||
return mEditText.getEditableText();
|
||||
|
|
@ -63,7 +73,7 @@ class InfiniPaintTextBoxInputConnection extends BaseInputConnection
|
|||
*/
|
||||
|
||||
/*
|
||||
* Return DOES still generate a key event, however. So rather than using it as the 'click a button' key
|
||||
* Return DOES still generate a key event, however. So rather than using it as the 'click a button' key
|
||||
* as we do with physical keyboards, let's just use it to hide the keyboard.
|
||||
*/
|
||||
|
||||
|
|
@ -78,253 +88,34 @@ class InfiniPaintTextBoxInputConnection extends BaseInputConnection
|
|||
|
||||
@Override
|
||||
public boolean commitText(CharSequence text, int newCursorPosition) {
|
||||
if (!super.commitText(text, newCursorPosition)) {
|
||||
if (!super.commitText(text, newCursorPosition))
|
||||
return false;
|
||||
}
|
||||
updateText();
|
||||
nativeCommitText(mTextBoxID, text.toString(), newCursorPosition);
|
||||
return true;
|
||||
}
|
||||
|
||||
@Override
|
||||
public boolean setComposingText(CharSequence text, int newCursorPosition) {
|
||||
if (!super.setComposingText(text, newCursorPosition)) {
|
||||
if (!super.setComposingText(text, newCursorPosition))
|
||||
return false;
|
||||
}
|
||||
updateText();
|
||||
nativeCommitText(mTextBoxID, text.toString(), newCursorPosition);
|
||||
return true;
|
||||
}
|
||||
|
||||
@Override
|
||||
public boolean deleteSurroundingText(int beforeLength, int afterLength) {
|
||||
// Workaround to capture backspace key. Ref: http://stackoverflow.com/questions>/14560344/android-backspace-in-webview-baseinputconnection
|
||||
// and https://bugzilla.libsdl.org/show_bug.cgi?id=2265
|
||||
if (beforeLength > 0 && afterLength == 0) {
|
||||
// backspace(s)
|
||||
while (beforeLength-- > 0) {
|
||||
}
|
||||
return true;
|
||||
}
|
||||
|
||||
if (!super.deleteSurroundingText(beforeLength, afterLength)) {
|
||||
if (!super.deleteSurroundingText(beforeLength, afterLength))
|
||||
return false;
|
||||
}
|
||||
updateText();
|
||||
nativeDeleteSurroundingText(mTextBoxID, beforeLength, afterLength);
|
||||
return true;
|
||||
}
|
||||
|
||||
protected void updateText() {
|
||||
final Editable content = getEditable();
|
||||
if (content == null) {
|
||||
return;
|
||||
}
|
||||
|
||||
String text = content.toString();
|
||||
int compareLength = Math.min(text.length(), mCommittedText.length());
|
||||
int matchLength, offset;
|
||||
|
||||
/* Backspace over characters that are no longer in the string */
|
||||
for (matchLength = 0; matchLength < compareLength; ) {
|
||||
int codePoint = mCommittedText.codePointAt(matchLength);
|
||||
if (codePoint != text.codePointAt(matchLength)) {
|
||||
break;
|
||||
}
|
||||
matchLength += Character.charCount(codePoint);
|
||||
}
|
||||
/* FIXME: This doesn't handle graphemes, like '🌬️' */
|
||||
for (offset = matchLength; offset < mCommittedText.length(); ) {
|
||||
int codePoint = mCommittedText.codePointAt(offset);
|
||||
offset += Character.charCount(codePoint);
|
||||
}
|
||||
|
||||
if (matchLength < text.length()) {
|
||||
String pendingText = text.subSequence(matchLength, text.length()).toString();
|
||||
if (!SDLActivity.dispatchingKeyEvent()) {
|
||||
for (offset = 0; offset < pendingText.length(); ) {
|
||||
int codePoint = pendingText.codePointAt(offset);
|
||||
if (codePoint == '\n') {
|
||||
if (SDLActivity.onNativeSoftReturnKey()) {
|
||||
return;
|
||||
}
|
||||
}
|
||||
/* Higher code points don't generate simulated scancodes */
|
||||
if (codePoint > 0 && codePoint < 128) {
|
||||
}
|
||||
offset += Character.charCount(codePoint);
|
||||
}
|
||||
}
|
||||
}
|
||||
mCommittedText = text;
|
||||
@Override
|
||||
public boolean setSelection(int start, int end) {
|
||||
if(!super.setSelection(start, end))
|
||||
return false;
|
||||
nativeSetSelection(mTextBoxID, start, end);
|
||||
return true;
|
||||
}
|
||||
}
|
||||
|
||||
//class InfiniPaintTextBoxInputConnection extends BaseInputConnection {
|
||||
// InfiniPaintTextBoxInputConnection(View targetView, boolean fullEditor) {
|
||||
// super(targetView, fullEditor);
|
||||
// }
|
||||
//
|
||||
// public native void nativeBeginBatchEdit();
|
||||
// public native void nativeClearMetaKeyStates(int states);
|
||||
// public native void nativeSetComposingText(CharSequence text, int newCursorPosition);
|
||||
// public native void nativeSetComposingRegion(int start, int end);
|
||||
// public native void nativeSetSelection(int start, int end);
|
||||
// public native void nativeCommitCorrection(int offset, CharSequence oldText, CharSequence newText);
|
||||
// public native void nativeCommitText(CharSequence text, int newCursorPosition);
|
||||
// public native void nativeDeleteSurroundingText(int beforeLength, int afterLength);
|
||||
// public native void nativeDeleteSurroundingTextInCodePoints(int beforeLength, int afterLength);
|
||||
// public native void nativeEndBatchEdit();
|
||||
// public native void nativeFinishComposingText();
|
||||
// public native CharSequence nativeGetSelectedText();
|
||||
// public native CharSequence nativeGetTextAfterCursor(int n);
|
||||
// public native CharSequence nativeGetTextBeforeCursor(int n);
|
||||
// public native void nativePerformContextMenuAction(int action);
|
||||
// public native void nativePerformEditorAction(int action);
|
||||
//
|
||||
// @Override
|
||||
// public boolean beginBatchEdit() {
|
||||
// nativeBeginBatchEdit();
|
||||
// return true;
|
||||
// }
|
||||
//
|
||||
// @Override
|
||||
// public boolean clearMetaKeyStates(int states) {
|
||||
// nativeClearMetaKeyStates(states);
|
||||
// return true;
|
||||
// }
|
||||
//
|
||||
// @Override
|
||||
// public boolean performSpellCheck() {
|
||||
// return true;
|
||||
// }
|
||||
//
|
||||
// @Override
|
||||
// public TextSnapshot takeSnapshot() {
|
||||
// return null;
|
||||
// }
|
||||
//
|
||||
// @Override
|
||||
// public CharSequence getTextBeforeCursor(int n, int flags) {
|
||||
// return nativeGetTextBeforeCursor(n);
|
||||
// }
|
||||
//
|
||||
// @Override
|
||||
// public CharSequence getTextAfterCursor(int n, int flags) {
|
||||
// return nativeGetTextAfterCursor(n);
|
||||
// }
|
||||
//
|
||||
// @Override
|
||||
// public CharSequence getSelectedText(int i) {
|
||||
// return nativeGetSelectedText();
|
||||
// }
|
||||
//
|
||||
// @Override
|
||||
// public int getCursorCapsMode(int i) {
|
||||
// return CAP_MODE_SENTENCES;
|
||||
// }
|
||||
//
|
||||
// @Override
|
||||
// public ExtractedText getExtractedText(ExtractedTextRequest extractedTextRequest, int i) {
|
||||
// return null;
|
||||
// }
|
||||
//
|
||||
// @Override
|
||||
// public boolean deleteSurroundingText(int i, int i1) {
|
||||
// nativeDeleteSurroundingText(i, i1);
|
||||
// return true;
|
||||
// }
|
||||
//
|
||||
// @Override
|
||||
// public boolean deleteSurroundingTextInCodePoints(int beforeLength, int afterLength) {
|
||||
// nativeDeleteSurroundingTextInCodePoints(beforeLength, afterLength);
|
||||
// return true;
|
||||
// }
|
||||
//
|
||||
// @Override
|
||||
// public boolean setComposingRegion(int i, int i1) {
|
||||
// nativeSetComposingRegion(i, i1);
|
||||
// return true;
|
||||
// }
|
||||
//
|
||||
// @Override
|
||||
// public boolean finishComposingText() {
|
||||
// nativeFinishComposingText();
|
||||
// return true;
|
||||
// }
|
||||
//
|
||||
// @Override
|
||||
// public boolean commitCompletion(CompletionInfo completionInfo) {
|
||||
// return true;
|
||||
// }
|
||||
//
|
||||
// @Override
|
||||
// public boolean commitCorrection(CorrectionInfo correctionInfo) {
|
||||
// nativeCommitCorrection(correctionInfo.getOffset(), correctionInfo.getOldText(), correctionInfo.getNewText());
|
||||
// return true;
|
||||
// }
|
||||
//
|
||||
// @Override
|
||||
// public boolean setSelection(int i, int i1) {
|
||||
// nativeSetSelection(i, i1);
|
||||
// return true;
|
||||
// }
|
||||
//
|
||||
// @Override
|
||||
// public boolean performEditorAction(int i) {
|
||||
// nativePerformEditorAction(i);
|
||||
// return true;
|
||||
// }
|
||||
//
|
||||
// @Override
|
||||
// public boolean performContextMenuAction(int i) {
|
||||
// nativePerformContextMenuAction(i);
|
||||
// return true;
|
||||
// }
|
||||
//
|
||||
// @Override
|
||||
// public boolean endBatchEdit() {
|
||||
// nativeEndBatchEdit();
|
||||
// return true;
|
||||
// }
|
||||
//
|
||||
// @Override
|
||||
// public boolean sendKeyEvent(KeyEvent keyEvent) {
|
||||
// return true;
|
||||
// }
|
||||
//
|
||||
// @Override
|
||||
// public boolean reportFullscreenMode(boolean b) {
|
||||
// return true;
|
||||
// }
|
||||
//
|
||||
// @Override
|
||||
// public boolean performPrivateCommand(String s, Bundle bundle) {
|
||||
// return false;
|
||||
// }
|
||||
//
|
||||
// @Override
|
||||
// public boolean requestCursorUpdates(int i) {
|
||||
// return true;
|
||||
// }
|
||||
//
|
||||
// @Override
|
||||
// public Handler getHandler() {
|
||||
// return null;
|
||||
// }
|
||||
//
|
||||
// @Override
|
||||
// public boolean commitContent(InputContentInfo inputContentInfo, int i, Bundle bundle) {
|
||||
// return true;
|
||||
// }
|
||||
//
|
||||
// @Override
|
||||
// public boolean commitText(CharSequence text, int newCursorPosition) {
|
||||
// nativeCommitText(text, newCursorPosition);
|
||||
// return true;
|
||||
// }
|
||||
//
|
||||
// @Override
|
||||
// public boolean setComposingText(CharSequence text, int newCursorPosition) {
|
||||
// nativeSetComposingText(text, newCursorPosition);
|
||||
// return true;
|
||||
// }
|
||||
//}
|
||||
|
||||
|
|
|
|||
|
|
@ -8,7 +8,13 @@ import android.view.inputmethod.InputConnection;
|
|||
|
||||
public class InfiniPaintTextBoxView extends View
|
||||
{
|
||||
InputConnection ic;
|
||||
public InfiniPaintTextBoxInputConnection ic;
|
||||
|
||||
int mTextBoxID;
|
||||
String mStr;
|
||||
int mSelectionBegin;
|
||||
int mSelectionEnd;
|
||||
int mInputType;
|
||||
|
||||
InfiniPaintTextBoxView(Context context) {
|
||||
super(context);
|
||||
|
|
@ -16,6 +22,14 @@ public class InfiniPaintTextBoxView extends View
|
|||
setFocusable(true);
|
||||
}
|
||||
|
||||
void setInitialData(int textboxID, String str, int selectionBegin, int selectionEnd, int inputType) {
|
||||
mTextBoxID = textboxID;
|
||||
mStr = str;
|
||||
mSelectionBegin = selectionBegin;
|
||||
mSelectionEnd = selectionEnd;
|
||||
mInputType = inputType;
|
||||
}
|
||||
|
||||
@Override
|
||||
public boolean onCheckIsTextEditor() {
|
||||
return true;
|
||||
|
|
@ -24,8 +38,9 @@ public class InfiniPaintTextBoxView extends View
|
|||
@Override
|
||||
public InputConnection onCreateInputConnection(EditorInfo outAttrs) {
|
||||
ic = new InfiniPaintTextBoxInputConnection(this, true);
|
||||
ic.setInitialData(mTextBoxID, mStr, mSelectionBegin, mSelectionEnd);
|
||||
|
||||
outAttrs.inputType = InputType.TYPE_CLASS_TEXT;
|
||||
outAttrs.inputType = mInputType;
|
||||
outAttrs.imeOptions = EditorInfo.IME_FLAG_NO_EXTRACT_UI |
|
||||
EditorInfo.IME_FLAG_NO_FULLSCREEN /* API 11 */ |
|
||||
EditorInfo.IME_ACTION_DONE;
|
||||
|
|
|
|||
|
|
@ -0,0 +1,14 @@
|
|||
package com.erroratline0.infinipaint;
|
||||
|
||||
public class IntPair {
|
||||
IntPair() {
|
||||
first = 0;
|
||||
second = 0;
|
||||
}
|
||||
IntPair(int initFirst, int initSecond) {
|
||||
first = initFirst;
|
||||
second = initSecond;
|
||||
}
|
||||
public int first;
|
||||
public int second;
|
||||
}
|
||||
|
|
@ -11,15 +11,15 @@ namespace AndroidJNICalls {
|
|||
InputManager* globalInputManager;
|
||||
std::mutex globalCallMutex;
|
||||
|
||||
void startTextInput() {
|
||||
void startTextInput(int input_type) {
|
||||
JNIEnv* env = static_cast<JNIEnv*>(SDL_GetAndroidJNIEnv());
|
||||
Logger::get().log("INFO", std::to_string((uint64_t)env) + " jni env value");
|
||||
jobject activity = (jobject)SDL_GetAndroidActivity();
|
||||
Logger::get().log("INFO", std::to_string((uint64_t)activity) + " activity value");
|
||||
jclass clazz = env->GetObjectClass(activity);
|
||||
jmethodID method_id = env->GetStaticMethodID(clazz, "startTextInput", "()V");
|
||||
jmethodID method_id = env->GetStaticMethodID(clazz, "startTextInput", "(I)V");
|
||||
Logger::get().log("INFO", std::to_string((uint64_t)method_id) + " method value");
|
||||
env->CallStaticVoidMethod(clazz, method_id);
|
||||
env->CallStaticVoidMethod(clazz, method_id, input_type);
|
||||
env->DeleteLocalRef(activity);
|
||||
env->DeleteLocalRef(clazz);
|
||||
}
|
||||
|
|
@ -35,6 +35,27 @@ JNIEnv* jniEnv;
|
|||
|
||||
using namespace AndroidJNICalls;
|
||||
|
||||
|
||||
// https://stackoverflow.com/questions/41820039/jstringjni-to-stdstringc-with-utf8-characters
|
||||
std::string jstring2string(JNIEnv *env, jstring jStr) {
|
||||
if (!jStr)
|
||||
return "";
|
||||
|
||||
const jclass stringClass = env->GetObjectClass(jStr);
|
||||
const jmethodID getBytes = env->GetMethodID(stringClass, "getBytes", "(Ljava/lang/String;)[B");
|
||||
const jbyteArray stringJbytes = (jbyteArray) env->CallObjectMethod(jStr, getBytes, env->NewStringUTF("UTF-8"));
|
||||
|
||||
size_t length = (size_t) env->GetArrayLength(stringJbytes);
|
||||
jbyte* pBytes = env->GetByteArrayElements(stringJbytes, NULL);
|
||||
|
||||
std::string ret = std::string((char *)pBytes, length);
|
||||
env->ReleaseByteArrayElements(stringJbytes, pBytes, JNI_ABORT);
|
||||
|
||||
env->DeleteLocalRef(stringJbytes);
|
||||
env->DeleteLocalRef(stringClass);
|
||||
return ret;
|
||||
}
|
||||
|
||||
extern "C"
|
||||
JNIEXPORT void JNICALL
|
||||
Java_com_erroratline0_infinipaint_InfiniPaintSurface_nativeInfiniPaintUpdateIMESafeArea(JNIEnv *env, jclass clazz, jint top, jint bottom, jint left, jint right) {
|
||||
|
|
@ -46,103 +67,12 @@ Java_com_erroratline0_infinipaint_InfiniPaintSurface_nativeInfiniPaintUpdateIMES
|
|||
|
||||
extern "C"
|
||||
JNIEXPORT void JNICALL
|
||||
Java_com_erroratline0_infinipaint_InfiniPaintTextBoxInputConnection_nativeBeginBatchEdit(
|
||||
JNIEnv *env, jobject jobject1) {
|
||||
// TODO: implement nativeBeginBatchEdit()
|
||||
}
|
||||
extern "C"
|
||||
JNIEXPORT void JNICALL
|
||||
Java_com_erroratline0_infinipaint_InfiniPaintTextBoxInputConnection_nativeClearMetaKeyStates(
|
||||
JNIEnv *env, jobject jobject1, jint states) {
|
||||
// TODO: implement nativeClearMetaKeyStates()
|
||||
}
|
||||
extern "C"
|
||||
JNIEXPORT void JNICALL
|
||||
Java_com_erroratline0_infinipaint_InfiniPaintTextBoxInputConnection_nativeSetComposingText(
|
||||
JNIEnv *env, jobject jobject1, jobject text, jint new_cursor_position) {
|
||||
// TODO: implement nativeSetComposingText()
|
||||
}
|
||||
extern "C"
|
||||
JNIEXPORT void JNICALL
|
||||
Java_com_erroratline0_infinipaint_InfiniPaintTextBoxInputConnection_nativeSetComposingRegion(
|
||||
JNIEnv *env, jobject jobject1, jint start, jint end) {
|
||||
// TODO: implement nativeSetComposingRegion()
|
||||
}
|
||||
extern "C"
|
||||
JNIEXPORT void JNICALL
|
||||
Java_com_erroratline0_infinipaint_InfiniPaintTextBoxInputConnection_nativeSetSelection(JNIEnv *env,
|
||||
jobject jobject1,
|
||||
jint start,
|
||||
jint end) {
|
||||
// TODO: implement nativeSetSelection()
|
||||
}
|
||||
extern "C"
|
||||
JNIEXPORT void JNICALL
|
||||
Java_com_erroratline0_infinipaint_InfiniPaintTextBoxInputConnection_nativeCommitCorrection(
|
||||
JNIEnv *env, jobject jobject1, jint offset, jobject old_text, jobject new_text) {
|
||||
// TODO: implement nativeCommitCorrection()
|
||||
}
|
||||
extern "C"
|
||||
JNIEXPORT void JNICALL
|
||||
Java_com_erroratline0_infinipaint_InfiniPaintTextBoxInputConnection_nativeCommitText(JNIEnv *env,
|
||||
jobject jobject1,
|
||||
jobject text,
|
||||
jint new_cursor_position) {
|
||||
// TODO: implement nativeCommitText()
|
||||
}
|
||||
extern "C"
|
||||
JNIEXPORT void JNICALL
|
||||
Java_com_erroratline0_infinipaint_InfiniPaintTextBoxInputConnection_nativeDeleteSurroundingText(
|
||||
JNIEnv *env, jobject jobject1, jint before_length, jint after_length) {
|
||||
// TODO: implement nativeDeleteSurroundingText()
|
||||
}
|
||||
extern "C"
|
||||
JNIEXPORT void JNICALL
|
||||
Java_com_erroratline0_infinipaint_InfiniPaintTextBoxInputConnection_nativeDeleteSurroundingTextInCodePoints(
|
||||
JNIEnv *env, jobject jobject1, jint before_length, jint after_length) {
|
||||
// TODO: implement nativeDeleteSurroundingTextInCodePoints()
|
||||
}
|
||||
extern "C"
|
||||
JNIEXPORT void JNICALL
|
||||
Java_com_erroratline0_infinipaint_InfiniPaintTextBoxInputConnection_nativeEndBatchEdit(JNIEnv *env,
|
||||
jobject jobject1) {
|
||||
// TODO: implement nativeEndBatchEdit()
|
||||
}
|
||||
extern "C"
|
||||
JNIEXPORT void JNICALL
|
||||
Java_com_erroratline0_infinipaint_InfiniPaintTextBoxInputConnection_nativeFinishComposingText(
|
||||
JNIEnv *env, jobject jobject1) {
|
||||
// TODO: implement nativeFinishComposingText()
|
||||
}
|
||||
extern "C"
|
||||
JNIEXPORT jobject JNICALL
|
||||
Java_com_erroratline0_infinipaint_InfiniPaintTextBoxInputConnection_nativeGetSelectedText(
|
||||
JNIEnv *env, jobject jobject1) {
|
||||
// TODO: implement nativeGetSelectedText()
|
||||
}
|
||||
extern "C"
|
||||
JNIEXPORT jobject JNICALL
|
||||
Java_com_erroratline0_infinipaint_InfiniPaintTextBoxInputConnection_nativeGetTextAfterCursor(
|
||||
JNIEnv *env, jobject jobject1, jint n) {
|
||||
// TODO: implement nativeGetTextAfterCursor()
|
||||
}
|
||||
extern "C"
|
||||
JNIEXPORT jobject JNICALL
|
||||
Java_com_erroratline0_infinipaint_InfiniPaintTextBoxInputConnection_nativeGetTextBeforeCursor(
|
||||
JNIEnv *env, jobject jobject1, jint n) {
|
||||
// TODO: implement nativeGetTextBeforeCursor()
|
||||
}
|
||||
extern "C"
|
||||
JNIEXPORT void JNICALL
|
||||
Java_com_erroratline0_infinipaint_InfiniPaintTextBoxInputConnection_nativePerformContextMenuAction(
|
||||
JNIEnv *env, jobject jobject1, jint action) {
|
||||
// TODO: implement nativePerformContextMenuAction()
|
||||
}
|
||||
extern "C"
|
||||
JNIEXPORT void JNICALL
|
||||
Java_com_erroratline0_infinipaint_InfiniPaintTextBoxInputConnection_nativePerformEditorAction(
|
||||
JNIEnv *env, jobject jobject1, jint action) {
|
||||
// TODO: implement nativePerformEditorAction()
|
||||
Java_com_erroratline0_infinipaint_InfiniPaintTextBoxInputConnection_nativeSetTextBoxCursor(
|
||||
JNIEnv *env, jclass clazz, jint cursor_begin, jint cursor_end) {
|
||||
if(globalInputManager) {
|
||||
std::scoped_lock a{globalCallMutex};
|
||||
globalInputManager->main.input_android_text_box_set_cursor(cursor_begin, cursor_end);
|
||||
}
|
||||
}
|
||||
|
||||
#endif
|
||||
|
|
@ -8,7 +8,7 @@ namespace AndroidJNICalls {
|
|||
extern InputManager* globalInputManager;
|
||||
extern std::mutex globalCallMutex;
|
||||
|
||||
void startTextInput();
|
||||
void startTextInput(int input_type);
|
||||
}
|
||||
|
||||
#endif
|
||||
|
|
|
|||
|
|
@ -15,6 +15,7 @@ void init() {
|
|||
PasteEvent::EVENT_NUM = SDL_RegisterEvents(1);
|
||||
OpenInfiniPaintFileEvent::EVENT_NUM = SDL_RegisterEvents(1);
|
||||
AddFileToCanvasEvent::EVENT_NUM = SDL_RegisterEvents(1);
|
||||
RefreshTextBoxInputEvent::EVENT_NUM = SDL_RegisterEvents(1);
|
||||
alreadyInitialized = true;
|
||||
}
|
||||
}
|
||||
|
|
@ -22,5 +23,6 @@ void init() {
|
|||
uint32_t PasteEvent::EVENT_NUM;
|
||||
uint32_t OpenInfiniPaintFileEvent::EVENT_NUM;
|
||||
uint32_t AddFileToCanvasEvent::EVENT_NUM;
|
||||
uint32_t RefreshTextBoxInputEvent::EVENT_NUM;
|
||||
|
||||
}
|
||||
|
|
|
|||
|
|
@ -67,4 +67,8 @@ namespace CustomEvents {
|
|||
std::filesystem::path filePath;
|
||||
Vector2f pos;
|
||||
};
|
||||
|
||||
struct RefreshTextBoxInputEvent {
|
||||
static uint32_t EVENT_NUM;
|
||||
};
|
||||
}
|
||||
|
|
|
|||
|
|
@ -114,7 +114,7 @@ void DrawCamera::update_main(World& w) {
|
|||
checks_after_input(w);
|
||||
}
|
||||
else {
|
||||
if(w.main.input.key(InputManager::KEY_CAMERA_ROTATE_COUNTERCLOCKWISE).held && !w.main.input.text.is_accepting_input()) {
|
||||
if(w.main.input.key(InputManager::KEY_CAMERA_ROTATE_COUNTERCLOCKWISE).held && !w.main.input.text_is_accepting_input()) {
|
||||
c.rotate_about(c.from_space(w.main.window.size.cast<float>() * 0.5f), -w.main.deltaTime);
|
||||
InputManager::MouseMotionCallbackArgs motion{
|
||||
.pos = w.main.input.mouse.pos,
|
||||
|
|
@ -124,7 +124,7 @@ void DrawCamera::update_main(World& w) {
|
|||
w.main.g.gui.set_to_layout();
|
||||
checks_after_input(w);
|
||||
}
|
||||
if(w.main.input.key(InputManager::KEY_CAMERA_ROTATE_CLOCKWISE).held && !w.main.input.text.is_accepting_input()) {
|
||||
if(w.main.input.key(InputManager::KEY_CAMERA_ROTATE_CLOCKWISE).held && !w.main.input.text_is_accepting_input()) {
|
||||
c.rotate_about(c.from_space(w.main.window.size.cast<float>() * 0.5f), w.main.deltaTime);
|
||||
InputManager::MouseMotionCallbackArgs motion{
|
||||
.pos = w.main.input.mouse.pos,
|
||||
|
|
|
|||
|
|
@ -268,6 +268,10 @@ void DrawingProgram::input_pen_axis_callback(const InputManager::PenAxisCallback
|
|||
drawTool->input_pen_axis_callback(axis);
|
||||
}
|
||||
|
||||
std::optional<InputManager::TextBoxStartInfo> DrawingProgram::get_text_box_start_info() {
|
||||
return drawTool->get_text_box_start_info();
|
||||
}
|
||||
|
||||
void DrawingProgram::server_init_no_file() {
|
||||
layerMan.server_init_no_file();
|
||||
}
|
||||
|
|
|
|||
|
|
@ -74,6 +74,7 @@ class DrawingProgram {
|
|||
void input_pen_touch_callback(const InputManager::PenTouchCallbackArgs& touch);
|
||||
void input_pen_motion_callback(const InputManager::PenMotionCallbackArgs& motion);
|
||||
void input_pen_axis_callback(const InputManager::PenAxisCallbackArgs& axis);
|
||||
std::optional<InputManager::TextBoxStartInfo> get_text_box_start_info();
|
||||
|
||||
void set_right_click_popup_location(const Vector2f& newLoc);
|
||||
void clear_right_click_popup();
|
||||
|
|
|
|||
|
|
@ -65,3 +65,4 @@ void DrawingProgramToolBase::input_pen_button_callback(const InputManager::PenBu
|
|||
void DrawingProgramToolBase::input_pen_touch_callback(const InputManager::PenTouchCallbackArgs& touch) {}
|
||||
void DrawingProgramToolBase::input_pen_motion_callback(const InputManager::PenMotionCallbackArgs& motion) {}
|
||||
void DrawingProgramToolBase::input_pen_axis_callback(const InputManager::PenAxisCallbackArgs& axis) {}
|
||||
std::optional<InputManager::TextBoxStartInfo> DrawingProgramToolBase::get_text_box_start_info() { return std::nullopt; }
|
||||
|
|
|
|||
|
|
@ -48,6 +48,7 @@ class DrawingProgramToolBase {
|
|||
virtual void input_pen_touch_callback(const InputManager::PenTouchCallbackArgs& touch);
|
||||
virtual void input_pen_motion_callback(const InputManager::PenMotionCallbackArgs& motion);
|
||||
virtual void input_pen_axis_callback(const InputManager::PenAxisCallbackArgs& axis);
|
||||
virtual std::optional<InputManager::TextBoxStartInfo> get_text_box_start_info();
|
||||
virtual ~DrawingProgramToolBase();
|
||||
static std::unique_ptr<DrawingProgramToolBase> allocate_tool_type(DrawingProgram& drawP, DrawingProgramToolType t);
|
||||
protected:
|
||||
|
|
|
|||
|
|
@ -176,6 +176,12 @@ void EditTool::input_mouse_motion_callback(const InputManager::MouseMotionCallba
|
|||
drawP.selection.input_mouse_motion_callback_modify_selection(motion);
|
||||
}
|
||||
|
||||
std::optional<InputManager::TextBoxStartInfo> EditTool::get_text_box_start_info() {
|
||||
if(objInfoBeingEdited)
|
||||
return compEditTool->get_text_box_start_info();
|
||||
return std::nullopt;
|
||||
}
|
||||
|
||||
void EditTool::right_click_popup_gui(Toolbar& t, Vector2f popupPos) {
|
||||
if(objInfoBeingEdited)
|
||||
return compEditTool->right_click_popup_gui(t, popupPos);
|
||||
|
|
|
|||
|
|
@ -33,6 +33,7 @@ class EditTool : public DrawingProgramToolBase {
|
|||
virtual void input_key_callback(const InputManager::KeyCallbackArgs& key) override;
|
||||
virtual void input_mouse_button_on_canvas_callback(const InputManager::MouseButtonCallbackArgs& button) override;
|
||||
virtual void input_mouse_motion_callback(const InputManager::MouseMotionCallbackArgs& motion) override;
|
||||
virtual std::optional<InputManager::TextBoxStartInfo> get_text_box_start_info() override;
|
||||
~EditTool();
|
||||
|
||||
void add_point_handle(const HandleData& handle);
|
||||
|
|
|
|||
|
|
@ -16,5 +16,6 @@ void DrawingProgramEditToolBase::input_text_callback(const InputManager::TextCal
|
|||
void DrawingProgramEditToolBase::input_key_callback(const InputManager::KeyCallbackArgs& key) {}
|
||||
void DrawingProgramEditToolBase::input_mouse_button_on_canvas_callback(const InputManager::MouseButtonCallbackArgs& button, bool isDraggingPoint) {}
|
||||
void DrawingProgramEditToolBase::input_mouse_motion_callback(const InputManager::MouseMotionCallbackArgs& motion, bool isDraggingPoint) {}
|
||||
std::optional<InputManager::TextBoxStartInfo> DrawingProgramEditToolBase::get_text_box_start_info() { return std::nullopt; }
|
||||
|
||||
DrawingProgramEditToolBase::~DrawingProgramEditToolBase() {}
|
||||
|
|
|
|||
|
|
@ -20,6 +20,7 @@ class DrawingProgramEditToolBase {
|
|||
virtual void input_key_callback(const InputManager::KeyCallbackArgs& key);
|
||||
virtual void input_mouse_button_on_canvas_callback(const InputManager::MouseButtonCallbackArgs& button, bool isDraggingPoint);
|
||||
virtual void input_mouse_motion_callback(const InputManager::MouseMotionCallbackArgs& motion, bool isDraggingPoint);
|
||||
virtual std::optional<InputManager::TextBoxStartInfo> get_text_box_start_info();
|
||||
virtual ~DrawingProgramEditToolBase();
|
||||
protected:
|
||||
DrawingProgram& drawP;
|
||||
|
|
|
|||
|
|
@ -203,7 +203,7 @@ void TextBoxEditTool::edit_gui(Toolbar& t) {
|
|||
}
|
||||
|
||||
void TextBoxEditTool::input_paste_callback(const CustomEvents::PasteEvent& paste) {
|
||||
if(textboxID.has_value() && textboxID.value() == drawP.world.main.input.text.current_textbox_editing_id()) {
|
||||
if(userInput && userInput->id == drawP.world.main.input.currentTextboxID.value()) {
|
||||
auto& a = static_cast<TextBoxCanvasComponent&>(comp->obj->get_comp());
|
||||
if(userInput->input_paste_callback(paste)) {
|
||||
commit_update_and_layout_func();
|
||||
|
|
@ -213,7 +213,7 @@ void TextBoxEditTool::input_paste_callback(const CustomEvents::PasteEvent& paste
|
|||
}
|
||||
|
||||
void TextBoxEditTool::input_text_key_callback(const InputManager::KeyCallbackArgs& key) {
|
||||
if(textboxID.has_value() && textboxID.value() == drawP.world.main.input.text.current_textbox_editing_id()) {
|
||||
if(userInput && userInput->id == drawP.world.main.input.currentTextboxID.value()) {
|
||||
auto& a = static_cast<TextBoxCanvasComponent&>(comp->obj->get_comp());
|
||||
auto changes = userInput->input_key_callback(drawP.world.main.input, key);
|
||||
if(changes.textEdited || changes.cursorChanged) {
|
||||
|
|
@ -224,7 +224,7 @@ void TextBoxEditTool::input_text_key_callback(const InputManager::KeyCallbackArg
|
|||
}
|
||||
|
||||
void TextBoxEditTool::input_text_callback(const InputManager::TextCallbackArgs& text) {
|
||||
if(textboxID.has_value() && textboxID.value() == drawP.world.main.input.text.current_textbox_editing_id()) {
|
||||
if(userInput && userInput->id == drawP.world.main.input.currentTextboxID.value()) {
|
||||
auto& a = static_cast<TextBoxCanvasComponent&>(comp->obj->get_comp());
|
||||
userInput->add_text_to_textbox(text.str);
|
||||
commit_update_and_layout_func();
|
||||
|
|
@ -275,6 +275,25 @@ void TextBoxEditTool::input_mouse_motion_callback(const InputManager::MouseMotio
|
|||
}
|
||||
}
|
||||
|
||||
std::optional<InputManager::TextBoxStartInfo> TextBoxEditTool::get_text_box_start_info() {
|
||||
if(userInput) {
|
||||
InputManager::TextInputProperties tProps {
|
||||
.inputType = SDL_TextInputType::SDL_TEXTINPUT_TYPE_TEXT,
|
||||
.capitalization = SDL_Capitalization::SDL_CAPITALIZE_NONE,
|
||||
.autocorrect = true,
|
||||
.multiline = true,
|
||||
.androidInputType = InputManager::AndroidInputType::ANDROIDTEXT_TYPE_CLASS_TEXT
|
||||
};
|
||||
|
||||
return InputManager::TextBoxStartInfo {
|
||||
.id = userInput->id,
|
||||
.rect = std::nullopt,
|
||||
.inputProperties = tProps,
|
||||
};
|
||||
}
|
||||
return std::nullopt;
|
||||
}
|
||||
|
||||
void TextBoxEditTool::right_click_popup_gui(Toolbar& t, Vector2f popupPos) {
|
||||
using namespace GUIStuff;
|
||||
using namespace ElementHelpers;
|
||||
|
|
@ -375,8 +394,8 @@ void TextBoxEditTool::commit_edit_updates(std::any& prevData) {
|
|||
auto& a = static_cast<TextBoxCanvasComponent&>(comp->obj->get_comp());
|
||||
a.d.editing = false;
|
||||
comp->obj->commit_update(drawP);
|
||||
if(textboxID.has_value())
|
||||
drawP.world.main.input.remove_text_box(textboxID.value());
|
||||
userInput = nullptr;
|
||||
CustomEvents::emit_event(CustomEvents::RefreshTextBoxInputEvent{});
|
||||
}
|
||||
|
||||
TextBoxEditTool::TextBoxEditToolAllData TextBoxEditTool::get_all_data(const TextBoxCanvasComponent& a) {
|
||||
|
|
@ -406,14 +425,8 @@ void TextBoxEditTool::edit_start(EditTool& editTool, std::any& prevData) {
|
|||
|
||||
comp->obj->commit_update(drawP);
|
||||
|
||||
userInput = std::make_unique<RichTextUserInput>(textbox, cur, currentModsPtr);
|
||||
textboxID = drawP.world.main.input.set_text_box_back(std::nullopt, {
|
||||
.inputType = SDL_TextInputType::SDL_TEXTINPUT_TYPE_TEXT,
|
||||
.capitalization = SDL_Capitalization::SDL_CAPITALIZE_NONE,
|
||||
.autocorrect = true,
|
||||
.multiline = true,
|
||||
.androidInputType = InputManager::AndroidInputType::ANDROIDTEXT_TYPE_CLASS_TEXT
|
||||
});
|
||||
userInput = std::make_unique<RichTextUserInput>(drawP.world.main.input.text_box_get_new_id(), textbox, cur, currentModsPtr);
|
||||
CustomEvents::emit_event(CustomEvents::RefreshTextBoxInputEvent{});
|
||||
}
|
||||
|
||||
bool TextBoxEditTool::edit_update() {
|
||||
|
|
|
|||
|
|
@ -22,9 +22,9 @@ class TextBoxEditTool : public DrawingProgramEditToolBase {
|
|||
virtual void input_text_callback(const InputManager::TextCallbackArgs& text) override;
|
||||
virtual void input_mouse_button_on_canvas_callback(const InputManager::MouseButtonCallbackArgs& button, bool isDraggingPoint) override;
|
||||
virtual void input_mouse_motion_callback(const InputManager::MouseMotionCallbackArgs& motion, bool isDraggingPoint) override;
|
||||
virtual std::optional<InputManager::TextBoxStartInfo> get_text_box_start_info() override;
|
||||
private:
|
||||
std::unique_ptr<RichTextUserInput> userInput;
|
||||
std::optional<unsigned> textboxID;
|
||||
|
||||
struct TextBoxEditToolAllData {
|
||||
TextBoxCanvasComponent::Data textboxData;
|
||||
|
|
|
|||
|
|
@ -163,3 +163,7 @@ void GUIHolder::input_finger_touch_callback(const InputManager::FingerTouchCallb
|
|||
void GUIHolder::input_finger_motion_callback(const InputManager::FingerMotionCallbackArgs& motion) {
|
||||
gui.input_finger_motion_callback(motion);
|
||||
}
|
||||
|
||||
std::optional<InputManager::TextBoxStartInfo> GUIHolder::get_text_box_start_info() {
|
||||
return gui.get_text_box_start_info();
|
||||
}
|
||||
|
|
|
|||
|
|
@ -33,6 +33,8 @@ class GUIHolder {
|
|||
void input_finger_touch_callback(const InputManager::FingerTouchCallbackArgs& touch);
|
||||
void input_finger_motion_callback(const InputManager::FingerMotionCallbackArgs& motion);
|
||||
|
||||
std::optional<InputManager::TextBoxStartInfo> get_text_box_start_info();
|
||||
|
||||
float final_gui_scale();
|
||||
private:
|
||||
void calculate_final_gui_scale();
|
||||
|
|
|
|||
|
|
@ -21,6 +21,7 @@ namespace GUIStuff {
|
|||
input_mouse_motion_callback(InputManager::convert_finger_motion_to_mouse_motion(motion));
|
||||
}
|
||||
void Element::input_key_callback(const InputManager::KeyCallbackArgs& key) {}
|
||||
std::optional<InputManager::TextBoxStartInfo> Element::get_text_box_start_info() { return std::nullopt; }
|
||||
|
||||
void Element::clay_draw(SkCanvas* canvas, UpdateInputData& io, Clay_RenderCommand* command, bool skiaAA) {}
|
||||
|
||||
|
|
|
|||
|
|
@ -35,6 +35,7 @@ namespace GUIStuff {
|
|||
virtual void input_finger_touch_callback(const InputManager::FingerTouchCallbackArgs& touch);
|
||||
virtual void input_finger_motion_callback(const InputManager::FingerMotionCallbackArgs& motion);
|
||||
virtual void input_key_callback(const InputManager::KeyCallbackArgs& key);
|
||||
virtual std::optional<InputManager::TextBoxStartInfo> get_text_box_start_info();
|
||||
protected:
|
||||
static SCollision::AABB<float> get_bb_from_command(Clay_RenderCommand* command);
|
||||
std::optional<SCollision::AABB<float>> boundingBox;
|
||||
|
|
|
|||
|
|
@ -23,16 +23,6 @@ template <typename T> struct TextBoxData {
|
|||
std::function<void()> onDeselect;
|
||||
};
|
||||
|
||||
|
||||
struct TextEditData {
|
||||
TextEditData(unsigned initTextboxInputID, const std::shared_ptr<RichText::TextBox>& initTextBox, const std::shared_ptr<RichText::TextBox::Cursor>& initCursor):
|
||||
textboxInputID(initTextboxInputID),
|
||||
userInput(initTextBox, initCursor, nullptr)
|
||||
{}
|
||||
unsigned textboxInputID;
|
||||
RichTextUserInput userInput;
|
||||
};
|
||||
|
||||
template <typename T> class TextBox : public Element {
|
||||
public:
|
||||
TextBox(GUIManager& gui);
|
||||
|
|
@ -47,6 +37,7 @@ template <typename T> class TextBox : public Element {
|
|||
virtual void input_text_callback(const InputManager::TextCallbackArgs& text) override;
|
||||
virtual void input_mouse_button_callback(const InputManager::MouseButtonCallbackArgs& button) override;
|
||||
virtual void input_mouse_motion_callback(const InputManager::MouseMotionCallbackArgs& motion) override;
|
||||
virtual std::optional<InputManager::TextBoxStartInfo> get_text_box_start_info() override;
|
||||
~TextBox();
|
||||
private:
|
||||
void populate_empty_textbox();
|
||||
|
|
@ -64,7 +55,8 @@ template <typename T> class TextBox : public Element {
|
|||
|
||||
bool isEmptyText = false;
|
||||
bool isHeld = false;
|
||||
std::optional<TextEditData> edit;
|
||||
|
||||
std::unique_ptr<RichTextUserInput> edit;
|
||||
|
||||
std::optional<T> oldData;
|
||||
std::string oldEmptyText;
|
||||
|
|
|
|||
|
|
@ -1,5 +1,6 @@
|
|||
#include "TextBox.decl.hpp"
|
||||
#include "../GUIManager.hpp"
|
||||
#include <SDL3/SDL_keyboard.h>
|
||||
|
||||
namespace GUIStuff {
|
||||
|
||||
|
|
@ -15,6 +16,11 @@ template <typename T> void TextBox<T>::layout(const Clay_ElementId& id, const Te
|
|||
gui.invalidate_draw_element(this);
|
||||
}
|
||||
|
||||
if(edit) {
|
||||
SCollision::AABB<float> rect = {boundingBox.value().min * gui.io.guiScaleMultiplier, boundingBox.value().max * gui.io.guiScaleMultiplier};
|
||||
gui.io.input->update_textbox_rectangle(edit->id, rect);
|
||||
}
|
||||
|
||||
CLAY(id, {
|
||||
.layout = {
|
||||
.sizing = {.width = CLAY_SIZING_GROW(static_cast<float>(io.fontSize * 2)), .height = CLAY_SIZING_FIXED(static_cast<float>(io.fontSize * 1.25f))}
|
||||
|
|
@ -32,10 +38,6 @@ template <typename T> void TextBox<T>::update() {
|
|||
oldDD.cur = *cur;
|
||||
gui.invalidate_draw_element(this);
|
||||
}
|
||||
if(edit.has_value()) {
|
||||
SCollision::AABB<float> rect = {boundingBox.value().min * gui.io.guiScaleMultiplier, boundingBox.value().max * gui.io.guiScaleMultiplier};
|
||||
gui.io.input->update_textbox_rectangle(edit.value().textboxInputID, rect);
|
||||
}
|
||||
}
|
||||
|
||||
template <typename T> void TextBox<T>::clay_draw(SkCanvas* canvas, UpdateInputData& io, Clay_RenderCommand* command, bool skiaAA) {
|
||||
|
|
@ -80,30 +82,29 @@ template <typename T> void TextBox<T>::clay_draw(SkCanvas* canvas, UpdateInputDa
|
|||
|
||||
template <typename T> void TextBox<T>::select() {
|
||||
if(!is_selected()) {
|
||||
SCollision::AABB<float> rect = {boundingBox.value().min * gui.io.guiScaleMultiplier, boundingBox.value().max * gui.io.guiScaleMultiplier};
|
||||
unsigned id = gui.io.input->set_text_box_front(rect, userInfo.textInputProps);
|
||||
if(isEmptyText)
|
||||
textbox->clear_text();
|
||||
edit = TextEditData(id, textbox, cur);
|
||||
edit = std::make_unique<RichTextUserInput>(gui.io.input->text_box_get_new_id(), textbox, cur, nullptr);
|
||||
CustomEvents::emit_event(CustomEvents::RefreshTextBoxInputEvent{});
|
||||
}
|
||||
}
|
||||
|
||||
template <typename T> void TextBox<T>::deselect() {
|
||||
if(is_selected()) {
|
||||
gui.io.input->remove_text_box(edit.value().textboxInputID);
|
||||
edit = nullptr;
|
||||
if(userInfo.onDeselect) userInfo.onDeselect();
|
||||
CustomEvents::emit_event(CustomEvents::RefreshTextBoxInputEvent{});
|
||||
reset_textbox_text();
|
||||
edit = std::nullopt;
|
||||
populate_empty_textbox();
|
||||
}
|
||||
}
|
||||
|
||||
template <typename T> bool TextBox<T>::is_selected() const {
|
||||
return edit.has_value();
|
||||
return edit != nullptr;
|
||||
}
|
||||
|
||||
template <typename T> void TextBox<T>::input_paste_callback(const CustomEvents::PasteEvent& paste) {
|
||||
if(is_selected() && edit.value().userInput.input_paste_callback(paste))
|
||||
if(is_selected() && edit->input_paste_callback(paste))
|
||||
after_text_input_callback();
|
||||
}
|
||||
|
||||
|
|
@ -118,7 +119,7 @@ template <typename T> void TextBox<T>::input_text_key_callback(const InputManage
|
|||
});
|
||||
}
|
||||
else {
|
||||
if(edit.value().userInput.input_key_callback(*gui.io.input, key).textEdited)
|
||||
if(edit->input_key_callback(*gui.io.input, key).textEdited)
|
||||
after_text_input_callback();
|
||||
}
|
||||
}
|
||||
|
|
@ -150,7 +151,7 @@ template <typename T> void TextBox<T>::after_text_input_callback() {
|
|||
|
||||
template <typename T> void TextBox<T>::input_text_callback(const InputManager::TextCallbackArgs& text) {
|
||||
if(is_selected()) {
|
||||
edit.value().userInput.add_text_to_textbox(text.str);
|
||||
edit->add_text_to_textbox(text.str);
|
||||
after_text_input_callback();
|
||||
}
|
||||
}
|
||||
|
|
@ -181,6 +182,18 @@ template <typename T> void TextBox<T>::input_mouse_motion_callback(const InputMa
|
|||
textbox->process_mouse_left_button(*cur, motion.pos - boundingBox.value().min, 0, isHeld, gui.io.input->key(InputManager::KEY_GENERIC_LSHIFT).held);
|
||||
}
|
||||
|
||||
template <typename T> std::optional<InputManager::TextBoxStartInfo> TextBox<T>::get_text_box_start_info() {
|
||||
if(edit) {
|
||||
SCollision::AABB<float> rect = {boundingBox.value().min * gui.io.guiScaleMultiplier, boundingBox.value().max * gui.io.guiScaleMultiplier};
|
||||
return InputManager::TextBoxStartInfo{
|
||||
.id = edit->id,
|
||||
.rect = rect,
|
||||
.inputProperties = userInfo.textInputProps
|
||||
};
|
||||
}
|
||||
return std::nullopt;
|
||||
}
|
||||
|
||||
template <typename T> void TextBox<T>::init_textbox(UpdateInputData& io) {
|
||||
if(!textbox) {
|
||||
textbox = std::make_shared<RichText::TextBox>();
|
||||
|
|
@ -212,7 +225,7 @@ template <typename T> bool TextBox<T>::update_data() {
|
|||
|
||||
template <typename T> TextBox<T>::~TextBox() {
|
||||
if(is_selected())
|
||||
gui.io.input->remove_text_box(edit.value().textboxInputID);
|
||||
CustomEvents::emit_event(CustomEvents::RefreshTextBoxInputEvent{});
|
||||
}
|
||||
|
||||
}
|
||||
|
|
|
|||
|
|
@ -757,6 +757,15 @@ void GUIManager::input_finger_motion_callback(InputManager::FingerMotionCallback
|
|||
mouse_callback(motion.pos, [&motion] (ElementContainer* e) { e->elem->input_finger_motion_callback(motion); });
|
||||
}
|
||||
|
||||
std::optional<InputManager::TextBoxStartInfo> GUIManager::get_text_box_start_info() {
|
||||
for(ElementContainer* e : orderedElements) {
|
||||
auto toRet = e->elem->get_text_box_start_info();
|
||||
if(toRet)
|
||||
return toRet;
|
||||
}
|
||||
return std::nullopt;
|
||||
}
|
||||
|
||||
void GUIManager::mouse_callback(const Vector2f& mousePos, const std::function<void(ElementContainer*)>& f) {
|
||||
cursorObstructed = false;
|
||||
int16_t zIndexObstructed = 0;
|
||||
|
|
|
|||
|
|
@ -108,6 +108,7 @@ class GUIManager {
|
|||
void input_mouse_wheel_callback(InputManager::MouseWheelCallbackArgs wheel);
|
||||
void input_finger_touch_callback(InputManager::FingerTouchCallbackArgs touch);
|
||||
void input_finger_motion_callback(InputManager::FingerMotionCallbackArgs motion);
|
||||
std::optional<InputManager::TextBoxStartInfo> get_text_box_start_info();
|
||||
|
||||
bool cursor_obstructed() const;
|
||||
private:
|
||||
|
|
|
|||
|
|
@ -91,76 +91,33 @@ InputManager::InputManager(MainProgram& initMain):
|
|||
keyAssignments = defaultKeyAssignments;
|
||||
}
|
||||
|
||||
unsigned InputManager::Text::get_id() {
|
||||
static unsigned nextID = 0;
|
||||
while(std::find_if(textBoxes.begin(), textBoxes.end(), [&](const TextBoxInfo& info) { return info.id == nextID; }) != textBoxes.end())
|
||||
++nextID;
|
||||
InputManager::TextBoxID InputManager::text_box_get_new_id() {
|
||||
static TextBoxID nextID = 0;
|
||||
++nextID;
|
||||
return nextID;
|
||||
}
|
||||
|
||||
unsigned InputManager::set_text_box_front(const std::optional<SCollision::AABB<float>>& textboxRect, const TextInputProperties& inputProps) {
|
||||
Text::TextBoxInfo textBoxInfo;
|
||||
textBoxInfo.rect = textboxRect;
|
||||
textBoxInfo.textInputProperties = inputProps;
|
||||
textBoxInfo.id = text.get_id();
|
||||
text.textBoxes.emplace_front(textBoxInfo);
|
||||
update_accepting_input(main.window.sdlWindow);
|
||||
return textBoxInfo.id;
|
||||
}
|
||||
void InputManager::refresh_receiving_text_box_input() {
|
||||
std::optional<TextBoxStartInfo> startInfo = main.get_text_box_start_info();
|
||||
if(startInfo.has_value()) {
|
||||
if(!textPropID.has_value())
|
||||
textPropID = SDL_CreateProperties();
|
||||
currentTextboxID = startInfo->id;
|
||||
|
||||
unsigned InputManager::set_text_box_back(const std::optional<SCollision::AABB<float>>& textboxRect, const TextInputProperties& inputProps) {
|
||||
Text::TextBoxInfo textBoxInfo;
|
||||
textBoxInfo.rect = textboxRect;
|
||||
textBoxInfo.textInputProperties = inputProps;
|
||||
textBoxInfo.id = text.get_id();
|
||||
text.textBoxes.emplace_back(textBoxInfo);
|
||||
update_accepting_input(main.window.sdlWindow);
|
||||
return textBoxInfo.id;
|
||||
}
|
||||
|
||||
void InputManager::remove_text_box(unsigned id) {
|
||||
std::erase_if(text.textBoxes, [id](Text::TextBoxInfo& info) {
|
||||
return (info.id == id);
|
||||
});
|
||||
update_accepting_input(main.window.sdlWindow);
|
||||
}
|
||||
|
||||
bool InputManager::Text::is_accepting_input() {
|
||||
return !textBoxes.empty();
|
||||
}
|
||||
|
||||
std::optional<unsigned> InputManager::Text::current_textbox_editing_id() {
|
||||
if(textBoxes.empty())
|
||||
return std::nullopt;
|
||||
return textBoxes.front().id;
|
||||
}
|
||||
|
||||
void InputManager::update_textbox_rectangle(unsigned textboxID, const SCollision::AABB<float>& textboxRect) {
|
||||
auto it = std::find_if(text.textBoxes.begin(), text.textBoxes.end(), [&](const auto& t) {return t.id == textboxID;});
|
||||
it->rect = textboxRect;
|
||||
}
|
||||
|
||||
void InputManager::update_accepting_input(SDL_Window* window) {
|
||||
if(!text.textBoxes.empty()) {
|
||||
auto& textbox = text.textBoxes.front();
|
||||
if(!text.propID.has_value())
|
||||
text.propID = SDL_CreateProperties();
|
||||
SDL_PropertiesID propIDVal = text.propID.value();
|
||||
SDL_PropertiesID propIDVal = textPropID.value();
|
||||
// There is a bug where decimal places disappear when textinput type is set to number on android. We'll just set those textinputs back to text type
|
||||
SDL_SetNumberProperty(propIDVal, SDL_PROP_TEXTINPUT_TYPE_NUMBER, (textbox.textInputProperties.inputType == SDL_TEXTINPUT_TYPE_NUMBER) ? SDL_TEXTINPUT_TYPE_TEXT : textbox.textInputProperties.inputType);
|
||||
SDL_SetNumberProperty(propIDVal, SDL_PROP_TEXTINPUT_CAPITALIZATION_NUMBER, textbox.textInputProperties.capitalization);
|
||||
SDL_SetNumberProperty(propIDVal, SDL_PROP_TEXTINPUT_AUTOCORRECT_BOOLEAN, textbox.textInputProperties.autocorrect);
|
||||
SDL_SetNumberProperty(propIDVal, SDL_PROP_TEXTINPUT_MULTILINE_BOOLEAN, textbox.textInputProperties.multiline);
|
||||
SDL_SetNumberProperty(propIDVal, SDL_PROP_TEXTINPUT_ANDROID_INPUTTYPE_NUMBER, (textbox.textInputProperties.androidInputType & ANDROIDTEXT_TYPE_CLASS_NUMBER) ? ANDROIDTEXT_TYPE_CLASS_TEXT : textbox.textInputProperties.androidInputType);
|
||||
if(text.textBoxes.front().rect)
|
||||
excludeIMEFromSafeArea = false;
|
||||
else
|
||||
excludeIMEFromSafeArea = true;
|
||||
SDL_SetNumberProperty(propIDVal, SDL_PROP_TEXTINPUT_TYPE_NUMBER, (startInfo->inputProperties.inputType == SDL_TEXTINPUT_TYPE_NUMBER) ? SDL_TEXTINPUT_TYPE_TEXT : startInfo->inputProperties.inputType);
|
||||
SDL_SetNumberProperty(propIDVal, SDL_PROP_TEXTINPUT_CAPITALIZATION_NUMBER, startInfo->inputProperties.capitalization);
|
||||
SDL_SetNumberProperty(propIDVal, SDL_PROP_TEXTINPUT_AUTOCORRECT_BOOLEAN, startInfo->inputProperties.autocorrect);
|
||||
SDL_SetNumberProperty(propIDVal, SDL_PROP_TEXTINPUT_MULTILINE_BOOLEAN, startInfo->inputProperties.multiline);
|
||||
SDL_SetNumberProperty(propIDVal, SDL_PROP_TEXTINPUT_ANDROID_INPUTTYPE_NUMBER, (startInfo->inputProperties.androidInputType & ANDROIDTEXT_TYPE_CLASS_NUMBER) ? ANDROIDTEXT_TYPE_CLASS_TEXT : startInfo->inputProperties.androidInputType);
|
||||
|
||||
update_textbox_rectangle(currentTextboxID.value(), startInfo->rect);
|
||||
|
||||
#ifdef __ANDROID__
|
||||
AndroidJNICalls::startTextInput();
|
||||
AndroidJNICalls::startTextInput(startInfo->inputProperties.androidInputType);
|
||||
#else
|
||||
SDL_StartTextInputWithProperties(window, propIDVal);
|
||||
SDL_StartTextInputWithProperties(main.window.sdlWindow, propIDVal);
|
||||
#endif
|
||||
|
||||
#ifdef __EMSCRIPTEN__
|
||||
|
|
@ -168,7 +125,8 @@ void InputManager::update_accepting_input(SDL_Window* window) {
|
|||
#endif
|
||||
}
|
||||
else {
|
||||
SDL_StopTextInput(window);
|
||||
SDL_StopTextInput(main.window.sdlWindow);
|
||||
currentTextboxID = std::nullopt;
|
||||
excludeIMEFromSafeArea = false;
|
||||
screenOffset = {0.0f, 0.0f};
|
||||
#ifdef __EMSCRIPTEN__
|
||||
|
|
@ -177,6 +135,32 @@ void InputManager::update_accepting_input(SDL_Window* window) {
|
|||
}
|
||||
}
|
||||
|
||||
bool InputManager::text_is_accepting_input() {
|
||||
return currentTextboxID.has_value();
|
||||
}
|
||||
|
||||
void InputManager::update_textbox_rectangle(TextBoxID textboxID, std::optional<SCollision::AABB<float>> textboxRect) {
|
||||
if(currentTextboxID.has_value() && textboxID == currentTextboxID.value()) {
|
||||
excludeIMEFromSafeArea = !textboxRect.has_value();
|
||||
if(excludeIMEFromSafeArea)
|
||||
screenOffset = {0.0f, 0.0f};
|
||||
else {
|
||||
constexpr float PADDING_BETWEEN_TEXTBOX_AND_IME = 15.0f;
|
||||
std::scoped_lock a{safeAreaWithoutIMEMutex};
|
||||
if(safeAreaWithoutIME.has_value()) {
|
||||
float bottomY = textboxRect->max.y();
|
||||
float yLimit = safeAreaWithoutIME->max.y() - PADDING_BETWEEN_TEXTBOX_AND_IME;
|
||||
if(bottomY >= yLimit)
|
||||
screenOffset = {0.0f, -(bottomY - yLimit)};
|
||||
else
|
||||
screenOffset = {0.0f, 0.0f};
|
||||
}
|
||||
else
|
||||
screenOffset = {0.0f, 0.0f};
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
std::string InputManager::get_clipboard_str_SDL() {
|
||||
char* data = SDL_GetClipboardText();
|
||||
std::string toRet(data);
|
||||
|
|
@ -908,7 +892,7 @@ void InputManager::backend_key_down_update(const SDL_KeyboardEvent& e) {
|
|||
return;
|
||||
}
|
||||
|
||||
bool acceptingTextInput = text.is_accepting_input();
|
||||
bool acceptingTextInput = text_is_accepting_input();
|
||||
|
||||
switch(kPress) {
|
||||
case SDLK_UP:
|
||||
|
|
@ -1060,7 +1044,7 @@ bool InputManager::ctrl_or_meta_held() {
|
|||
void InputManager::backend_key_up_update(const SDL_KeyboardEvent& e) {
|
||||
auto kPress = e.key;
|
||||
|
||||
bool acceptingTextInput = text.is_accepting_input();
|
||||
bool acceptingTextInput = text_is_accepting_input();
|
||||
|
||||
switch(kPress) {
|
||||
case SDLK_UP:
|
||||
|
|
@ -1141,23 +1125,6 @@ void InputManager::update() {
|
|||
touch_finger_do_mouse_down();
|
||||
touch.touchEventType = Touch::ONE_FINGER_EVENT;
|
||||
}
|
||||
constexpr float PADDING_BETWEEN_TEXTBOX_AND_IME = 15.0f;
|
||||
if(!text.textBoxes.empty()) {
|
||||
auto& r = text.textBoxes.front().rect;
|
||||
std::scoped_lock a{safeAreaWithoutIMEMutex};
|
||||
if(r.has_value() && safeAreaWithoutIME.has_value()) {
|
||||
float bottomY = r.value().max.y();
|
||||
float yLimit = safeAreaWithoutIME.value().max.y() - PADDING_BETWEEN_TEXTBOX_AND_IME;
|
||||
if(bottomY >= yLimit)
|
||||
screenOffset = {0.0f, -(bottomY - yLimit)};
|
||||
else
|
||||
screenOffset = {0.0f, 0.0f};
|
||||
}
|
||||
else
|
||||
screenOffset = {0.0f, 0.0f};
|
||||
}
|
||||
else
|
||||
screenOffset = {0.0f, 0.0f};
|
||||
}
|
||||
|
||||
void InputManager::frame_reset(const Vector2i& windowSize) {
|
||||
|
|
|
|||
|
|
@ -143,6 +143,7 @@ struct InputManager {
|
|||
ANDROIDTEXT_TYPE_TEXT_VARIATION_WEB_PASSWORD = 0x000000e0
|
||||
};
|
||||
|
||||
typedef int64_t TextBoxID;
|
||||
struct TextInputProperties {
|
||||
SDL_TextInputType inputType;
|
||||
SDL_Capitalization capitalization;
|
||||
|
|
@ -151,31 +152,27 @@ struct InputManager {
|
|||
int androidInputType;
|
||||
};
|
||||
|
||||
unsigned set_text_box_front(const std::optional<SCollision::AABB<float>>& textboxRect, const TextInputProperties& inputProps);
|
||||
unsigned set_text_box_back(const std::optional<SCollision::AABB<float>>& textboxRect, const TextInputProperties& inputProps);
|
||||
void remove_text_box(unsigned textboxID);
|
||||
void update_accepting_input(SDL_Window* window);
|
||||
void update_textbox_rectangle(unsigned textboxID, const SCollision::AABB<float>& textboxRect);
|
||||
struct TextBoxStartInfo {
|
||||
TextBoxID id;
|
||||
std::optional<SCollision::AABB<float>> rect;
|
||||
TextInputProperties inputProperties;
|
||||
|
||||
struct Text {
|
||||
bool is_accepting_input();
|
||||
std::optional<unsigned> current_textbox_editing_id();
|
||||
void update_textbox_rectangle();
|
||||
// Android textbox info
|
||||
std::string str;
|
||||
int startCursorPos;
|
||||
int endCursorPos;
|
||||
};
|
||||
|
||||
private:
|
||||
struct TextBoxInfo {
|
||||
std::optional<SCollision::AABB<float>> rect;
|
||||
TextInputProperties textInputProperties;
|
||||
unsigned id;
|
||||
};
|
||||
void refresh_receiving_text_box_input();
|
||||
void update_textbox_rectangle(TextBoxID textboxID, std::optional<SCollision::AABB<float>> textboxRect);
|
||||
bool text_is_accepting_input();
|
||||
|
||||
std::optional<SDL_PropertiesID> propID;
|
||||
void text_update_textbox_rectangle();
|
||||
TextBoxID text_box_get_new_id();
|
||||
void update_text_box_area_offset();
|
||||
|
||||
std::deque<TextBoxInfo> textBoxes;
|
||||
unsigned get_id();
|
||||
|
||||
friend struct InputManager;
|
||||
} text;
|
||||
std::optional<TextBoxID> currentTextboxID;
|
||||
std::optional<SDL_PropertiesID> textPropID;
|
||||
|
||||
#ifdef __APPLE__
|
||||
SDL_Keymod CTRL_MOD = SDL_KMOD_GUI;
|
||||
|
|
|
|||
|
|
@ -422,6 +422,13 @@ void MainProgram::input_window_scale_callback(const InputManager::WindowScaleCal
|
|||
post_callback();
|
||||
}
|
||||
|
||||
std::optional<InputManager::TextBoxStartInfo> MainProgram::get_text_box_start_info() {
|
||||
auto toRet = g.get_text_box_start_info();
|
||||
if(toRet)
|
||||
return toRet;
|
||||
return screen->get_text_box_start_info();
|
||||
}
|
||||
|
||||
void MainProgram::toggle_full_screen() {
|
||||
window.fullscreen = !window.fullscreen;
|
||||
SDL_SetWindowFullscreen(window.sdlWindow, window.fullscreen);
|
||||
|
|
|
|||
|
|
@ -158,6 +158,8 @@ class MainProgram {
|
|||
void input_window_resize_callback(const InputManager::WindowResizeCallbackArgs& w);
|
||||
void input_window_scale_callback(const InputManager::WindowScaleCallbackArgs& w);
|
||||
|
||||
std::optional<InputManager::TextBoxStartInfo> get_text_box_start_info();
|
||||
|
||||
void create_new_tab(const CustomEvents::OpenInfiniPaintFileEvent& openFile);
|
||||
void set_tab_to_close(World* world);
|
||||
void switch_to_tab(size_t wIndex);
|
||||
|
|
|
|||
|
|
@ -8,7 +8,8 @@ template <typename T> std::optional<T> shared_ptr_to_opt(const std::shared_ptr<T
|
|||
return std::nullopt;
|
||||
}
|
||||
|
||||
RichTextUserInput::RichTextUserInput(const std::shared_ptr<RichText::TextBox>& initTextBox, const std::shared_ptr<RichText::TextBox::Cursor>& initCursor, const std::shared_ptr<RichText::TextStyleModifier::ModifierMap>& initModMap):
|
||||
RichTextUserInput::RichTextUserInput(InputManager::TextBoxID initId, const std::shared_ptr<RichText::TextBox>& initTextBox, const std::shared_ptr<RichText::TextBox::Cursor>& initCursor, const std::shared_ptr<RichText::TextStyleModifier::ModifierMap>& initModMap):
|
||||
id(initId),
|
||||
textBox(initTextBox),
|
||||
cursor(initCursor),
|
||||
modMap(initModMap)
|
||||
|
|
|
|||
|
|
@ -6,7 +6,7 @@
|
|||
|
||||
class RichTextUserInput {
|
||||
public:
|
||||
RichTextUserInput(const std::shared_ptr<RichText::TextBox>& initTextBox, const std::shared_ptr<RichText::TextBox::Cursor>& initCursor, const std::shared_ptr<RichText::TextStyleModifier::ModifierMap>& initModMap);
|
||||
RichTextUserInput(InputManager::TextBoxID initId, const std::shared_ptr<RichText::TextBox>& initTextBox, const std::shared_ptr<RichText::TextBox::Cursor>& initCursor, const std::shared_ptr<RichText::TextStyleModifier::ModifierMap>& initModMap);
|
||||
struct Changes {
|
||||
bool textEdited = false;
|
||||
bool cursorChanged = false;
|
||||
|
|
@ -16,6 +16,7 @@ class RichTextUserInput {
|
|||
void add_text_to_textbox(const std::string& inputText);
|
||||
void do_textbox_operation_with_undo(const std::function<void()>& func);
|
||||
void add_textbox_undo(const RichText::TextBox::Cursor& prevCursor, const RichText::TextData& prevRichText);
|
||||
const InputManager::TextBoxID id;
|
||||
private:
|
||||
std::shared_ptr<RichText::TextBox> textBox;
|
||||
std::shared_ptr<RichText::TextBox::Cursor> cursor;
|
||||
|
|
|
|||
|
|
@ -102,3 +102,7 @@ void DrawingProgramScreen::input_window_resize_callback(const InputManager::Wind
|
|||
|
||||
void DrawingProgramScreen::input_window_scale_callback(const InputManager::WindowScaleCallbackArgs& w) {
|
||||
}
|
||||
|
||||
std::optional<InputManager::TextBoxStartInfo> DrawingProgramScreen::get_text_box_start_info() {
|
||||
return main.world->get_text_box_start_info();
|
||||
}
|
||||
|
|
|
|||
|
|
@ -27,4 +27,5 @@ class DrawingProgramScreen : public Screen {
|
|||
virtual void input_finger_motion_callback(const InputManager::FingerMotionCallbackArgs& motion) override;
|
||||
virtual void input_window_resize_callback(const InputManager::WindowResizeCallbackArgs& w) override;
|
||||
virtual void input_window_scale_callback(const InputManager::WindowScaleCallbackArgs& w) override;
|
||||
virtual std::optional<InputManager::TextBoxStartInfo> get_text_box_start_info() override;
|
||||
};
|
||||
|
|
|
|||
|
|
@ -30,5 +30,6 @@ void Screen::input_finger_motion_callback(const InputManager::FingerMotionCallba
|
|||
void Screen::input_window_resize_callback(const InputManager::WindowResizeCallbackArgs& w) {}
|
||||
void Screen::input_window_scale_callback(const InputManager::WindowScaleCallbackArgs& w) {}
|
||||
void Screen::input_app_about_to_go_to_background_callback() {}
|
||||
std::optional<InputManager::TextBoxStartInfo> Screen::get_text_box_start_info() { return std::nullopt; }
|
||||
|
||||
Screen::~Screen() {}
|
||||
|
|
|
|||
|
|
@ -32,6 +32,7 @@ class Screen {
|
|||
virtual void input_window_resize_callback(const InputManager::WindowResizeCallbackArgs& w);
|
||||
virtual void input_window_scale_callback(const InputManager::WindowScaleCallbackArgs& w);
|
||||
virtual void input_app_about_to_go_to_background_callback();
|
||||
virtual std::optional<InputManager::TextBoxStartInfo> get_text_box_start_info();
|
||||
|
||||
virtual ~Screen();
|
||||
protected:
|
||||
|
|
|
|||
|
|
@ -347,6 +347,12 @@ void World::input_multi_finger_motion_callback(const InputManager::MultiFingerMo
|
|||
drawData.cam.input_multi_finger_motion_callback(*this, motion);
|
||||
}
|
||||
|
||||
std::optional<InputManager::TextBoxStartInfo> World::get_text_box_start_info() {
|
||||
if(!clientStillConnecting)
|
||||
return drawProg.get_text_box_start_info();
|
||||
return std::nullopt;
|
||||
}
|
||||
|
||||
void World::send_chat_message(const std::string& message) {
|
||||
if(!clientStillConnecting)
|
||||
ownClientData->send_chat_message(ownClientData, *this, message);
|
||||
|
|
|
|||
|
|
@ -109,6 +109,7 @@ class World {
|
|||
void input_pen_axis_callback(const InputManager::PenAxisCallbackArgs& axis);
|
||||
void input_multi_finger_touch_callback(const InputManager::MultiFingerTouchCallbackArgs& touch);
|
||||
void input_multi_finger_motion_callback(const InputManager::MultiFingerMotionCallbackArgs& motion);
|
||||
std::optional<InputManager::TextBoxStartInfo> get_text_box_start_info();
|
||||
private:
|
||||
bool saveThumbnail = false;
|
||||
bool hasUnsavedLocalChanges = false;
|
||||
|
|
|
|||
16
src/main.cpp
16
src/main.cpp
|
|
@ -109,6 +109,8 @@ extern "C"
|
|||
}
|
||||
#endif
|
||||
|
||||
#include "AndroidJNICalls.hpp"
|
||||
|
||||
#include <unicode/udata.h>
|
||||
std::string icudt; // Put this in global space so that it isn't deallocated
|
||||
|
||||
|
|
@ -369,6 +371,10 @@ void init_logs(MainStruct& mS) {
|
|||
}
|
||||
|
||||
SDL_AppResult SDL_AppInit(void **appstate, int argc, char **argv) {
|
||||
#ifdef __ANDROID__
|
||||
std::scoped_lock a{AndroidJNICalls::globalCallMutex};
|
||||
#endif
|
||||
|
||||
std::vector<std::filesystem::path> listOfFilesToOpenFromCommand;
|
||||
for(int i = 1; i < argc; i++)
|
||||
listOfFilesToOpenFromCommand.emplace_back(std::filesystem::canonical(std::filesystem::path(std::u8string_view(reinterpret_cast<char8_t*>(argv[i])))));
|
||||
|
|
@ -592,6 +598,10 @@ void regular_draw(MainStruct& mS) {
|
|||
}
|
||||
|
||||
SDL_AppResult SDL_AppIterate(void *appstate) {
|
||||
#ifdef __ANDROID__
|
||||
std::scoped_lock a{AndroidJNICalls::globalCallMutex};
|
||||
#endif
|
||||
|
||||
std::chrono::steady_clock::time_point frameTimeStart = std::chrono::steady_clock::now();
|
||||
|
||||
MainStruct& mS = *((MainStruct*)appstate);
|
||||
|
|
@ -631,6 +641,10 @@ SDL_AppResult SDL_AppIterate(void *appstate) {
|
|||
}
|
||||
|
||||
SDL_AppResult SDL_AppEvent(void *appstate, SDL_Event *event) {
|
||||
#ifdef __ANDROID__
|
||||
std::scoped_lock a{AndroidJNICalls::globalCallMutex};
|
||||
#endif
|
||||
|
||||
MainStruct& mS = *((MainStruct*)appstate);
|
||||
|
||||
#ifdef NDEBUG
|
||||
|
|
@ -788,6 +802,8 @@ SDL_AppResult SDL_AppEvent(void *appstate, SDL_Event *event) {
|
|||
mS.m->input_open_infinipaint_file_callback(*CustomEvents::get_event<CustomEvents::OpenInfiniPaintFileEvent>());
|
||||
else if(event->type == CustomEvents::AddFileToCanvasEvent::EVENT_NUM)
|
||||
mS.m->input_add_file_to_canvas_callback(*CustomEvents::get_event<CustomEvents::AddFileToCanvasEvent>());
|
||||
else if(event->type == CustomEvents::RefreshTextBoxInputEvent::EVENT_NUM)
|
||||
mS.m->input.refresh_receiving_text_box_input();
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
|
|
|||
Loading…
Add table
Add a link
Reference in a new issue