mirror of https://gitlab.com/nakst/essence
start designer rewrite
This commit is contained in:
parent
78ab907d00
commit
fe5b3adb7b
|
@ -716,7 +716,7 @@ void InstanceCreate(EsMessage *message) {
|
||||||
|
|
||||||
EsButton *button;
|
EsButton *button;
|
||||||
|
|
||||||
EsToolbarAddFileMenu(toolbar);
|
EsFileMenuAddToToolbar(toolbar);
|
||||||
button = EsButtonCreate(toolbar, ES_BUTTON_DROPDOWN, ES_STYLE_PUSH_BUTTON_TOOLBAR_BIG, INTERFACE_STRING(ImageEditorImage));
|
button = EsButtonCreate(toolbar, ES_BUTTON_DROPDOWN, ES_STYLE_PUSH_BUTTON_TOOLBAR_BIG, INTERFACE_STRING(ImageEditorImage));
|
||||||
EsButtonSetIcon(button, ES_ICON_IMAGE_X_GENERIC);
|
EsButtonSetIcon(button, ES_ICON_IMAGE_X_GENERIC);
|
||||||
button->accessKey = 'I';
|
button->accessKey = 'I';
|
||||||
|
|
|
@ -281,7 +281,7 @@ void ProcessApplicationMessage(EsMessage *message) {
|
||||||
|
|
||||||
EsElement *toolbarMain = instance->toolbarMain = EsWindowGetToolbar(window, true);
|
EsElement *toolbarMain = instance->toolbarMain = EsWindowGetToolbar(window, true);
|
||||||
|
|
||||||
EsToolbarAddFileMenu(toolbarMain);
|
EsFileMenuAddToToolbar(toolbarMain);
|
||||||
|
|
||||||
button = EsButtonCreate(toolbarMain, ES_FLAGS_DEFAULT, {}, INTERFACE_STRING(CommonSearchOpen));
|
button = EsButtonCreate(toolbarMain, ES_FLAGS_DEFAULT, {}, INTERFACE_STRING(CommonSearchOpen));
|
||||||
button->accessKey = 'S';
|
button->accessKey = 'S';
|
||||||
|
|
|
@ -703,11 +703,14 @@ void InstanceClose(EsInstance *instance) {
|
||||||
|
|
||||||
EsDialogAddButton(dialog, ES_FLAGS_DEFAULT, ES_STYLE_PUSH_BUTTON_DANGEROUS, INTERFACE_STRING(FileCloseWithModificationsDelete),
|
EsDialogAddButton(dialog, ES_FLAGS_DEFAULT, ES_STYLE_PUSH_BUTTON_DANGEROUS, INTERFACE_STRING(FileCloseWithModificationsDelete),
|
||||||
[] (EsInstance *instance, EsElement *, EsCommand *) {
|
[] (EsInstance *instance, EsElement *, EsCommand *) {
|
||||||
|
EsDialogClose(instance->window->dialogs.Last());
|
||||||
EsInstanceDestroy(instance);
|
EsInstanceDestroy(instance);
|
||||||
});
|
});
|
||||||
|
|
||||||
EsButton *button = EsDialogAddButton(dialog, ES_BUTTON_DEFAULT, 0, INTERFACE_STRING(FileCloseWithModificationsSave),
|
EsButton *button = EsDialogAddButton(dialog, ES_BUTTON_DEFAULT, 0, INTERFACE_STRING(FileCloseWithModificationsSave),
|
||||||
[] (EsInstance *instance, EsElement *, EsCommand *) {
|
[] (EsInstance *instance, EsElement *, EsCommand *) {
|
||||||
|
EsDialogClose(instance->window->dialogs.Last());
|
||||||
|
|
||||||
APIInstance *apiInstance = (APIInstance *) instance->_private;
|
APIInstance *apiInstance = (APIInstance *) instance->_private;
|
||||||
|
|
||||||
if (apiInstance->startupInformation->filePathBytes) {
|
if (apiInstance->startupInformation->filePathBytes) {
|
||||||
|
@ -1288,7 +1291,7 @@ EsMessage *EsMessageReceive() {
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
void InstanceSetModified(EsInstance *instance, bool modified) {
|
void EsInstanceSetModified(EsInstance *instance, bool modified) {
|
||||||
EsCommandSetEnabled(EsCommandByID(instance, ES_COMMAND_SAVE), modified);
|
EsCommandSetEnabled(EsCommandByID(instance, ES_COMMAND_SAVE), modified);
|
||||||
|
|
||||||
uint8_t m[2];
|
uint8_t m[2];
|
||||||
|
@ -1330,7 +1333,7 @@ void EsInstanceOpenComplete(EsMessage *message, bool success, const char *errorT
|
||||||
EsUndoClear(instance->undoManager);
|
EsUndoClear(instance->undoManager);
|
||||||
}
|
}
|
||||||
|
|
||||||
InstanceSetModified(instance, false);
|
EsInstanceSetModified(instance, false);
|
||||||
}
|
}
|
||||||
|
|
||||||
EsAssert(!message->instanceOpen.file->operationComplete);
|
EsAssert(!message->instanceOpen.file->operationComplete);
|
||||||
|
@ -1359,7 +1362,7 @@ void EsInstanceSaveComplete(EsMessage *message, bool success) {
|
||||||
MessageDesktop(buffer, 1, instance->window->handle);
|
MessageDesktop(buffer, 1, instance->window->handle);
|
||||||
|
|
||||||
if (success) {
|
if (success) {
|
||||||
InstanceSetModified(instance, false);
|
EsInstanceSetModified(instance, false);
|
||||||
EsRectangle bounds = EsElementGetWindowBounds(instance->window->toolbarSwitcher);
|
EsRectangle bounds = EsElementGetWindowBounds(instance->window->toolbarSwitcher);
|
||||||
size_t messageBytes;
|
size_t messageBytes;
|
||||||
char *message = EsStringAllocateAndFormat(&messageBytes, "Saved to %s", // TODO Localization.
|
char *message = EsStringAllocateAndFormat(&messageBytes, "Saved to %s", // TODO Localization.
|
||||||
|
@ -1763,7 +1766,7 @@ void EsUndoPush(EsUndoManager *manager, EsUndoCallback callback, const void *ite
|
||||||
}
|
}
|
||||||
|
|
||||||
if (manager->instance->undoManager == manager) {
|
if (manager->instance->undoManager == manager) {
|
||||||
InstanceSetModified(manager->instance, true);
|
EsInstanceSetModified(manager->instance, true);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
|
@ -1471,7 +1471,7 @@ bool ApplicationInstanceStart(int64_t applicationID, _EsApplicationStartupInform
|
||||||
if (desktop.inShutdown) {
|
if (desktop.inShutdown) {
|
||||||
return false;
|
return false;
|
||||||
}
|
}
|
||||||
|
|
||||||
InstalledApplication *application = nullptr;
|
InstalledApplication *application = nullptr;
|
||||||
|
|
||||||
for (uintptr_t i = 0; i < desktop.installedApplications.Length(); i++) {
|
for (uintptr_t i = 0; i < desktop.installedApplications.Length(); i++) {
|
||||||
|
@ -1499,6 +1499,10 @@ bool ApplicationInstanceStart(int64_t applicationID, _EsApplicationStartupInform
|
||||||
startupInformation = &_startupInformation;
|
startupInformation = &_startupInformation;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
if (instance->tab) {
|
||||||
|
EsButtonSetCheck(instance->tab->closeButton, ES_CHECK_UNCHECKED, false);
|
||||||
|
}
|
||||||
|
|
||||||
if (instance->tab && instance->tab->notRespondingInstance) {
|
if (instance->tab && instance->tab->notRespondingInstance) {
|
||||||
ApplicationInstanceClose(instance->tab->notRespondingInstance);
|
ApplicationInstanceClose(instance->tab->notRespondingInstance);
|
||||||
instance->tab->notRespondingInstance = nullptr;
|
instance->tab->notRespondingInstance = nullptr;
|
||||||
|
|
|
@ -5526,7 +5526,7 @@ void FileMenuRename(EsInstance *_instance, EsElement *, EsCommand *) {
|
||||||
instance->fileMenuNameTextbox->messageUser = FileMenuNameTextboxMessage;
|
instance->fileMenuNameTextbox->messageUser = FileMenuNameTextboxMessage;
|
||||||
}
|
}
|
||||||
|
|
||||||
void FileMenuCreate(EsInstance *_instance, EsElement *element, EsCommand *) {
|
void EsFileMenuCreate(EsInstance *_instance, EsElement *element, uint64_t menuFlags) {
|
||||||
// TODO Make this user-customizable?
|
// TODO Make this user-customizable?
|
||||||
|
|
||||||
// const EsFileMenuSettings *settings = (const EsFileMenuSettings *) element->userData.p;
|
// const EsFileMenuSettings *settings = (const EsFileMenuSettings *) element->userData.p;
|
||||||
|
@ -5535,7 +5535,7 @@ void FileMenuCreate(EsInstance *_instance, EsElement *element, EsCommand *) {
|
||||||
EsInstanceClassEditorSettings *editorSettings = &instance->editorSettings;
|
EsInstanceClassEditorSettings *editorSettings = &instance->editorSettings;
|
||||||
bool newDocument = !instance->startupInformation || !instance->startupInformation->filePath;
|
bool newDocument = !instance->startupInformation || !instance->startupInformation->filePath;
|
||||||
|
|
||||||
EsMenu *menu = EsMenuCreate(element, ES_FLAGS_DEFAULT);
|
EsMenu *menu = EsMenuCreate(element, menuFlags);
|
||||||
if (!menu) return;
|
if (!menu) return;
|
||||||
EsPanel *panel1 = EsPanelCreate(menu, ES_PANEL_HORIZONTAL | ES_CELL_H_LEFT, &styleFileMenuDocumentInformationPanel1);
|
EsPanel *panel1 = EsPanelCreate(menu, ES_PANEL_HORIZONTAL | ES_CELL_H_LEFT, &styleFileMenuDocumentInformationPanel1);
|
||||||
if (!panel1) goto show;
|
if (!panel1) goto show;
|
||||||
|
@ -5611,7 +5611,11 @@ void FileMenuCreate(EsInstance *_instance, EsElement *element, EsCommand *) {
|
||||||
show: EsMenuShow(menu);
|
show: EsMenuShow(menu);
|
||||||
}
|
}
|
||||||
|
|
||||||
void EsToolbarAddFileMenu(EsElement *element, const EsFileMenuSettings *settings) {
|
void FileMenuCreate(EsInstance *_instance, EsElement *element, EsCommand *) {
|
||||||
|
EsFileMenuCreate(_instance, element);
|
||||||
|
}
|
||||||
|
|
||||||
|
void EsFileMenuAddToToolbar(EsElement *element, const EsFileMenuSettings *settings) {
|
||||||
EsButton *button = EsButtonCreate(element, ES_BUTTON_DROPDOWN, 0, INTERFACE_STRING(CommonFileMenu));
|
EsButton *button = EsButtonCreate(element, ES_BUTTON_DROPDOWN, 0, INTERFACE_STRING(CommonFileMenu));
|
||||||
if (!button) return;
|
if (!button) return;
|
||||||
button->accessKey = 'F';
|
button->accessKey = 'F';
|
||||||
|
|
|
@ -2313,6 +2313,7 @@ function void EsInstanceSetClassViewer(ES_INSTANCE_TYPE *instance, const EsInsta
|
||||||
function EsApplicationStartupRequest EsInstanceGetStartupRequest(ES_INSTANCE_TYPE *instance);
|
function EsApplicationStartupRequest EsInstanceGetStartupRequest(ES_INSTANCE_TYPE *instance);
|
||||||
function void EsInstanceOpenComplete(EsMessage *message, bool success, STRING errorText = BLANK_STRING);
|
function void EsInstanceOpenComplete(EsMessage *message, bool success, STRING errorText = BLANK_STRING);
|
||||||
function void EsInstanceSaveComplete(EsMessage *message, bool success);
|
function void EsInstanceSaveComplete(EsMessage *message, bool success);
|
||||||
|
function void EsInstanceSetModified(ES_INSTANCE_TYPE *instance, bool modified);
|
||||||
|
|
||||||
function EsError EsUserTaskStart(EsUserTaskCallback callback, EsGeneric data, STRING title, uint32_t iconID);
|
function EsError EsUserTaskStart(EsUserTaskCallback callback, EsGeneric data, STRING title, uint32_t iconID);
|
||||||
function void EsUserTaskSetProgress(EsUserTask *task, double progress, EsFileOffsetDifference bytesPerSecond); // Set bytesPerSecond to -1 if not applicable.
|
function void EsUserTaskSetProgress(EsUserTask *task, double progress, EsFileOffsetDifference bytesPerSecond); // Set bytesPerSecond to -1 if not applicable.
|
||||||
|
@ -2389,7 +2390,8 @@ function EsDialog *EsDialogShow(EsWindow *window, STRING title, STRING content,
|
||||||
function EsButton *EsDialogAddButton(EsDialog *dialog, uint64_t flags = ES_FLAGS_DEFAULT, EsStyle *style = ES_NULL,
|
function EsButton *EsDialogAddButton(EsDialog *dialog, uint64_t flags = ES_FLAGS_DEFAULT, EsStyle *style = ES_NULL,
|
||||||
STRING label = BLANK_STRING, EsCommandCallback callback = ES_NULL);
|
STRING label = BLANK_STRING, EsCommandCallback callback = ES_NULL);
|
||||||
|
|
||||||
function void EsToolbarAddFileMenu(EsElement *element, const EsFileMenuSettings *settings = ES_NULL);
|
function void EsFileMenuAddToToolbar(EsElement *toolbar, const EsFileMenuSettings *settings = ES_NULL);
|
||||||
|
function void EsFileMenuCreate(ES_INSTANCE_TYPE *instance, EsElement *parent, uint64_t flags = ES_FLAGS_DEFAULT);
|
||||||
|
|
||||||
private function EsHandle _EsWindowGetHandle(EsWindow *window);
|
private function EsHandle _EsWindowGetHandle(EsWindow *window);
|
||||||
private function void _EsUISetFont(EsFontFamily id);
|
private function void _EsUISetFont(EsFontFamily id);
|
||||||
|
|
|
@ -1323,7 +1323,7 @@ void EsMemoryZero(void *destination, size_t bytes) {
|
||||||
}
|
}
|
||||||
|
|
||||||
void EsMemoryMove(void *_start, void *_end, intptr_t amount, bool zeroEmptySpace) {
|
void EsMemoryMove(void *_start, void *_end, intptr_t amount, bool zeroEmptySpace) {
|
||||||
// TODO Prevent this from being optimised out in the kernel./
|
// TODO Prevent this from being optimised out in the kernel.
|
||||||
|
|
||||||
uint8_t *start = (uint8_t *) _start;
|
uint8_t *start = (uint8_t *) _start;
|
||||||
uint8_t *end = (uint8_t *) _end;
|
uint8_t *end = (uint8_t *) _end;
|
||||||
|
|
|
@ -363,7 +363,6 @@ EsWindowAddSizeAlternative=361
|
||||||
EsMenuAddCommandsFromToolbar=362
|
EsMenuAddCommandsFromToolbar=362
|
||||||
EsPanelStartMovementAnimation=363
|
EsPanelStartMovementAnimation=363
|
||||||
EsElementStartTransition=364
|
EsElementStartTransition=364
|
||||||
EsToolbarAddFileMenu=365
|
|
||||||
EsFileWriteAllFromHandle=366
|
EsFileWriteAllFromHandle=366
|
||||||
EsFileWriteAllGatherFromHandle=367
|
EsFileWriteAllGatherFromHandle=367
|
||||||
EsButtonSetIconFromBits=368
|
EsButtonSetIconFromBits=368
|
||||||
|
@ -462,3 +461,6 @@ EsInstanceGetStartupRequest=460
|
||||||
EsImageDisplayPaint=461
|
EsImageDisplayPaint=461
|
||||||
EsElementGetInsetBounds=462
|
EsElementGetInsetBounds=462
|
||||||
EsDialogShow=463
|
EsDialogShow=463
|
||||||
|
EsInstanceSetModified=464
|
||||||
|
EsFileMenuAddToToolbar=465
|
||||||
|
EsFileMenuCreate=466
|
||||||
|
|
13
util/build.c
13
util/build.c
|
@ -334,6 +334,7 @@ void BuildUtilities() {
|
||||||
#ifndef __APPLE__ // Luigi doesn't support macOS.
|
#ifndef __APPLE__ // Luigi doesn't support macOS.
|
||||||
BUILD_UTILITY("config_editor", "-lX11 -Wno-unused-parameter", "");
|
BUILD_UTILITY("config_editor", "-lX11 -Wno-unused-parameter", "");
|
||||||
#endif
|
#endif
|
||||||
|
#ifndef __APPLE__ // Luigi doesn't support macOS.
|
||||||
BUILD_UTILITY("reflect_gen", "", "designer/");
|
BUILD_UTILITY("reflect_gen", "", "designer/");
|
||||||
|
|
||||||
if (CheckDependencies("Utilities.DesignerHeader")) {
|
if (CheckDependencies("Utilities.DesignerHeader")) {
|
||||||
|
@ -345,8 +346,7 @@ void BuildUtilities() {
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
#ifndef __APPLE__ // Luigi doesn't support macOS.
|
if (CheckDependencies("Utilities.OldDesigner1") || CheckDependencies("Utilities.OldDesigner2")) {
|
||||||
if (CheckDependencies("Utilities.Designer1") || CheckDependencies("Utilities.Designer2")) {
|
|
||||||
if (!CallSystem("gcc -MMD -o bin/designer.o -c util/designer/designer.c -g -std=c2x -fsanitize=address " WARNING_FLAGS_C)
|
if (!CallSystem("gcc -MMD -o bin/designer.o -c util/designer/designer.c -g -std=c2x -fsanitize=address " WARNING_FLAGS_C)
|
||||||
&& !CallSystem("gcc -MMD -o bin/designer_luigi.o -c util/designer/designer_luigi.c -g -std=c2x " WARNING_FLAGS_C)
|
&& !CallSystem("gcc -MMD -o bin/designer_luigi.o -c util/designer/designer_luigi.c -g -std=c2x " WARNING_FLAGS_C)
|
||||||
&& !CallSystem("gcc -o bin/designer -g bin/designer.o bin/designer_luigi.o -lX11 -lm -fsanitize=address ")) {
|
&& !CallSystem("gcc -o bin/designer -g bin/designer.o bin/designer_luigi.o -lX11 -lm -fsanitize=address ")) {
|
||||||
|
@ -354,6 +354,12 @@ void BuildUtilities() {
|
||||||
ParseDependencies("bin/designer_luigi.d", "Utilities.Designer2", false);
|
ParseDependencies("bin/designer_luigi.d", "Utilities.Designer2", false);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
if (CheckDependencies("Utilities.Designer")) {
|
||||||
|
if (!CallSystem("g++ -MMD -D UI_LINUX util/designer2.cpp -o bin/designer2 -g -lX11 -Wno-unused-parameter " WARNING_FLAGS)) {
|
||||||
|
ParseDependencies("bin/designer2.d", "Utilities.Designer", false);
|
||||||
|
}
|
||||||
|
}
|
||||||
#endif
|
#endif
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -1174,6 +1180,9 @@ void DoCommand(const char *l) {
|
||||||
} else if (0 == strcmp(l, "designer")) {
|
} else if (0 == strcmp(l, "designer")) {
|
||||||
BuildUtilities();
|
BuildUtilities();
|
||||||
CallSystem("bin/designer \"res/Theme Source.dat\" \"res/Themes/Theme.dat\" \"res/Cursors.png\" \"desktop/styles.header\"");
|
CallSystem("bin/designer \"res/Theme Source.dat\" \"res/Themes/Theme.dat\" \"res/Cursors.png\" \"desktop/styles.header\"");
|
||||||
|
} else if (0 == strcmp(l, "designer2")) {
|
||||||
|
BuildUtilities();
|
||||||
|
CallSystem("bin/designer2");
|
||||||
} else if (0 == strcmp(l, "replace-many")) {
|
} else if (0 == strcmp(l, "replace-many")) {
|
||||||
forceRebuild = true;
|
forceRebuild = true;
|
||||||
printf("Enter the name of the replacement file: ");
|
printf("Enter the name of the replacement file: ");
|
||||||
|
|
File diff suppressed because it is too large
Load Diff
|
@ -0,0 +1,16 @@
|
||||||
|
[general]
|
||||||
|
name=Designer
|
||||||
|
icon=icon_applications_interfacedesign
|
||||||
|
|
||||||
|
[build]
|
||||||
|
source=util/designer2.cpp
|
||||||
|
compile_flags=-D UI_ESSENCE -Wno-unused-parameter
|
||||||
|
|
||||||
|
[@file_type]
|
||||||
|
extension=designer
|
||||||
|
name=Designer file
|
||||||
|
icon=icon_text_css
|
||||||
|
|
||||||
|
[@handler]
|
||||||
|
extension=designer
|
||||||
|
action=open
|
191
util/luigi.h
191
util/luigi.h
|
@ -22,6 +22,8 @@
|
||||||
#define _UI_TO_STRING_2(x) _UI_TO_STRING_1(x)
|
#define _UI_TO_STRING_2(x) _UI_TO_STRING_1(x)
|
||||||
|
|
||||||
#ifdef UI_WINDOWS
|
#ifdef UI_WINDOWS
|
||||||
|
#undef _UNICODE
|
||||||
|
#undef UNICODE
|
||||||
#include <windows.h>
|
#include <windows.h>
|
||||||
|
|
||||||
#define UI_ASSERT(x) do { if (!(x)) { ui.assertionFailure = true; \
|
#define UI_ASSERT(x) do { if (!(x)) { ui.assertionFailure = true; \
|
||||||
|
@ -64,6 +66,9 @@
|
||||||
#define UI_CLOCK EsTimeStampMs
|
#define UI_CLOCK EsTimeStampMs
|
||||||
#define UI_CLOCKS_PER_SECOND 1000
|
#define UI_CLOCKS_PER_SECOND 1000
|
||||||
#define UI_CLOCK_T uint64_t
|
#define UI_CLOCK_T uint64_t
|
||||||
|
|
||||||
|
// Callback to allow the application to process messages.
|
||||||
|
void _UIMessageProcess(EsMessage *message);
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
#ifdef UI_DEBUG
|
#ifdef UI_DEBUG
|
||||||
|
@ -97,7 +102,7 @@ typedef struct UITheme {
|
||||||
|
|
||||||
#define UI_SIZE_TEXTBOX_MARGIN (3)
|
#define UI_SIZE_TEXTBOX_MARGIN (3)
|
||||||
#define UI_SIZE_TEXTBOX_WIDTH (200)
|
#define UI_SIZE_TEXTBOX_WIDTH (200)
|
||||||
#define UI_SIZE_TEXTBOX_HEIGHT (25)
|
#define UI_SIZE_TEXTBOX_HEIGHT (27)
|
||||||
|
|
||||||
#define UI_SIZE_TAB_PANE_SPACE_TOP (2)
|
#define UI_SIZE_TAB_PANE_SPACE_TOP (2)
|
||||||
#define UI_SIZE_TAB_PANE_SPACE_LEFT (4)
|
#define UI_SIZE_TAB_PANE_SPACE_LEFT (4)
|
||||||
|
@ -335,6 +340,7 @@ typedef struct UIWindow {
|
||||||
#define UI_WINDOW_MENU (1 << 0)
|
#define UI_WINDOW_MENU (1 << 0)
|
||||||
#define UI_WINDOW_INSPECTOR (1 << 1)
|
#define UI_WINDOW_INSPECTOR (1 << 1)
|
||||||
#define UI_WINDOW_CENTER_IN_OWNER (1 << 2)
|
#define UI_WINDOW_CENTER_IN_OWNER (1 << 2)
|
||||||
|
#define UI_WINDOW_MAXIMIZE (1 << 3)
|
||||||
|
|
||||||
UIElement e;
|
UIElement e;
|
||||||
|
|
||||||
|
@ -483,14 +489,20 @@ typedef struct UITextbox {
|
||||||
ptrdiff_t bytes;
|
ptrdiff_t bytes;
|
||||||
int carets[2];
|
int carets[2];
|
||||||
int scroll;
|
int scroll;
|
||||||
|
bool rejectNextKey;
|
||||||
} UITextbox;
|
} UITextbox;
|
||||||
|
|
||||||
typedef struct UIMenu {
|
|
||||||
#define UI_MENU_PLACE_ABOVE (1 << 0)
|
#define UI_MENU_PLACE_ABOVE (1 << 0)
|
||||||
|
#define UI_MENU_NO_SCROLL (1 << 1)
|
||||||
|
#ifdef UI_ESSENCE
|
||||||
|
typedef EsMenu UIMenu;
|
||||||
|
#else
|
||||||
|
typedef struct UIMenu {
|
||||||
UIElement e;
|
UIElement e;
|
||||||
int pointX, pointY;
|
int pointX, pointY;
|
||||||
UIScrollBar *vScroll;
|
UIScrollBar *vScroll;
|
||||||
} UIMenu;
|
} UIMenu;
|
||||||
|
#endif
|
||||||
|
|
||||||
typedef struct UISlider {
|
typedef struct UISlider {
|
||||||
UIElement e;
|
UIElement e;
|
||||||
|
@ -596,7 +608,7 @@ void UICodeInsertContent(UICode *code, const char *content, ptrdiff_t byteCount,
|
||||||
|
|
||||||
void UIDrawBlock(UIPainter *painter, UIRectangle rectangle, uint32_t color);
|
void UIDrawBlock(UIPainter *painter, UIRectangle rectangle, uint32_t color);
|
||||||
void UIDrawInvert(UIPainter *painter, UIRectangle rectangle);
|
void UIDrawInvert(UIPainter *painter, UIRectangle rectangle);
|
||||||
void UIDrawLine(UIPainter *painter, int x0, int y0, int x1, int y1, uint32_t color);
|
bool UIDrawLine(UIPainter *painter, int x0, int y0, int x1, int y1, uint32_t color); // Returns false if the line was not visible.
|
||||||
void UIDrawGlyph(UIPainter *painter, int x, int y, int c, uint32_t color);
|
void UIDrawGlyph(UIPainter *painter, int x, int y, int c, uint32_t color);
|
||||||
void UIDrawRectangle(UIPainter *painter, UIRectangle r, uint32_t mainColor, uint32_t borderColor, UIRectangle borderSize);
|
void UIDrawRectangle(UIPainter *painter, UIRectangle r, uint32_t mainColor, uint32_t borderColor, UIRectangle borderSize);
|
||||||
void UIDrawBorder(UIPainter *painter, UIRectangle r, uint32_t borderColor, UIRectangle borderSize);
|
void UIDrawBorder(UIPainter *painter, UIRectangle r, uint32_t borderColor, UIRectangle borderSize);
|
||||||
|
@ -685,6 +697,9 @@ struct {
|
||||||
|
|
||||||
#ifdef UI_ESSENCE
|
#ifdef UI_ESSENCE
|
||||||
EsInstance *instance;
|
EsInstance *instance;
|
||||||
|
|
||||||
|
void *menuData[256]; // HACK This limits the number of menu items to 128.
|
||||||
|
uintptr_t menuIndex;
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
#ifdef UI_FREETYPE
|
#ifdef UI_FREETYPE
|
||||||
|
@ -1072,10 +1087,22 @@ void UIDrawBlock(UIPainter *painter, UIRectangle rectangle, uint32_t color) {
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
#ifdef UI_SSE2
|
||||||
|
__m128i color4 = _mm_set_epi32(color, color, color, color);
|
||||||
|
#endif
|
||||||
|
|
||||||
for (int line = rectangle.t; line < rectangle.b; line++) {
|
for (int line = rectangle.t; line < rectangle.b; line++) {
|
||||||
uint32_t *bits = painter->bits + line * painter->width + rectangle.l;
|
uint32_t *bits = painter->bits + line * painter->width + rectangle.l;
|
||||||
int count = UI_RECT_WIDTH(rectangle);
|
int count = UI_RECT_WIDTH(rectangle);
|
||||||
|
|
||||||
|
#ifdef UI_SSE2
|
||||||
|
while (count >= 4) {
|
||||||
|
_mm_storeu_si128((__m128i *) bits, color4);
|
||||||
|
bits += 4;
|
||||||
|
count -= 4;
|
||||||
|
}
|
||||||
|
#endif
|
||||||
|
|
||||||
while (count--) {
|
while (count--) {
|
||||||
*bits++ = color;
|
*bits++ = color;
|
||||||
}
|
}
|
||||||
|
@ -1086,26 +1113,38 @@ void UIDrawBlock(UIPainter *painter, UIRectangle rectangle, uint32_t color) {
|
||||||
#endif
|
#endif
|
||||||
}
|
}
|
||||||
|
|
||||||
void UIDrawLine(UIPainter *painter, int x0, int y0, int x1, int y1, uint32_t color) {
|
bool UIDrawLine(UIPainter *painter, int x0, int y0, int x1, int y1, uint32_t color) {
|
||||||
// Clip the line to the painter's clip rectangle.
|
// Apply the clip.
|
||||||
|
|
||||||
if (x0 > x1) { int t = x0; x0 = x1; x1 = t; }
|
UIRectangle c = painter->clip;
|
||||||
if (y0 > y1) { int t = y0; y0 = y1; y1 = t; }
|
|
||||||
UIRectangle bounds = UIRectangleIntersection(painter->clip, UI_RECT_4(x0, x1, y0, y1));
|
|
||||||
int dx = x1 - x0, dy = y1 - y0;
|
int dx = x1 - x0, dy = y1 - y0;
|
||||||
int points[8], count = 0;
|
const int p[4] = { -dx, dx, -dy, dy };
|
||||||
int iLY = dx ? (y0 + (bounds.l - x0) * dy / dx) : 0x7FFFFFFF;
|
const int q[4] = { x0 - c.l, c.r - x0, y0 - c.t, c.b - y0 };
|
||||||
int iRY = dx ? (y0 + (bounds.r - x0) * dy / dx) : 0x7FFFFFFF;
|
float t0 = 0.0f, t1 = 1.0f; // How far along the line the points end up.
|
||||||
int iTX = dy ? (x0 + (bounds.t - y0) * dx / dy) : 0x7FFFFFFF;
|
|
||||||
int iBX = dy ? (x0 + (bounds.b - y0) * dx / dy) : 0x7FFFFFFF;
|
for (int i = 0; i < 4; i++) {
|
||||||
if (iLY >= bounds.t && iLY <= bounds.b) points[count + 0] = bounds.l, points[count + 1] = iLY, count += 2;
|
if (!p[i] && q[i] < 0) return false;
|
||||||
if (iRY >= bounds.t && iRY <= bounds.b) points[count + 0] = bounds.r, points[count + 1] = iRY, count += 2;
|
float r = (float) q[i] / p[i];
|
||||||
if (iTX >= bounds.l && iTX <= bounds.r) points[count + 1] = bounds.t, points[count + 0] = iTX, count += 2;
|
if (p[i] < 0 && r > t1) return false;
|
||||||
if (iBX >= bounds.l && iBX <= bounds.r) points[count + 1] = bounds.b, points[count + 0] = iBX, count += 2;
|
if (p[i] > 0 && r < t0) return false;
|
||||||
if (count < 4) return;
|
if (p[i] < 0 && r > t0) t0 = r;
|
||||||
x0 = points[0], y0 = points[1], x1 = points[2], y1 = points[3];
|
if (p[i] > 0 && r < t1) t1 = r;
|
||||||
if (x0 == x1 && y0 == y1 && count > 4) x1 = points[4], y1 = points[5];
|
}
|
||||||
|
|
||||||
|
x1 = x0 + t1 * dx, y1 = y0 + t1 * dy;
|
||||||
|
x0 += t0 * dx, y0 += t0 * dy;
|
||||||
|
|
||||||
|
// Calculate the delta X and delta Y.
|
||||||
|
|
||||||
|
if (y1 < y0) {
|
||||||
|
int t;
|
||||||
|
t = x0, x0 = x1, x1 = t;
|
||||||
|
t = y0, y0 = y1, y1 = t;
|
||||||
|
}
|
||||||
|
|
||||||
dx = x1 - x0, dy = y1 - y0;
|
dx = x1 - x0, dy = y1 - y0;
|
||||||
|
int dxs = dx < 0 ? -1 : 1;
|
||||||
|
if (dx < 0) dx = -dx;
|
||||||
|
|
||||||
// Draw the line using Bresenham's line algorithm.
|
// Draw the line using Bresenham's line algorithm.
|
||||||
|
|
||||||
|
@ -1114,7 +1153,7 @@ void UIDrawLine(UIPainter *painter, int x0, int y0, int x1, int y1, uint32_t col
|
||||||
if (dy * dy < dx * dx) {
|
if (dy * dy < dx * dx) {
|
||||||
int m = 2 * dy - dx;
|
int m = 2 * dy - dx;
|
||||||
|
|
||||||
for (int i = 0; i < dx; i++, bits++) {
|
for (int i = 0; i < dx; i++, bits += dxs) {
|
||||||
*bits = color;
|
*bits = color;
|
||||||
if (m > 0) bits += painter->width, m -= 2 * dx;
|
if (m > 0) bits += painter->width, m -= 2 * dx;
|
||||||
m += 2 * dy;
|
m += 2 * dy;
|
||||||
|
@ -1124,10 +1163,12 @@ void UIDrawLine(UIPainter *painter, int x0, int y0, int x1, int y1, uint32_t col
|
||||||
|
|
||||||
for (int i = 0; i < dy; i++, bits += painter->width) {
|
for (int i = 0; i < dy; i++, bits += painter->width) {
|
||||||
*bits = color;
|
*bits = color;
|
||||||
if (m > 0) bits++, m -= 2 * dy;
|
if (m > 0) bits += dxs, m -= 2 * dy;
|
||||||
m += 2 * dx;
|
m += 2 * dx;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
return true;
|
||||||
}
|
}
|
||||||
|
|
||||||
void UIDrawInvert(UIPainter *painter, UIRectangle rectangle) {
|
void UIDrawInvert(UIPainter *painter, UIRectangle rectangle) {
|
||||||
|
@ -1645,6 +1686,20 @@ UIPanel *UIPanelCreate(UIElement *parent, uint32_t flags) {
|
||||||
return panel;
|
return panel;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
void _UIButtonCalculateColors(UIElement *element, uint32_t *color, uint32_t *textColor) {
|
||||||
|
bool disabled = element->flags & UI_ELEMENT_DISABLED;
|
||||||
|
bool focused = element == element->window->focused;
|
||||||
|
bool pressed = element == element->window->pressed;
|
||||||
|
bool hovered = element == element->window->hovered;
|
||||||
|
*color = disabled ? ui.theme.buttonDisabled
|
||||||
|
: (pressed && hovered) ? ui.theme.buttonPressed
|
||||||
|
: (pressed || hovered) ? ui.theme.buttonHovered
|
||||||
|
: focused ? ui.theme.selected : ui.theme.buttonNormal;
|
||||||
|
*textColor = disabled ? ui.theme.textDisabled
|
||||||
|
: *color == ui.theme.selected ? ui.theme.textSelected : ui.theme.text;
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
int _UIButtonMessage(UIElement *element, UIMessage message, int di, void *dp) {
|
int _UIButtonMessage(UIElement *element, UIMessage message, int di, void *dp) {
|
||||||
UIButton *button = (UIButton *) element;
|
UIButton *button = (UIButton *) element;
|
||||||
bool isMenuItem = element->flags & UI_BUTTON_MENU_ITEM;
|
bool isMenuItem = element->flags & UI_BUTTON_MENU_ITEM;
|
||||||
|
@ -1668,16 +1723,8 @@ int _UIButtonMessage(UIElement *element, UIMessage message, int di, void *dp) {
|
||||||
} else if (message == UI_MSG_PAINT) {
|
} else if (message == UI_MSG_PAINT) {
|
||||||
UIPainter *painter = (UIPainter *) dp;
|
UIPainter *painter = (UIPainter *) dp;
|
||||||
|
|
||||||
bool disabled = element->flags & UI_ELEMENT_DISABLED;
|
uint32_t color, textColor;
|
||||||
bool focused = element == element->window->focused;
|
_UIButtonCalculateColors(element, &color, &textColor);
|
||||||
bool pressed = element == element->window->pressed;
|
|
||||||
bool hovered = element == element->window->hovered;
|
|
||||||
uint32_t color = disabled ? ui.theme.buttonDisabled
|
|
||||||
: (pressed && hovered) ? ui.theme.buttonPressed
|
|
||||||
: (pressed || hovered) ? ui.theme.buttonHovered
|
|
||||||
: focused ? ui.theme.selected : ui.theme.buttonNormal;
|
|
||||||
uint32_t textColor = disabled ? ui.theme.textDisabled
|
|
||||||
: color == ui.theme.selected ? ui.theme.textSelected : ui.theme.text;
|
|
||||||
|
|
||||||
UIDrawRectangle(painter, element->bounds, color, ui.theme.border, UI_RECT_1(isMenuItem ? 0 : 1));
|
UIDrawRectangle(painter, element->bounds, color, ui.theme.border, UI_RECT_1(isMenuItem ? 0 : 1));
|
||||||
|
|
||||||
|
@ -1931,6 +1978,19 @@ int _UITabPaneMessage(UIElement *element, UIMessage message, int di, void *dp) {
|
||||||
child->flags |= UI_ELEMENT_HIDE;
|
child->flags |= UI_ELEMENT_HIDE;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
child = child->next;
|
||||||
|
index++;
|
||||||
|
}
|
||||||
|
} else if (message == UI_MSG_GET_HEIGHT) {
|
||||||
|
UIElement *child = element->children;
|
||||||
|
int index = 0;
|
||||||
|
int baseHeight = UI_SIZE_BUTTON_HEIGHT * element->window->scale;
|
||||||
|
|
||||||
|
while (child) {
|
||||||
|
if (tabPane->active == index) {
|
||||||
|
return baseHeight + UIElementMessage(child, UI_MSG_GET_HEIGHT, di, dp);
|
||||||
|
}
|
||||||
|
|
||||||
child = child->next;
|
child = child->next;
|
||||||
index++;
|
index++;
|
||||||
}
|
}
|
||||||
|
@ -2785,7 +2845,10 @@ int _UITextboxMessage(UIElement *element, UIMessage message, int di, void *dp) {
|
||||||
UIKeyTyped *m = (UIKeyTyped *) dp;
|
UIKeyTyped *m = (UIKeyTyped *) dp;
|
||||||
bool handled = true;
|
bool handled = true;
|
||||||
|
|
||||||
if (m->code == UI_KEYCODE_BACKSPACE || m->code == UI_KEYCODE_DELETE) {
|
if (textbox->rejectNextKey) {
|
||||||
|
textbox->rejectNextKey = false;
|
||||||
|
handled = false;
|
||||||
|
} else if (m->code == UI_KEYCODE_BACKSPACE || m->code == UI_KEYCODE_DELETE) {
|
||||||
if (textbox->carets[0] == textbox->carets[1]) {
|
if (textbox->carets[0] == textbox->carets[1]) {
|
||||||
UITextboxMoveCaret(textbox, m->code == UI_KEYCODE_BACKSPACE, element->window->ctrl);
|
UITextboxMoveCaret(textbox, m->code == UI_KEYCODE_BACKSPACE, element->window->ctrl);
|
||||||
}
|
}
|
||||||
|
@ -3512,6 +3575,7 @@ bool _UIMenusClose() {
|
||||||
return anyClosed;
|
return anyClosed;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
#ifndef UI_ESSENCE
|
||||||
int _UIMenuItemMessage(UIElement *element, UIMessage message, int di, void *dp) {
|
int _UIMenuItemMessage(UIElement *element, UIMessage message, int di, void *dp) {
|
||||||
if (message == UI_MSG_CLICKED) {
|
if (message == UI_MSG_CLICKED) {
|
||||||
_UIMenusClose();
|
_UIMenusClose();
|
||||||
|
@ -3556,11 +3620,12 @@ int _UIMenuMessage(UIElement *element, UIMessage message, int di, void *dp) {
|
||||||
UIElement *child = element->children;
|
UIElement *child = element->children;
|
||||||
int position = element->bounds.t + 2 - menu->vScroll->position;
|
int position = element->bounds.t + 2 - menu->vScroll->position;
|
||||||
int totalHeight = 0;
|
int totalHeight = 0;
|
||||||
|
int scrollBarSize = (menu->e.flags & UI_MENU_NO_SCROLL) ? 0 : UI_SIZE_SCROLL_BAR;
|
||||||
|
|
||||||
while (child) {
|
while (child) {
|
||||||
if (~child->flags & UI_ELEMENT_NON_CLIENT) {
|
if (~child->flags & UI_ELEMENT_NON_CLIENT) {
|
||||||
int height = UIElementMessage(child, UI_MSG_GET_HEIGHT, 0, 0);
|
int height = UIElementMessage(child, UI_MSG_GET_HEIGHT, 0, 0);
|
||||||
UIElementMove(child, UI_RECT_4(element->bounds.l + 2, element->bounds.r - UI_SIZE_SCROLL_BAR - 2,
|
UIElementMove(child, UI_RECT_4(element->bounds.l + 2, element->bounds.r - scrollBarSize - 2,
|
||||||
position, position + height), false);
|
position, position + height), false);
|
||||||
position += height;
|
position += height;
|
||||||
totalHeight += height;
|
totalHeight += height;
|
||||||
|
@ -3570,7 +3635,7 @@ int _UIMenuMessage(UIElement *element, UIMessage message, int di, void *dp) {
|
||||||
}
|
}
|
||||||
|
|
||||||
UIRectangle scrollBarBounds = element->bounds;
|
UIRectangle scrollBarBounds = element->bounds;
|
||||||
scrollBarBounds.l = scrollBarBounds.r - UI_SIZE_SCROLL_BAR * element->window->scale;
|
scrollBarBounds.l = scrollBarBounds.r - scrollBarSize * element->window->scale;
|
||||||
menu->vScroll->maximum = totalHeight;
|
menu->vScroll->maximum = totalHeight;
|
||||||
menu->vScroll->page = UI_RECT_HEIGHT(element->bounds);
|
menu->vScroll->page = UI_RECT_HEIGHT(element->bounds);
|
||||||
UIElementMove(&menu->vScroll->e, scrollBarBounds, true);
|
UIElementMove(&menu->vScroll->e, scrollBarBounds, true);
|
||||||
|
@ -3625,6 +3690,7 @@ UIMenu *UIMenuCreate(UIElement *parent, uint32_t flags) {
|
||||||
|
|
||||||
return menu;
|
return menu;
|
||||||
}
|
}
|
||||||
|
#endif
|
||||||
|
|
||||||
UIRectangle UIElementScreenBounds(UIElement *element) {
|
UIRectangle UIElementScreenBounds(UIElement *element) {
|
||||||
int x = 0, y = 0;
|
int x = 0, y = 0;
|
||||||
|
@ -3865,7 +3931,9 @@ UIElement *_UIElementPreviousSibling(UIElement *element) {
|
||||||
return sibling;
|
return sibling;
|
||||||
}
|
}
|
||||||
|
|
||||||
void _UIWindowInputEvent(UIWindow *window, UIMessage message, int di, void *dp) {
|
bool _UIWindowInputEvent(UIWindow *window, UIMessage message, int di, void *dp) {
|
||||||
|
bool handled = true;
|
||||||
|
|
||||||
if (window->pressed) {
|
if (window->pressed) {
|
||||||
if (message == UI_MSG_MOUSE_MOVE) {
|
if (message == UI_MSG_MOUSE_MOVE) {
|
||||||
UIElementMessage(window->pressed, UI_MSG_MOUSE_DRAG, di, dp);
|
UIElementMessage(window->pressed, UI_MSG_MOUSE_DRAG, di, dp);
|
||||||
|
@ -3943,7 +4011,7 @@ void _UIWindowInputEvent(UIWindow *window, UIMessage message, int di, void *dp)
|
||||||
element = element->parent;
|
element = element->parent;
|
||||||
}
|
}
|
||||||
} else if (message == UI_MSG_KEY_TYPED) {
|
} else if (message == UI_MSG_KEY_TYPED) {
|
||||||
bool handled = false;
|
handled = false;
|
||||||
|
|
||||||
if (window->focused) {
|
if (window->focused) {
|
||||||
UIElement *element = window->focused;
|
UIElement *element = window->focused;
|
||||||
|
@ -3993,6 +4061,8 @@ void _UIWindowInputEvent(UIWindow *window, UIMessage message, int di, void *dp)
|
||||||
if (~element->flags & UI_ELEMENT_WINDOW) {
|
if (~element->flags & UI_ELEMENT_WINDOW) {
|
||||||
UIElementFocus(element);
|
UIElementFocus(element);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
handled = true;
|
||||||
} else if (!window->dialog) {
|
} else if (!window->dialog) {
|
||||||
for (intptr_t i = window->shortcutCount - 1; i >= 0; i--) {
|
for (intptr_t i = window->shortcutCount - 1; i >= 0; i--) {
|
||||||
UIShortcut *shortcut = window->shortcuts + i;
|
UIShortcut *shortcut = window->shortcuts + i;
|
||||||
|
@ -4000,6 +4070,7 @@ void _UIWindowInputEvent(UIWindow *window, UIMessage message, int di, void *dp)
|
||||||
if (shortcut->code == m->code && shortcut->ctrl == window->ctrl
|
if (shortcut->code == m->code && shortcut->ctrl == window->ctrl
|
||||||
&& shortcut->shift == window->shift && shortcut->alt == window->alt) {
|
&& shortcut->shift == window->shift && shortcut->alt == window->alt) {
|
||||||
shortcut->invoke(shortcut->cp);
|
shortcut->invoke(shortcut->cp);
|
||||||
|
handled = true;
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@ -4018,6 +4089,7 @@ void _UIWindowInputEvent(UIWindow *window, UIMessage message, int di, void *dp)
|
||||||
}
|
}
|
||||||
|
|
||||||
end: _UIUpdate();
|
end: _UIUpdate();
|
||||||
|
return handled;
|
||||||
}
|
}
|
||||||
|
|
||||||
void _UIInitialiseCommon() {
|
void _UIInitialiseCommon() {
|
||||||
|
@ -4259,6 +4331,11 @@ UIWindow *UIWindowCreate(UIWindow *owner, uint32_t flags, const char *cTitle, in
|
||||||
| ButtonPressMask | ButtonReleaseMask | KeyPressMask | KeyReleaseMask | StructureNotifyMask
|
| ButtonPressMask | ButtonReleaseMask | KeyPressMask | KeyReleaseMask | StructureNotifyMask
|
||||||
| EnterWindowMask | LeaveWindowMask | ButtonMotionMask | KeymapStateMask | FocusChangeMask);
|
| EnterWindowMask | LeaveWindowMask | ButtonMotionMask | KeymapStateMask | FocusChangeMask);
|
||||||
|
|
||||||
|
if (flags & UI_WINDOW_MAXIMIZE) {
|
||||||
|
Atom atoms[2] = { XInternAtom(ui.display, "_NET_WM_STATE_MAXIMIZED_HORZ", 0), XInternAtom(ui.display, "_NET_WM_STATE_MAXIMIZED_VERT", 0) };
|
||||||
|
XChangeProperty(ui.display, window->window, XInternAtom(ui.display, "_NET_WM_STATE", 0), XA_ATOM, 32, PropModeReplace, (unsigned char *) atoms, 2);
|
||||||
|
}
|
||||||
|
|
||||||
if (~flags & UI_WINDOW_MENU) {
|
if (~flags & UI_WINDOW_MENU) {
|
||||||
XMapRaised(ui.display, window->window);
|
XMapRaised(ui.display, window->window);
|
||||||
}
|
}
|
||||||
|
@ -4517,6 +4594,22 @@ bool _UIProcessEvent(XEvent *event) {
|
||||||
window->alt = true;
|
window->alt = true;
|
||||||
window->altCode = event->xkey.keycode;
|
window->altCode = event->xkey.keycode;
|
||||||
_UIWindowInputEvent(window, UI_MSG_MOUSE_MOVE, 0, 0);
|
_UIWindowInputEvent(window, UI_MSG_MOUSE_MOVE, 0, 0);
|
||||||
|
} else if (symbol == XK_KP_Left) {
|
||||||
|
m.code = UI_KEYCODE_LEFT;
|
||||||
|
} else if (symbol == XK_KP_Right) {
|
||||||
|
m.code = UI_KEYCODE_RIGHT;
|
||||||
|
} else if (symbol == XK_KP_Up) {
|
||||||
|
m.code = UI_KEYCODE_UP;
|
||||||
|
} else if (symbol == XK_KP_Down) {
|
||||||
|
m.code = UI_KEYCODE_DOWN;
|
||||||
|
} else if (symbol == XK_KP_Home) {
|
||||||
|
m.code = UI_KEYCODE_HOME;
|
||||||
|
} else if (symbol == XK_KP_End) {
|
||||||
|
m.code = UI_KEYCODE_END;
|
||||||
|
} else if (symbol == XK_KP_Enter) {
|
||||||
|
m.code = UI_KEYCODE_ENTER;
|
||||||
|
} else if (symbol == XK_KP_Delete) {
|
||||||
|
m.code = UI_KEYCODE_DELETE;
|
||||||
}
|
}
|
||||||
|
|
||||||
_UIWindowInputEvent(window, UI_MSG_KEY_TYPED, 0, &m);
|
_UIWindowInputEvent(window, UI_MSG_KEY_TYPED, 0, &m);
|
||||||
|
@ -5083,14 +5176,32 @@ bool _UIMessageLoopSingle(int *result) {
|
||||||
if (ui.animating) {
|
if (ui.animating) {
|
||||||
// TODO.
|
// TODO.
|
||||||
} else {
|
} else {
|
||||||
EsMessageReceive();
|
_UIMessageProcess(EsMessageReceive());
|
||||||
}
|
}
|
||||||
|
|
||||||
return true;
|
return true;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
UIMenu *UIMenuCreate(UIElement *parent, uint32_t flags) {
|
||||||
|
ui.menuIndex = 0;
|
||||||
|
return EsMenuCreate(parent->window->window, ES_MENU_AT_CURSOR);
|
||||||
|
}
|
||||||
|
|
||||||
|
void _UIMenuItemCallback(EsMenu *menu, EsGeneric context) {
|
||||||
|
((void (*)(void *)) ui.menuData[context.u * 2 + 0])(ui.menuData[context.u * 2 + 1]);
|
||||||
|
}
|
||||||
|
|
||||||
|
void UIMenuAddItem(UIMenu *menu, uint32_t flags, const char *label, ptrdiff_t labelBytes, void (*invoke)(void *cp), void *cp) {
|
||||||
|
EsAssert(ui.menuIndex < 128);
|
||||||
|
ui.menuData[ui.menuIndex * 2 + 0] = (void *) invoke;
|
||||||
|
ui.menuData[ui.menuIndex * 2 + 1] = cp;
|
||||||
|
EsMenuAddItem(menu, (flags & UI_BUTTON_CHECKED) ? ES_MENU_ITEM_CHECKED : ES_FLAGS_DEFAULT,
|
||||||
|
label, labelBytes, _UIMenuItemCallback, ui.menuIndex);
|
||||||
|
ui.menuIndex++;
|
||||||
|
}
|
||||||
|
|
||||||
void UIMenuShow(UIMenu *menu) {
|
void UIMenuShow(UIMenu *menu) {
|
||||||
// TODO.
|
EsMenuShow(menu);
|
||||||
}
|
}
|
||||||
|
|
||||||
int _UIWindowCanvasMessage(EsElement *element, EsMessage *message) {
|
int _UIWindowCanvasMessage(EsElement *element, EsMessage *message) {
|
||||||
|
@ -5122,7 +5233,7 @@ int _UIWindowCanvasMessage(EsElement *element, EsMessage *message) {
|
||||||
m.text = c;
|
m.text = c;
|
||||||
m.textBytes = EsMessageGetInputText(message, c);
|
m.textBytes = EsMessageGetInputText(message, c);
|
||||||
m.code = message->keyboard.scancode;
|
m.code = message->keyboard.scancode;
|
||||||
_UIWindowInputEvent(window, UI_MSG_KEY_TYPED, 0, &m);
|
return _UIWindowInputEvent(window, UI_MSG_KEY_TYPED, 0, &m) ? ES_HANDLED : 0;
|
||||||
} else if (message->type == ES_MSG_MOUSE_LEFT_CLICK) {
|
} else if (message->type == ES_MSG_MOUSE_LEFT_CLICK) {
|
||||||
_UIInspectorSetFocusedWindow(window);
|
_UIInspectorSetFocusedWindow(window);
|
||||||
} else if (message->type == ES_MSG_USER_START) {
|
} else if (message->type == ES_MSG_USER_START) {
|
||||||
|
|
Loading…
Reference in New Issue