Simplify clipboard API

This commit is contained in:
UnknownShadow200 2021-01-31 18:57:35 +11:00
parent 4b398eb546
commit 083652ebf4
6 changed files with 65 additions and 76 deletions

View File

@ -215,6 +215,12 @@ void Input_SetPressed(int key) {
Input_Pressed[key] = true;
Event_RaiseInput(&InputEvents.Down, key, wasPressed);
#ifndef CC_BUILD_WEB
/* Webclient needs special handling for clipboard copy/paste */
if (key == 'C' && Key_IsActionPressed()) Event_RaiseInput(&InputEvents.Down, INPUT_CLIPBOARD_COPY, 0);
if (key == 'V' && Key_IsActionPressed()) Event_RaiseInput(&InputEvents.Down, INPUT_CLIPBOARD_PASTE, 0);
#endif
/* don't allow multiple left mouse down events */
if (key != KEY_LMOUSE || wasPressed) return;
Pointer_SetPressed(0, true);

View File

@ -44,7 +44,10 @@ enum InputButtons {
/* NOTE: RMOUSE must be before MMOUSE for PlayerClick compatibility */
KEY_XBUTTON1, KEY_XBUTTON2, KEY_LMOUSE, KEY_RMOUSE, KEY_MMOUSE,
INPUT_COUNT
INPUT_COUNT,
INPUT_CLIPBOARD_COPY = 1001,
INPUT_CLIPBOARD_PASTE = 1002
};
/* Simple names for each input button. */

View File

@ -438,13 +438,16 @@ static void LInput_Unselect(void* widget, int idx) {
Window_CloseKeyboard();
}
static void LInput_CopyFromClipboard(cc_string* text, void* widget) {
struct LInput* w = (struct LInput*)widget;
String_UNSAFE_TrimStart(text);
String_UNSAFE_TrimEnd(text);
static void LInput_CopyFromClipboard(struct LInput* w) {
cc_string text; char textBuffer[2048];
String_InitArray(text, textBuffer);
if (w->ClipboardFilter) w->ClipboardFilter(text);
LInput_AppendString(w, text);
Clipboard_GetText(&text);
String_UNSAFE_TrimStart(&text);
String_UNSAFE_TrimEnd(&text);
if (w->ClipboardFilter) w->ClipboardFilter(&text);
LInput_AppendString(w, &text);
}
static void LInput_KeyDown(void* widget, int key, cc_bool was) {
@ -453,10 +456,10 @@ static void LInput_KeyDown(void* widget, int key, cc_bool was) {
LInput_Backspace(w);
} else if (key == KEY_DELETE) {
LInput_Delete(w);
} else if (key == 'C' && Key_IsActionPressed()) {
} else if (key == INPUT_CLIPBOARD_COPY) {
if (w->text.length) Clipboard_SetText(&w->text);
} else if (key == 'V' && Key_IsActionPressed()) {
Clipboard_RequestText(LInput_CopyFromClipboard, w);
} else if (key == INPUT_CLIPBOARD_PASTE) {
LInput_CopyFromClipboard(w);
} else if (key == KEY_ESCAPE) {
LInput_Clear(w);
} else if (key == KEY_LEFT) {

View File

@ -1216,18 +1216,20 @@ static void InputWidget_EndKey(struct InputWidget* w) {
InputWidget_UpdateCaret(w);
}
static void InputWidget_CopyFromClipboard(cc_string* text, void* w) {
InputWidget_AppendText((struct InputWidget*)w, text);
static void InputWidget_CopyFromClipboard(struct InputWidget* w) {
cc_string text; char textBuffer[2048];
String_InitArray(text, textBuffer);
Clipboard_GetText(&text);
InputWidget_AppendText(w, &text);
}
static cc_bool InputWidget_OtherKey(struct InputWidget* w, int key) {
int maxChars = w->GetMaxLines() * INPUTWIDGET_LEN;
if (!Key_IsActionPressed()) return false;
if (key == 'V' && w->text.length < maxChars) {
Clipboard_RequestText(InputWidget_CopyFromClipboard, w);
if (key == INPUT_CLIPBOARD_PASTE && w->text.length < maxChars) {
InputWidget_CopyFromClipboard(w);
return true;
} else if (key == 'C') {
} else if (key == INPUT_CLIPBOARD_COPY) {
if (!w->text.length) return true;
Clipboard_SetText(&w->text);
return true;

View File

@ -16,17 +16,7 @@ struct _WinData WindowInfo;
int Display_ScaleX(int x) { return (int)(x * DisplayInfo.ScaleX); }
int Display_ScaleY(int y) { return (int)(y * DisplayInfo.ScaleY); }
#define Display_CentreX(width) (DisplayInfo.X + (DisplayInfo.Width - width) / 2)
#define Display_CentreY(height) (DisplayInfo.Y + (DisplayInfo.Height - height) / 2)
#ifndef CC_BUILD_WEB
void Clipboard_RequestText(RequestClipboardCallback callback, void* obj) {
cc_string text; char textBuffer[2048];
String_InitArray(text, textBuffer);
Clipboard_GetText(&text);
callback(&text, obj);
}
#endif
#define Display_CentreY(height) (DisplayInfo.Y + (DisplayInfo.Height - height) / 2)
#ifdef CC_BUILD_IOS
/* iOS implements some functions in external interop_ios.m file */
@ -3560,23 +3550,32 @@ void Window_Init(void) {
DisplayInfo.ScaleY = DisplayInfo.ScaleX;
/* Copy text, but only if user isn't selecting something else on the webpage */
/* (don't check window.clipboardData here, that's handled in Clipboard_SetText instead) */
EM_ASM(window.addEventListener('copy',
function(e) {
if (window.getSelection && window.getSelection().toString()) return;
if (window.cc_copyText) {
if (e.clipboardData) { e.clipboardData.setData('text/plain', window.cc_copyText); }
ccall('Window_ReqClipboardText', 'void');
if (!window.cc_copyText) return;
if (window.clipboardData) {
window.clipboardData.setData('Text', window.cc_copyText);
} else if (e.clipboardData) {
e.clipboardData.setData('text/plain', window.cc_copyText);
e.preventDefault();
window.cc_copyText = null;
}
}
window.cc_copyText = null;
});
);
/* Paste text (window.clipboardData is handled in Clipboard_RequestText instead) */
/* Paste text */
EM_ASM(window.addEventListener('paste',
function(e) {
var contents = e.clipboardData ? e.clipboardData.getData('text/plain') : "";
ccall('Window_GotClipboardText', 'void', ['string'], [contents]);
if (window.clipboardData) {
var contents = window.clipboardData.getData('Text');
ccall('Window_GotClipboardText', 'void', ['string'], [contents]);
} else if (e.clipboardData) {
var contents = e.clipboardData.getData('text/plain');
ccall('Window_GotClipboardText', 'void', ['string'], [contents]);
}
});
);
@ -3632,46 +3631,23 @@ void Window_SetTitle(const cc_string* title) {
EM_ASM_({ document.title = UTF8ToString($0); }, str);
}
static RequestClipboardCallback clipboard_func;
static void* clipboard_obj;
EMSCRIPTEN_KEEPALIVE void Window_GotClipboardText(char* src) {
cc_string str; char strBuffer[512];
if (!clipboard_func) return;
String_InitArray(str, strBuffer);
String_AppendUtf8(&str, src, String_CalcLen(src, 2048));
clipboard_func(&str, clipboard_obj);
clipboard_func = NULL;
static char pasteBuffer[512];
static cc_string pasteStr;
EMSCRIPTEN_KEEPALIVE void Window_ReqClipboardText(void) {
Event_RaiseInput(&InputEvents.Down, INPUT_CLIPBOARD_COPY, 0);
}
void Clipboard_GetText(cc_string* value) { }
EMSCRIPTEN_KEEPALIVE void Window_GotClipboardText(char* src) {
String_InitArray(pasteStr, pasteBuffer);
String_AppendUtf8(&pasteStr, src, String_CalcLen(src, 2048));
Event_RaiseInput(&InputEvents.Down, INPUT_CLIPBOARD_PASTE, 0);
}
void Clipboard_GetText(cc_string* value) { String_Copy(value, &pasteStr); }
void Clipboard_SetText(const cc_string* value) {
char str[NATIVE_STR_LEN];
Platform_EncodeUtf8(str, value);
/* For IE11, use window.clipboardData to set the clipboard */
/* For other browsers, instead use the window.copy events */
EM_ASM_({
if (window.clipboardData) {
if (window.getSelection && window.getSelection().toString()) return;
window.clipboardData.setData('Text', UTF8ToString($0));
} else {
window.cc_copyText = UTF8ToString($0);
}
}, str);
}
void Clipboard_RequestText(RequestClipboardCallback callback, void* obj) {
clipboard_func = callback;
clipboard_obj = obj;
/* For IE11, use window.clipboardData to get the clipboard */
EM_ASM_({
if (!window.clipboardData) return;
var contents = window.clipboardData.getData('Text');
ccall('Window_GotClipboardText', 'void', ['string'], [contents]);
});
EM_ASM_({ window.cc_copyText = UTF8ToString($0); }, str);
}
void Window_Show(void) { }

View File

@ -82,15 +82,14 @@ void Window_Create(int width, int height);
/* Sets the text of the titlebar above the window. */
CC_API void Window_SetTitle(const cc_string* title);
typedef void (*RequestClipboardCallback)(cc_string* value, void* obj);
/* Gets the text currently on the clipboard. */
/* NOTE: On most platforms this function can be called at any time. */
/* In web backend, can only be called during INPUT_CLIPBOARD_PASTE event. */
CC_API void Clipboard_GetText(cc_string* value);
/* Sets the text currently on the clipboard. */
/* NOTE: On most platforms this function can be called at any time. */
/* In web backend, can only be called during INPUT_CLIPBOARD_COPY event. */
CC_API void Clipboard_SetText(const cc_string* value);
/* Calls a callback function when text is retrieved from the clipboard. */
/* NOTE: On most platforms this just calls Clipboard_GetText. */
/* With emscripten however, the callback is instead called when a 'paste' event arrives. */
void Clipboard_RequestText(RequestClipboardCallback callback, void* obj);
/* Makes the window visible and focussed on screen. */
void Window_Show(void);