From b95807281da30e535d9e8dc3e277a5b3c534e87f Mon Sep 17 00:00:00 2001 From: nakst <> Date: Sun, 26 Sep 2021 16:16:36 +0100 Subject: [PATCH] new menu design --- apps/file_manager/main.cpp | 11 +++++++++-- desktop/gui.cpp | 28 ++++++++++++++-------------- desktop/styles.header | 6 +++--- desktop/theme.cpp | 12 +++++------- kernel/graphics.cpp | 16 ++++++++-------- res/Theme Source.dat | Bin 52990 -> 53108 bytes res/Themes/Theme.dat | Bin 53672 -> 53700 bytes 7 files changed, 39 insertions(+), 34 deletions(-) diff --git a/apps/file_manager/main.cpp b/apps/file_manager/main.cpp index d1cb4de..4cfc718 100644 --- a/apps/file_manager/main.cpp +++ b/apps/file_manager/main.cpp @@ -313,10 +313,17 @@ void BlockingTaskThread(EsGeneric _instance) { void BlockingTaskComplete(Instance *instance) { EsAssert(instance->blockingTaskInProgress); // Task should have been in progress. instance->blockingTaskInProgress = false; - if (instance->blockingTaskReachedTimeout) EsDialogClose(instance->blockingDialog); + + if (instance->blockingTaskReachedTimeout && instance->blockingDialog) { + EsDialogClose(instance->blockingDialog); + } + instance->blockingDialog = nullptr; Task *task = &instance->blockingTask; - if (task->then) task->then(instance, task); + + if (task->then) { + task->then(instance, task); + } } void BlockingTaskQueue(Instance *instance, Task task) { diff --git a/desktop/gui.cpp b/desktop/gui.cpp index 4090b87..69ff719 100644 --- a/desktop/gui.cpp +++ b/desktop/gui.cpp @@ -912,12 +912,9 @@ EsWindow *EsWindowCreate(EsInstance *instance, EsWindowStyle style) { EsSyscall(ES_SYSCALL_WINDOW_SET_PROPERTY, window->handle, style == ES_WINDOW_PLAIN ? ES_WINDOW_SOLID_TRUE : ES_FLAGS_DEFAULT, 0, ES_WINDOW_PROPERTY_SOLID); window->mainPanel = EsPanelCreate(window, ES_ELEMENT_NON_CLIENT | ES_CELL_FILL, nullptr); } else if (style == ES_WINDOW_MENU) { - EsSyscall(ES_SYSCALL_WINDOW_SET_PROPERTY, window->handle, ES_WINDOW_SOLID_TRUE, 9 * theming.scale, ES_WINDOW_PROPERTY_SOLID); - EsSyscall(ES_SYSCALL_WINDOW_SET_PROPERTY, window->handle, BLEND_WINDOW_MATERIAL_GLASS, 0, ES_WINDOW_PROPERTY_MATERIAL); + window->SetStyle(ES_STYLE_MENU_ROOT); - window->SetStyle(ES_STYLE_PANEL_MENU_ROOT); - - EsPanel *panel = EsPanelCreate(window, ES_ELEMENT_NON_CLIENT | ES_PANEL_HORIZONTAL | ES_CELL_FILL, ES_STYLE_PANEL_MENU_CONTAINER); + EsPanel *panel = EsPanelCreate(window, ES_ELEMENT_NON_CLIENT | ES_PANEL_HORIZONTAL | ES_CELL_FILL, ES_STYLE_MENU_CONTAINER); panel->cName = "menu"; panel->separatorStylePart = ES_STYLE_MENU_SEPARATOR_VERTICAL; panel->separatorFlags = ES_CELL_V_FILL; @@ -934,6 +931,9 @@ EsWindow *EsWindowCreate(EsInstance *instance, EsWindowStyle style) { }; window->mainPanel = panel; + + EsSyscall(ES_SYSCALL_WINDOW_SET_PROPERTY, window->handle, ES_WINDOW_SOLID_TRUE, panel->currentStyle->insets.l, ES_WINDOW_PROPERTY_SOLID); + EsSyscall(ES_SYSCALL_WINDOW_SET_PROPERTY, window->handle, BLEND_WINDOW_MATERIAL_GLASS, 0, ES_WINDOW_PROPERTY_MATERIAL); } if (style == ES_WINDOW_INSPECTOR) { @@ -966,7 +966,7 @@ void EsMenuAddSeparator(EsMenu *menu) { } void EsMenuNextColumn(EsMenu *menu, uint64_t flags) { - EsPanelCreate(menu->children[0], ES_PANEL_VERTICAL | ES_CELL_V_TOP | flags, ES_STYLE_PANEL_MENU_COLUMN); + EsPanelCreate(menu->children[0], ES_PANEL_VERTICAL | ES_CELL_V_TOP | flags, ES_STYLE_MENU_COLUMN); } EsElement *EsMenuGetSource(EsMenu *menu) { @@ -1037,20 +1037,20 @@ void EsMenuShow(EsMenu *menu, int fixedWidth, int fixedHeight) { EsRectangle windowBounds = menu->source->window->GetScreenBounds(); - if (position.x + width >= windowBounds.r) { - position.x = windowBounds.r - width - 1; + if (position.x + width - menuInsets.r >= windowBounds.r) { + position.x = windowBounds.r - width - 1 + menuInsets.r; } - if (position.x < windowBounds.l) { - position.x = windowBounds.l; + if (position.x + menuInsets.l < windowBounds.l) { + position.x = windowBounds.l - menuInsets.l; } - if (position.y + height >= windowBounds.b) { - position.y = windowBounds.b - height - 1; + if (position.y + height - menuInsets.b >= windowBounds.b) { + position.y = windowBounds.b - height - 1 + menuInsets.b; } - if (position.y < windowBounds.t) { - position.y = windowBounds.t; + if (position.y + menuInsets.t < windowBounds.t) { + position.y = windowBounds.t - menuInsets.t; } } else { position = EsMouseGetPosition(); diff --git a/desktop/styles.header b/desktop/styles.header index f71f235..076edfc 100644 --- a/desktop/styles.header +++ b/desktop/styles.header @@ -47,6 +47,9 @@ define ES_STYLE_LIST_VIEW_BORDERED (ES_STYLE_CAST(1295)) define ES_STYLE_LIST_DISPLAY_DEFAULT (ES_STYLE_CAST(1441)) private define ES_STYLE_MARKER_DOWN_ARROW (ES_STYLE_CAST(1297)) private define ES_STYLE_MARKER_UP_ARROW (ES_STYLE_CAST(1501)) +private define ES_STYLE_MENU_COLUMN (ES_STYLE_CAST(1321)) +private define ES_STYLE_MENU_CONTAINER (ES_STYLE_CAST(1323)) +private define ES_STYLE_MENU_ROOT (ES_STYLE_CAST(1325)) private define ES_STYLE_MENU_ITEM_HEADER (ES_STYLE_CAST(1299)) private define ES_STYLE_MENU_ITEM_NORMAL (ES_STYLE_CAST(1301)) private define ES_STYLE_MENU_SEPARATOR_HORIZONTAL (ES_STYLE_CAST(1303)) @@ -60,9 +63,6 @@ define ES_STYLE_PANEL_GROUP_BOX (ES_STYLE_CAST(1315)) define ES_STYLE_PANEL_INSET (ES_STYLE_CAST(1641)) private define ES_STYLE_PANEL_INSPECTOR_WINDOW_CONTAINER (ES_STYLE_CAST(1317)) private define ES_STYLE_PANEL_INSPECTOR_WINDOW_ROOT (ES_STYLE_CAST(1319)) -private define ES_STYLE_PANEL_MENU_COLUMN (ES_STYLE_CAST(1321)) -private define ES_STYLE_PANEL_MENU_CONTAINER (ES_STYLE_CAST(1323)) -private define ES_STYLE_PANEL_MENU_ROOT (ES_STYLE_CAST(1325)) define ES_STYLE_PANEL_POPUP (ES_STYLE_CAST(1331)) define ES_STYLE_PANEL_SHEET (ES_STYLE_CAST(1333)) private define ES_STYLE_PANEL_SHUTDOWN_OVERLAY (ES_STYLE_CAST(1335)) diff --git a/desktop/theme.cpp b/desktop/theme.cpp index b0f39c1..0db6a37 100644 --- a/desktop/theme.cpp +++ b/desktop/theme.cpp @@ -547,13 +547,11 @@ void ThemeFillCorner(EsPainter *painter, EsRectangle bounds, int cx, int cy, if (outsideCount == (1 << (2 * STYLE_CORNER_OVERSAMPLING))) { } else if (mainPaint.type == THEME_PAINT_OVERWRITE) { // TODO Support borders when using an overwrite main paint. - uint32_t m1 = ((mainCount << 8) >> STYLE_CORNER_OVERSAMPLING * 2); - uint32_t m2 = 256 - m1; - uint32_t r2 = m2 * (*b & 0x00FF00FF); - uint32_t g2 = m2 * ((*b >> 8) & 0x00FF00FF); - uint32_t r1 = m1 * (mainColor & 0x00FF00FF); - uint32_t g1 = m1 * ((mainColor >> 8) & 0x00FF00FF); - *b = (0xFF00FF00 & (g1 + g2)) | (0x00FF00FF & ((r1 + r2) >> 8)); + // TODO Anti-aliasing (if it's possible). + + if (mainCount > (1 << (2 * STYLE_CORNER_OVERSAMPLING - 1))) { + *b = mainColor; + } } else if (outsideCount || ((borderColor & 0xFF000000) != 0xFF000000) || (mainColor & 0xFF000000) != 0xFF000000) { BlendPixel(b, (mainColor & 0x00FFFFFF) | (((mainAlpha * mainCount) << (24 - STYLE_CORNER_OVERSAMPLING * 2)) & 0xFF000000), painter->target->fullAlpha); diff --git a/kernel/graphics.cpp b/kernel/graphics.cpp index 50ef71d..a599378 100644 --- a/kernel/graphics.cpp +++ b/kernel/graphics.cpp @@ -240,7 +240,7 @@ void Surface::Scroll(EsRectangle region, ptrdiff_t delta, bool vertical) { #define C2(p) ((p & 0x00FF0000) >> 0x10) #define C3(p) ((p & 0xFF000000) >> 0x18) -ES_FUNCTION_OPTIMISE_O2 +ES_FUNCTION_OPTIMISE_O3 void BlurRegionOfImage(uint32_t *image, int width, int height, int stride, uint16_t *k, uintptr_t repeat) { if (width <= 3 || height <= 3) { return; @@ -281,7 +281,7 @@ void BlurRegionOfImage(uint32_t *image, int width, int height, int stride, uint1 } } -ES_FUNCTION_OPTIMISE_O2 +ES_FUNCTION_OPTIMISE_O3 void BlurRegionOfImage(uint32_t *image, int width, int height, int stride, uintptr_t repeat) { if (width <= 3 || height <= 3) { return; @@ -296,9 +296,9 @@ void BlurRegionOfImage(uint32_t *image, int width, int height, int stride, uintp for (int i = 0; i < width; i++, u++, v++) { if (i + 3 < width) g = *v; - *u = (((C0(a) * 0x07 + C0(b) * 0x1A + C0(c) * 0x38 + C0(d) * 0x49 + C0(e) * 0x38 + C0(f) * 0x1A + C0(g) * 0x07) >> 8) << 0x00) - + (((C1(a) * 0x07 + C1(b) * 0x1A + C1(c) * 0x38 + C1(d) * 0x49 + C1(e) * 0x38 + C1(f) * 0x1A + C1(g) * 0x07) >> 8) << 0x08) - + (((C2(a) * 0x07 + C2(b) * 0x1A + C2(c) * 0x38 + C2(d) * 0x49 + C2(e) * 0x38 + C2(f) * 0x1A + C2(g) * 0x07) >> 8) << 0x10) + *u = (((C0(a) * 0x07 + C0(b) * 0x1A + C0(c) * 0x38 + C0(d) * 0x4D + C0(e) * 0x38 + C0(f) * 0x1A + C0(g) * 0x07) >> 8) << 0x00) + + (((C1(a) * 0x07 + C1(b) * 0x1A + C1(c) * 0x38 + C1(d) * 0x4D + C1(e) * 0x38 + C1(f) * 0x1A + C1(g) * 0x07) >> 8) << 0x08) + + (((C2(a) * 0x07 + C2(b) * 0x1A + C2(c) * 0x38 + C2(d) * 0x4D + C2(e) * 0x38 + C2(f) * 0x1A + C2(g) * 0x07) >> 8) << 0x10) + (C3(d) << 0x18); a = b, b = c, c = d, d = e, e = f, f = g; } @@ -314,9 +314,9 @@ void BlurRegionOfImage(uint32_t *image, int width, int height, int stride, uintp for (int i = 0; i < height; i++, u += stride, v += stride) { if (i + 3 < height) g = *v; - *u = (((C0(a) * 0x07 + C0(b) * 0x1A + C0(c) * 0x38 + C0(d) * 0x49 + C0(e) * 0x38 + C0(f) * 0x1A + C0(g) * 0x07) >> 8) << 0x00) - + (((C1(a) * 0x07 + C1(b) * 0x1A + C1(c) * 0x38 + C1(d) * 0x49 + C1(e) * 0x38 + C1(f) * 0x1A + C1(g) * 0x07) >> 8) << 0x08) - + (((C2(a) * 0x07 + C2(b) * 0x1A + C2(c) * 0x38 + C2(d) * 0x49 + C2(e) * 0x38 + C2(f) * 0x1A + C2(g) * 0x07) >> 8) << 0x10) + *u = (((C0(a) * 0x07 + C0(b) * 0x1A + C0(c) * 0x38 + C0(d) * 0x4D + C0(e) * 0x38 + C0(f) * 0x1A + C0(g) * 0x07) >> 8) << 0x00) + + (((C1(a) * 0x07 + C1(b) * 0x1A + C1(c) * 0x38 + C1(d) * 0x4D + C1(e) * 0x38 + C1(f) * 0x1A + C1(g) * 0x07) >> 8) << 0x08) + + (((C2(a) * 0x07 + C2(b) * 0x1A + C2(c) * 0x38 + C2(d) * 0x4D + C2(e) * 0x38 + C2(f) * 0x1A + C2(g) * 0x07) >> 8) << 0x10) + (C3(d) << 0x18); a = b, b = c, c = d, d = e, e = f, f = g; } diff --git a/res/Theme Source.dat b/res/Theme Source.dat index 232da278d9887105ae3017a19f4443e7ff33ce91..7b86dd0e20783ea3c4c56b461368f9499c1c3c1c 100644 GIT binary patch delta 337 zcmex2m-)*)W>zr<1_sZKta_|g2@T!8sd=S(&iOf|xp^Y342+G@4Si6dypqJsywoC5 zplEYggKL{kTPIj1C_leMY_mRVCgbK8Yz1sAl1+?_lO08+H<$CuaWIBWE|ieqmXniI zZU7SvlM~$xC)bEcqKj?5D8}r)IW6g{uc+K3$-4|G3@HtaK$n34GZ1Vp*r38YId{(_ ze%H2!w&0A!l>BnA<m8$?%}gF`llzn9m^_&$C+^DIJY}yVGo!%fYX`owY<_!GnKh{_ zH(LB}Spy^3FP<f-xgM#BDXB%dQKrl-o^6c%Adi5B^UG3;Qd1Nh7#Le7A%p{pQj3cr d!flfodqJv$QwtJ{5=-(SW`s0sjyk=B82}K;amN4v delta 423 zcmew|kNMwRW>zr<1_qanta_}Q3t3Ycy&EP5B<7{&==rARmFhX?=alB=iL^2>Hbys0 zL6OKSNzBYkEfNLFHHS4=x9GI>BgqHl=a-0WzQ|U}#w^jqIQgQK#N-e5oSU<FB{`IQ z8yebzGZIts%Nc&N{$XQCVMu9Y1UiBhiktW*7iySJ?%T~bxldkwa)A>YQ&_`fLp5<u z0U&4q5tA428&AF=Dv2txSyznNTgkcwZaf166BEez29WWBoSdA(+}zwv<&zVOOc~23 zD~6a(E{J5=te^PJS6twOzz4WeplYB_CZ?9M$%TQUn*-PL@@^K|=g7<`xH;tDcNPgl z3k3%T#+FHp9l!v}FH$hH1o7J@Z+1SW&FWQOUoZZ*tbwr?6okR41&Kw8CHX}lGh0F$ p7`wot5brZEc(j){FirvooJ(e6PJTKhU<`qZD;oMXUpT#l835*UfQ|qF diff --git a/res/Themes/Theme.dat b/res/Themes/Theme.dat index dd7f039b8b66d1f153a22eed105898a2004ad8e1..6427ce77969771578ebed18cdf5017ba3f6538e3 100644 GIT binary patch delta 4109 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 PjCDeT+w~V-+gtX3VKI*x delta 4166 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±kr#toqj*pS22$Y%8|dfs=XVR;aPU$oziTu1w?D5hVGJYf_&VqL+q zW$VXuWdZb7&fEvX;8N8L2;cjbU`g0eZMq#oo9aLwrdye(i?G+AOa~!LTcqlo2az*u zOyEr{6Vh^V4;5gNr7olalKuMCm>krV7eu}10U#%ju|WmskHa8a^Utwa8*vs;NiI~F zb20kZ;BmAq8yFjgy3rr#01v=-H)3Ftvf@fm>arg#`FvDLw4Yjw2|_*Cn}^N#upnqJ zoO|JP8R@a3I_gVM9nfRQyB(zsJw?S-R^v=SgBVcyT|-KXx8Q)H9YmY66$cxBx02zz P5R-$nm-Pe3cUAu%SDuPZ