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;
|
||||
|
||||
EsToolbarAddFileMenu(toolbar);
|
||||
EsFileMenuAddToToolbar(toolbar);
|
||||
button = EsButtonCreate(toolbar, ES_BUTTON_DROPDOWN, ES_STYLE_PUSH_BUTTON_TOOLBAR_BIG, INTERFACE_STRING(ImageEditorImage));
|
||||
EsButtonSetIcon(button, ES_ICON_IMAGE_X_GENERIC);
|
||||
button->accessKey = 'I';
|
||||
|
|
|
@ -281,7 +281,7 @@ void ProcessApplicationMessage(EsMessage *message) {
|
|||
|
||||
EsElement *toolbarMain = instance->toolbarMain = EsWindowGetToolbar(window, true);
|
||||
|
||||
EsToolbarAddFileMenu(toolbarMain);
|
||||
EsFileMenuAddToToolbar(toolbarMain);
|
||||
|
||||
button = EsButtonCreate(toolbarMain, ES_FLAGS_DEFAULT, {}, INTERFACE_STRING(CommonSearchOpen));
|
||||
button->accessKey = 'S';
|
||||
|
|
|
@ -703,11 +703,14 @@ void InstanceClose(EsInstance *instance) {
|
|||
|
||||
EsDialogAddButton(dialog, ES_FLAGS_DEFAULT, ES_STYLE_PUSH_BUTTON_DANGEROUS, INTERFACE_STRING(FileCloseWithModificationsDelete),
|
||||
[] (EsInstance *instance, EsElement *, EsCommand *) {
|
||||
EsDialogClose(instance->window->dialogs.Last());
|
||||
EsInstanceDestroy(instance);
|
||||
});
|
||||
|
||||
EsButton *button = EsDialogAddButton(dialog, ES_BUTTON_DEFAULT, 0, INTERFACE_STRING(FileCloseWithModificationsSave),
|
||||
[] (EsInstance *instance, EsElement *, EsCommand *) {
|
||||
EsDialogClose(instance->window->dialogs.Last());
|
||||
|
||||
APIInstance *apiInstance = (APIInstance *) instance->_private;
|
||||
|
||||
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);
|
||||
|
||||
uint8_t m[2];
|
||||
|
@ -1330,7 +1333,7 @@ void EsInstanceOpenComplete(EsMessage *message, bool success, const char *errorT
|
|||
EsUndoClear(instance->undoManager);
|
||||
}
|
||||
|
||||
InstanceSetModified(instance, false);
|
||||
EsInstanceSetModified(instance, false);
|
||||
}
|
||||
|
||||
EsAssert(!message->instanceOpen.file->operationComplete);
|
||||
|
@ -1359,7 +1362,7 @@ void EsInstanceSaveComplete(EsMessage *message, bool success) {
|
|||
MessageDesktop(buffer, 1, instance->window->handle);
|
||||
|
||||
if (success) {
|
||||
InstanceSetModified(instance, false);
|
||||
EsInstanceSetModified(instance, false);
|
||||
EsRectangle bounds = EsElementGetWindowBounds(instance->window->toolbarSwitcher);
|
||||
size_t messageBytes;
|
||||
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) {
|
||||
InstanceSetModified(manager->instance, true);
|
||||
EsInstanceSetModified(manager->instance, true);
|
||||
}
|
||||
}
|
||||
|
||||
|
|
|
@ -1471,7 +1471,7 @@ bool ApplicationInstanceStart(int64_t applicationID, _EsApplicationStartupInform
|
|||
if (desktop.inShutdown) {
|
||||
return false;
|
||||
}
|
||||
|
||||
|
||||
InstalledApplication *application = nullptr;
|
||||
|
||||
for (uintptr_t i = 0; i < desktop.installedApplications.Length(); i++) {
|
||||
|
@ -1499,6 +1499,10 @@ bool ApplicationInstanceStart(int64_t applicationID, _EsApplicationStartupInform
|
|||
startupInformation = &_startupInformation;
|
||||
}
|
||||
|
||||
if (instance->tab) {
|
||||
EsButtonSetCheck(instance->tab->closeButton, ES_CHECK_UNCHECKED, false);
|
||||
}
|
||||
|
||||
if (instance->tab && instance->tab->notRespondingInstance) {
|
||||
ApplicationInstanceClose(instance->tab->notRespondingInstance);
|
||||
instance->tab->notRespondingInstance = nullptr;
|
||||
|
|
|
@ -5526,7 +5526,7 @@ void FileMenuRename(EsInstance *_instance, EsElement *, EsCommand *) {
|
|||
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?
|
||||
|
||||
// const EsFileMenuSettings *settings = (const EsFileMenuSettings *) element->userData.p;
|
||||
|
@ -5535,7 +5535,7 @@ void FileMenuCreate(EsInstance *_instance, EsElement *element, EsCommand *) {
|
|||
EsInstanceClassEditorSettings *editorSettings = &instance->editorSettings;
|
||||
bool newDocument = !instance->startupInformation || !instance->startupInformation->filePath;
|
||||
|
||||
EsMenu *menu = EsMenuCreate(element, ES_FLAGS_DEFAULT);
|
||||
EsMenu *menu = EsMenuCreate(element, menuFlags);
|
||||
if (!menu) return;
|
||||
EsPanel *panel1 = EsPanelCreate(menu, ES_PANEL_HORIZONTAL | ES_CELL_H_LEFT, &styleFileMenuDocumentInformationPanel1);
|
||||
if (!panel1) goto show;
|
||||
|
@ -5611,7 +5611,11 @@ void FileMenuCreate(EsInstance *_instance, EsElement *element, EsCommand *) {
|
|||
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));
|
||||
if (!button) return;
|
||||
button->accessKey = 'F';
|
||||
|
|
|
@ -2313,6 +2313,7 @@ function void EsInstanceSetClassViewer(ES_INSTANCE_TYPE *instance, const EsInsta
|
|||
function EsApplicationStartupRequest EsInstanceGetStartupRequest(ES_INSTANCE_TYPE *instance);
|
||||
function void EsInstanceOpenComplete(EsMessage *message, bool success, STRING errorText = BLANK_STRING);
|
||||
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 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,
|
||||
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 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) {
|
||||
// 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 *end = (uint8_t *) _end;
|
||||
|
|
|
@ -363,7 +363,6 @@ EsWindowAddSizeAlternative=361
|
|||
EsMenuAddCommandsFromToolbar=362
|
||||
EsPanelStartMovementAnimation=363
|
||||
EsElementStartTransition=364
|
||||
EsToolbarAddFileMenu=365
|
||||
EsFileWriteAllFromHandle=366
|
||||
EsFileWriteAllGatherFromHandle=367
|
||||
EsButtonSetIconFromBits=368
|
||||
|
@ -462,3 +461,6 @@ EsInstanceGetStartupRequest=460
|
|||
EsImageDisplayPaint=461
|
||||
EsElementGetInsetBounds=462
|
||||
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.
|
||||
BUILD_UTILITY("config_editor", "-lX11 -Wno-unused-parameter", "");
|
||||
#endif
|
||||
#ifndef __APPLE__ // Luigi doesn't support macOS.
|
||||
BUILD_UTILITY("reflect_gen", "", "designer/");
|
||||
|
||||
if (CheckDependencies("Utilities.DesignerHeader")) {
|
||||
|
@ -345,8 +346,7 @@ void BuildUtilities() {
|
|||
}
|
||||
}
|
||||
|
||||
#ifndef __APPLE__ // Luigi doesn't support macOS.
|
||||
if (CheckDependencies("Utilities.Designer1") || CheckDependencies("Utilities.Designer2")) {
|
||||
if (CheckDependencies("Utilities.OldDesigner1") || CheckDependencies("Utilities.OldDesigner2")) {
|
||||
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 -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);
|
||||
}
|
||||
}
|
||||
|
||||
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
|
||||
}
|
||||
|
||||
|
@ -1174,6 +1180,9 @@ void DoCommand(const char *l) {
|
|||
} else if (0 == strcmp(l, "designer")) {
|
||||
BuildUtilities();
|
||||
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")) {
|
||||
forceRebuild = true;
|
||||
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)
|
||||
|
||||
#ifdef UI_WINDOWS
|
||||
#undef _UNICODE
|
||||
#undef UNICODE
|
||||
#include <windows.h>
|
||||
|
||||
#define UI_ASSERT(x) do { if (!(x)) { ui.assertionFailure = true; \
|
||||
|
@ -64,6 +66,9 @@
|
|||
#define UI_CLOCK EsTimeStampMs
|
||||
#define UI_CLOCKS_PER_SECOND 1000
|
||||
#define UI_CLOCK_T uint64_t
|
||||
|
||||
// Callback to allow the application to process messages.
|
||||
void _UIMessageProcess(EsMessage *message);
|
||||
#endif
|
||||
|
||||
#ifdef UI_DEBUG
|
||||
|
@ -97,7 +102,7 @@ typedef struct UITheme {
|
|||
|
||||
#define UI_SIZE_TEXTBOX_MARGIN (3)
|
||||
#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_LEFT (4)
|
||||
|
@ -335,6 +340,7 @@ typedef struct UIWindow {
|
|||
#define UI_WINDOW_MENU (1 << 0)
|
||||
#define UI_WINDOW_INSPECTOR (1 << 1)
|
||||
#define UI_WINDOW_CENTER_IN_OWNER (1 << 2)
|
||||
#define UI_WINDOW_MAXIMIZE (1 << 3)
|
||||
|
||||
UIElement e;
|
||||
|
||||
|
@ -483,14 +489,20 @@ typedef struct UITextbox {
|
|||
ptrdiff_t bytes;
|
||||
int carets[2];
|
||||
int scroll;
|
||||
bool rejectNextKey;
|
||||
} UITextbox;
|
||||
|
||||
typedef struct UIMenu {
|
||||
#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;
|
||||
int pointX, pointY;
|
||||
UIScrollBar *vScroll;
|
||||
} UIMenu;
|
||||
#endif
|
||||
|
||||
typedef struct UISlider {
|
||||
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 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 UIDrawRectangle(UIPainter *painter, UIRectangle r, uint32_t mainColor, uint32_t borderColor, UIRectangle borderSize);
|
||||
void UIDrawBorder(UIPainter *painter, UIRectangle r, uint32_t borderColor, UIRectangle borderSize);
|
||||
|
@ -685,6 +697,9 @@ struct {
|
|||
|
||||
#ifdef UI_ESSENCE
|
||||
EsInstance *instance;
|
||||
|
||||
void *menuData[256]; // HACK This limits the number of menu items to 128.
|
||||
uintptr_t menuIndex;
|
||||
#endif
|
||||
|
||||
#ifdef UI_FREETYPE
|
||||
|
@ -1072,10 +1087,22 @@ void UIDrawBlock(UIPainter *painter, UIRectangle rectangle, uint32_t color) {
|
|||
return;
|
||||
}
|
||||
|
||||
#ifdef UI_SSE2
|
||||
__m128i color4 = _mm_set_epi32(color, color, color, color);
|
||||
#endif
|
||||
|
||||
for (int line = rectangle.t; line < rectangle.b; line++) {
|
||||
uint32_t *bits = painter->bits + line * painter->width + rectangle.l;
|
||||
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--) {
|
||||
*bits++ = color;
|
||||
}
|
||||
|
@ -1086,26 +1113,38 @@ void UIDrawBlock(UIPainter *painter, UIRectangle rectangle, uint32_t color) {
|
|||
#endif
|
||||
}
|
||||
|
||||
void UIDrawLine(UIPainter *painter, int x0, int y0, int x1, int y1, uint32_t color) {
|
||||
// Clip the line to the painter's clip rectangle.
|
||||
bool UIDrawLine(UIPainter *painter, int x0, int y0, int x1, int y1, uint32_t color) {
|
||||
// Apply the clip.
|
||||
|
||||
if (x0 > x1) { int t = x0; x0 = x1; x1 = t; }
|
||||
if (y0 > y1) { int t = y0; y0 = y1; y1 = t; }
|
||||
UIRectangle bounds = UIRectangleIntersection(painter->clip, UI_RECT_4(x0, x1, y0, y1));
|
||||
UIRectangle c = painter->clip;
|
||||
int dx = x1 - x0, dy = y1 - y0;
|
||||
int points[8], count = 0;
|
||||
int iLY = dx ? (y0 + (bounds.l - x0) * dy / dx) : 0x7FFFFFFF;
|
||||
int iRY = dx ? (y0 + (bounds.r - x0) * dy / dx) : 0x7FFFFFFF;
|
||||
int iTX = dy ? (x0 + (bounds.t - y0) * dx / dy) : 0x7FFFFFFF;
|
||||
int iBX = dy ? (x0 + (bounds.b - y0) * dx / dy) : 0x7FFFFFFF;
|
||||
if (iLY >= bounds.t && iLY <= bounds.b) points[count + 0] = bounds.l, points[count + 1] = iLY, count += 2;
|
||||
if (iRY >= bounds.t && iRY <= bounds.b) points[count + 0] = bounds.r, points[count + 1] = iRY, count += 2;
|
||||
if (iTX >= bounds.l && iTX <= bounds.r) points[count + 1] = bounds.t, points[count + 0] = iTX, count += 2;
|
||||
if (iBX >= bounds.l && iBX <= bounds.r) points[count + 1] = bounds.b, points[count + 0] = iBX, count += 2;
|
||||
if (count < 4) return;
|
||||
x0 = points[0], y0 = points[1], x1 = points[2], y1 = points[3];
|
||||
if (x0 == x1 && y0 == y1 && count > 4) x1 = points[4], y1 = points[5];
|
||||
const int p[4] = { -dx, dx, -dy, dy };
|
||||
const int q[4] = { x0 - c.l, c.r - x0, y0 - c.t, c.b - y0 };
|
||||
float t0 = 0.0f, t1 = 1.0f; // How far along the line the points end up.
|
||||
|
||||
for (int i = 0; i < 4; i++) {
|
||||
if (!p[i] && q[i] < 0) return false;
|
||||
float r = (float) q[i] / p[i];
|
||||
if (p[i] < 0 && r > t1) return false;
|
||||
if (p[i] > 0 && r < t0) return false;
|
||||
if (p[i] < 0 && r > t0) t0 = r;
|
||||
if (p[i] > 0 && r < t1) t1 = r;
|
||||
}
|
||||
|
||||
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;
|
||||
int dxs = dx < 0 ? -1 : 1;
|
||||
if (dx < 0) dx = -dx;
|
||||
|
||||
// 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) {
|
||||
int m = 2 * dy - dx;
|
||||
|
||||
for (int i = 0; i < dx; i++, bits++) {
|
||||
for (int i = 0; i < dx; i++, bits += dxs) {
|
||||
*bits = color;
|
||||
if (m > 0) bits += painter->width, m -= 2 * dx;
|
||||
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) {
|
||||
*bits = color;
|
||||
if (m > 0) bits++, m -= 2 * dy;
|
||||
if (m > 0) bits += dxs, m -= 2 * dy;
|
||||
m += 2 * dx;
|
||||
}
|
||||
}
|
||||
|
||||
return true;
|
||||
}
|
||||
|
||||
void UIDrawInvert(UIPainter *painter, UIRectangle rectangle) {
|
||||
|
@ -1645,6 +1686,20 @@ UIPanel *UIPanelCreate(UIElement *parent, uint32_t flags) {
|
|||
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) {
|
||||
UIButton *button = (UIButton *) element;
|
||||
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) {
|
||||
UIPainter *painter = (UIPainter *) dp;
|
||||
|
||||
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;
|
||||
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;
|
||||
uint32_t color, textColor;
|
||||
_UIButtonCalculateColors(element, &color, &textColor);
|
||||
|
||||
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 = 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;
|
||||
index++;
|
||||
}
|
||||
|
@ -2785,7 +2845,10 @@ int _UITextboxMessage(UIElement *element, UIMessage message, int di, void *dp) {
|
|||
UIKeyTyped *m = (UIKeyTyped *) dp;
|
||||
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]) {
|
||||
UITextboxMoveCaret(textbox, m->code == UI_KEYCODE_BACKSPACE, element->window->ctrl);
|
||||
}
|
||||
|
@ -3512,6 +3575,7 @@ bool _UIMenusClose() {
|
|||
return anyClosed;
|
||||
}
|
||||
|
||||
#ifndef UI_ESSENCE
|
||||
int _UIMenuItemMessage(UIElement *element, UIMessage message, int di, void *dp) {
|
||||
if (message == UI_MSG_CLICKED) {
|
||||
_UIMenusClose();
|
||||
|
@ -3556,11 +3620,12 @@ int _UIMenuMessage(UIElement *element, UIMessage message, int di, void *dp) {
|
|||
UIElement *child = element->children;
|
||||
int position = element->bounds.t + 2 - menu->vScroll->position;
|
||||
int totalHeight = 0;
|
||||
int scrollBarSize = (menu->e.flags & UI_MENU_NO_SCROLL) ? 0 : UI_SIZE_SCROLL_BAR;
|
||||
|
||||
while (child) {
|
||||
if (~child->flags & UI_ELEMENT_NON_CLIENT) {
|
||||
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 += height;
|
||||
totalHeight += height;
|
||||
|
@ -3570,7 +3635,7 @@ int _UIMenuMessage(UIElement *element, UIMessage message, int di, void *dp) {
|
|||
}
|
||||
|
||||
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->page = UI_RECT_HEIGHT(element->bounds);
|
||||
UIElementMove(&menu->vScroll->e, scrollBarBounds, true);
|
||||
|
@ -3625,6 +3690,7 @@ UIMenu *UIMenuCreate(UIElement *parent, uint32_t flags) {
|
|||
|
||||
return menu;
|
||||
}
|
||||
#endif
|
||||
|
||||
UIRectangle UIElementScreenBounds(UIElement *element) {
|
||||
int x = 0, y = 0;
|
||||
|
@ -3865,7 +3931,9 @@ UIElement *_UIElementPreviousSibling(UIElement *element) {
|
|||
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 (message == UI_MSG_MOUSE_MOVE) {
|
||||
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;
|
||||
}
|
||||
} else if (message == UI_MSG_KEY_TYPED) {
|
||||
bool handled = false;
|
||||
handled = false;
|
||||
|
||||
if (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) {
|
||||
UIElementFocus(element);
|
||||
}
|
||||
|
||||
handled = true;
|
||||
} else if (!window->dialog) {
|
||||
for (intptr_t i = window->shortcutCount - 1; i >= 0; 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
|
||||
&& shortcut->shift == window->shift && shortcut->alt == window->alt) {
|
||||
shortcut->invoke(shortcut->cp);
|
||||
handled = true;
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
@ -4018,6 +4089,7 @@ void _UIWindowInputEvent(UIWindow *window, UIMessage message, int di, void *dp)
|
|||
}
|
||||
|
||||
end: _UIUpdate();
|
||||
return handled;
|
||||
}
|
||||
|
||||
void _UIInitialiseCommon() {
|
||||
|
@ -4259,6 +4331,11 @@ UIWindow *UIWindowCreate(UIWindow *owner, uint32_t flags, const char *cTitle, in
|
|||
| ButtonPressMask | ButtonReleaseMask | KeyPressMask | KeyReleaseMask | StructureNotifyMask
|
||||
| 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) {
|
||||
XMapRaised(ui.display, window->window);
|
||||
}
|
||||
|
@ -4517,6 +4594,22 @@ bool _UIProcessEvent(XEvent *event) {
|
|||
window->alt = true;
|
||||
window->altCode = event->xkey.keycode;
|
||||
_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);
|
||||
|
@ -5083,14 +5176,32 @@ bool _UIMessageLoopSingle(int *result) {
|
|||
if (ui.animating) {
|
||||
// TODO.
|
||||
} else {
|
||||
EsMessageReceive();
|
||||
_UIMessageProcess(EsMessageReceive());
|
||||
}
|
||||
|
||||
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) {
|
||||
// TODO.
|
||||
EsMenuShow(menu);
|
||||
}
|
||||
|
||||
int _UIWindowCanvasMessage(EsElement *element, EsMessage *message) {
|
||||
|
@ -5122,7 +5233,7 @@ int _UIWindowCanvasMessage(EsElement *element, EsMessage *message) {
|
|||
m.text = c;
|
||||
m.textBytes = EsMessageGetInputText(message, c);
|
||||
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) {
|
||||
_UIInspectorSetFocusedWindow(window);
|
||||
} else if (message->type == ES_MSG_USER_START) {
|
||||
|
|
Loading…
Reference in New Issue