From d2f3c851a7273f35f128d4ea58b752251c5d5001 Mon Sep 17 00:00:00 2001 From: Jaakko Keränen Date: Sat, 13 Feb 2021 21:15:51 +0200 Subject: Windows: Custom frame preference; further minor tweaks --- src/app.c | 21 +++++++++++ src/prefs.c | 1 + src/prefs.h | 1 + src/ui/color.c | 4 ++ src/ui/color.h | 1 + src/ui/util.c | 9 ++++- src/ui/window.c | 111 +++++++++++++++++++++++++++++++------------------------- 7 files changed, 96 insertions(+), 52 deletions(-) (limited to 'src') diff --git a/src/app.c b/src/app.c index b815a0ab..cc3614ea 100644 --- a/src/app.c +++ b/src/app.c @@ -158,6 +158,9 @@ static iString *serializePrefs_App_(const iApp *d) { iString *str = new_String(); const iSidebarWidget *sidebar = findWidget_App("sidebar"); const iSidebarWidget *sidebar2 = findWidget_App("sidebar2"); +#if defined (LAGRANGE_CUSTOM_FRAME) + appendFormat_String(str, "customframe arg:%d\n", d->prefs.customFrame); +#endif appendFormat_String(str, "window.retain arg:%d\n", d->prefs.retainWindowSize); if (d->prefs.retainWindowSize) { int w, h, x, y; @@ -283,6 +286,9 @@ static void loadPrefs_App_(iApp *d) { if (equal_Command(cmd, "uiscale")) { setUiScale_Window(get_Window(), argf_Command(cmd)); } + else if (equal_Command(cmd, "customframe")) { + d->prefs.customFrame = arg_Command(cmd); + } else if (equal_Command(cmd, "window.setrect") && !argLabel_Command(cmd, "snap")) { const iInt2 pos = coord_Command(cmd); d->initialWindowRect = init_Rect( @@ -298,6 +304,9 @@ static void loadPrefs_App_(iApp *d) { else { /* default preference values */ } +#if !defined (LAGRANGE_CUSTOM_FRAME) + d->prefs.customFrame = iFalse; +#endif iRelease(f); } @@ -603,6 +612,11 @@ void processEvents_App(enum iAppEventMode eventMode) { switch (ev.type) { case SDL_QUIT: d->isRunning = iFalse; + if (findWidget_App("prefs")) { + /* Make sure changed preferences get saved. */ + postCommand_App("prefs.dismiss"); + processEvents_App(postedEventsOnly_AppEventMode); + } goto backToMainLoop; case SDL_DROPFILE: { iBool wasUsed = processEvent_Window(d->window, &ev); @@ -909,6 +923,8 @@ static iBool handlePrefsCommands_(iWidget *d, const char *cmd) { postCommandf_App("downloads path:%s", cstr_String(text_InputWidget(findChild_Widget(d, "prefs.downloads")))); #endif + postCommandf_App("customframe arg:%d", + isSelected_Widget(findChild_Widget(d, "prefs.customframe"))); postCommandf_App("window.retain arg:%d", isSelected_Widget(findChild_Widget(d, "prefs.retainwindow"))); postCommandf_App("smoothscroll arg:%d", @@ -1120,6 +1136,10 @@ iBool handleCommand_App(const char *cmd) { d->prefs.retainWindowSize = arg_Command(cmd); return iTrue; } + else if (equal_Command(cmd, "customframe")) { + d->prefs.customFrame = arg_Command(cmd); + return iTrue; + } else if (equal_Command(cmd, "window.maximize")) { if (!argLabel_Command(cmd, "toggle")) { setSnap_Window(d->window, maximized_WindowSnap); @@ -1409,6 +1429,7 @@ iBool handleCommand_App(const char *cmd) { setToggle_Widget(findChild_Widget(dlg, "prefs.smoothscroll"), d->prefs.smoothScrolling); setToggle_Widget(findChild_Widget(dlg, "prefs.imageloadscroll"), d->prefs.loadImageInsteadOfScrolling); setToggle_Widget(findChild_Widget(dlg, "prefs.ostheme"), d->prefs.useSystemTheme); + setToggle_Widget(findChild_Widget(dlg, "prefs.customframe"), d->prefs.customFrame); setToggle_Widget(findChild_Widget(dlg, "prefs.retainwindow"), d->prefs.retainWindowSize); setText_InputWidget(findChild_Widget(dlg, "prefs.uiscale"), collectNewFormat_String("%g", uiScale_Window(d->window))); diff --git a/src/prefs.c b/src/prefs.c index fe755c63..89e7f203 100644 --- a/src/prefs.c +++ b/src/prefs.c @@ -26,6 +26,7 @@ void init_Prefs(iPrefs *d) { d->dialogTab = 0; d->useSystemTheme = iTrue; d->theme = dark_ColorTheme; + d->customFrame = iTrue; d->retainWindowSize = iTrue; d->uiScale = 1.0f; /* default set elsewhere */ d->zoomPercent = 100; diff --git a/src/prefs.h b/src/prefs.h index 1c3274d9..de354a04 100644 --- a/src/prefs.h +++ b/src/prefs.h @@ -38,6 +38,7 @@ struct Impl_Prefs { /* Window */ iBool useSystemTheme; enum iColorTheme theme; + iBool customFrame; /* when LAGRANGE_CUSTOM_FRAME is defined */ iBool retainWindowSize; float uiScale; int zoomPercent; diff --git a/src/ui/color.c b/src/ui/color.c index 0227bd3e..870db2d0 100644 --- a/src/ui/color.c +++ b/src/ui/color.c @@ -89,6 +89,7 @@ void setThemePalette_Color(enum iColorTheme theme) { copy_(uiTextShortcut_ColorId, cyan_ColorId); copy_(uiTextAction_ColorId, cyan_ColorId); copy_(uiTextCaution_ColorId, orange_ColorId); + copy_(uiTextAppTitle_ColorId, cyan_ColorId); copy_(uiFrame_ColorId, black_ColorId); copy_(uiEmboss1_ColorId, gray25_ColorId); copy_(uiEmboss2_ColorId, black_ColorId); @@ -134,6 +135,7 @@ void setThemePalette_Color(enum iColorTheme theme) { copy_(uiTextShortcut_ColorId, cyan_ColorId); copy_(uiTextAction_ColorId, cyan_ColorId); copy_(uiTextCaution_ColorId, orange_ColorId); + copy_(uiTextAppTitle_ColorId, cyan_ColorId); copy_(uiFrame_ColorId, gray25_ColorId); copy_(uiEmboss1_ColorId, gray50_ColorId); copy_(uiEmboss2_ColorId, black_ColorId); @@ -178,6 +180,7 @@ void setThemePalette_Color(enum iColorTheme theme) { copy_(uiTextShortcut_ColorId, brown_ColorId); copy_(uiTextAction_ColorId, brown_ColorId); copy_(uiTextCaution_ColorId, teal_ColorId); + copy_(uiTextAppTitle_ColorId, teal_ColorId); copy_(uiFrame_ColorId, gray50_ColorId); copy_(uiEmboss1_ColorId, white_ColorId); copy_(uiEmboss2_ColorId, gray50_ColorId); @@ -223,6 +226,7 @@ void setThemePalette_Color(enum iColorTheme theme) { copy_(uiTextShortcut_ColorId, brown_ColorId); copy_(uiTextAction_ColorId, brown_ColorId); copy_(uiTextCaution_ColorId, teal_ColorId); + copy_(uiTextAppTitle_ColorId, teal_ColorId); copy_(uiFrame_ColorId, gray75_ColorId); copy_(uiEmboss1_ColorId, white_ColorId); copy_(uiEmboss2_ColorId, white_ColorId); diff --git a/src/ui/color.h b/src/ui/color.h index 6849ff2b..69dbe797 100644 --- a/src/ui/color.h +++ b/src/ui/color.h @@ -106,6 +106,7 @@ enum iColorId { uiBackgroundFolder_ColorId, uiTextDim_ColorId, uiSubheading_ColorId, + uiTextAppTitle_ColorId, /* content theme colors */ tmFirst_ColorId, diff --git a/src/ui/util.c b/src/ui/util.c index d64a93b6..75a770eb 100644 --- a/src/ui/util.c +++ b/src/ui/util.c @@ -1083,10 +1083,15 @@ iWidget *makePreferences_Widget(void) { setId_Widget(addChild_Widget(themes, iClob(new_LabelWidget("Pure White", "theme.set arg:3"))), "prefs.theme.3"); } addChildFlags_Widget(values, iClob(themes), arrangeHorizontal_WidgetFlag | arrangeSize_WidgetFlag); - addChild_Widget(headings, iClob(makeHeading_Widget("Retain window size:"))); - addChild_Widget(values, iClob(makeToggle_Widget("prefs.retainwindow"))); +#if defined (LAGRANGE_CUSTOM_FRAME) + addChild_Widget(headings, iClob(makeHeading_Widget("Custom window frame:"))); + addChild_Widget(values, iClob(makeToggle_Widget("prefs.customframe"))); +#endif + makeTwoColumnHeading_("SIZING", headings, values); addChild_Widget(headings, iClob(makeHeading_Widget("UI scale factor:"))); setId_Widget(addChild_Widget(values, iClob(new_InputWidget(8))), "prefs.uiscale"); + addChild_Widget(headings, iClob(makeHeading_Widget("Retain placement:"))); + addChild_Widget(values, iClob(makeToggle_Widget("prefs.retainwindow"))); makeTwoColumnHeading_("WIDE LAYOUT", headings, values); addChild_Widget(headings, iClob(makeHeading_Widget("Site icon:"))); addChild_Widget(values, iClob(makeToggle_Widget("prefs.sideicon"))); diff --git a/src/ui/window.c b/src/ui/window.c index ef4a6fca..39e43340 100644 --- a/src/ui/window.c +++ b/src/ui/window.c @@ -91,7 +91,7 @@ static iBool handleRootCommands_(iWidget *root, const char *cmd) { return iFalse; } else if (equal_Command(cmd, "window.focus.gained")) { - setTextColor_LabelWidget(findWidget_App("winbar.app"), uiTextShortcut_ColorId); + setTextColor_LabelWidget(findWidget_App("winbar.app"), uiTextAppTitle_ColorId); setTextColor_LabelWidget(findWidget_App("winbar.title"), uiTextStrong_ColorId); return iFalse; } @@ -557,7 +557,8 @@ static void setupUserInterface_Window(iWindow *d) { addChild_Widget(d->root, iClob(div)); #if defined (LAGRANGE_CUSTOM_FRAME) - /* Window title bar. */ { + /* Window title bar. */ + if (prefs_App()->customFrame) { setPadding1_Widget(div, 1); iWidget *winBar = new_Widget(); setPadding_Widget(winBar, 0, gap_UI / 3, 0, 0); @@ -573,7 +574,7 @@ static void setupUserInterface_Window(iWindow *d) { addChildFlags_Widget(winBar, iClob(new_LabelWidget("Lagrange", NULL)), fixedHeight_WidgetFlag | frameless_WidgetFlag); - setTextColor_LabelWidget(appButton, uiTextShortcut_ColorId); + setTextColor_LabelWidget(appButton, uiTextAppTitle_ColorId); setId_Widget(as_Widget(appButton), "winbar.app"); iLabelWidget *appTitle; setFont_LabelWidget(appButton, uiContentBold_FontId); @@ -862,17 +863,21 @@ SDL_HitTestResult hitTest_Window(const iWindow *d, iInt2 pos) { iBool create_Window_(iWindow *d, iRect rect, uint32_t flags) { flags |= SDL_WINDOW_RESIZABLE | SDL_WINDOW_ALLOW_HIGHDPI | SDL_WINDOW_HIDDEN; #if defined (LAGRANGE_CUSTOM_FRAME) - /* We are drawing a custom frame so hide the default one. */ - flags |= SDL_WINDOW_BORDERLESS; + if (prefs_App()->customFrame) { + /* We are drawing a custom frame so hide the default one. */ + flags |= SDL_WINDOW_BORDERLESS; + } #endif if (SDL_CreateWindowAndRenderer( width_Rect(rect), height_Rect(rect), flags, &d->win, &d->render)) { return iFalse; } #if defined (LAGRANGE_CUSTOM_FRAME) - /* Register a handler for window hit testing (drag, resize). */ - SDL_SetWindowHitTest(d->win, hitTest_Window_, d); - SDL_SetWindowResizable(d->win, SDL_TRUE); + if (prefs_App()->customFrame) { + /* Register a handler for window hit testing (drag, resize). */ + SDL_SetWindowHitTest(d->win, hitTest_Window_, d); + SDL_SetWindowResizable(d->win, SDL_TRUE); + } #endif return iTrue; } @@ -979,15 +984,16 @@ void init_Window(iWindow *d, iRect rect) { updateRootSize_Window_(d, iFalse); d->appIcon = NULL; #if defined (LAGRANGE_CUSTOM_FRAME) - /* Load the app icon for drawing in the title bar. */ { + /* Load the app icon for drawing in the title bar. */ + if (prefs_App()->customFrame) { SDL_Surface *surf = loadAppIconSurface_(appIconSize_()); SDL_SetHint(SDL_HINT_RENDER_SCALE_QUALITY, "0"); d->appIcon = SDL_CreateTextureFromSurface(d->render, surf); free(surf->pixels); SDL_FreeSurface(surf); + /* We need to observe non-client-area events. */ + SDL_EventState(SDL_SYSWMEVENT, SDL_TRUE); } - /* We need to observe non-client-area events. */ - SDL_EventState(SDL_SYSWMEVENT, SDL_TRUE); #endif } @@ -1027,6 +1033,9 @@ static iBool isNormalPlacement_Window_(const iWindow *d) { static iBool unsnap_Window_(iWindow *d, const iInt2 *newPos) { #if defined (LAGRANGE_CUSTOM_FRAME) + if (!prefs_App()->customFrame) { + return iFalse; + } const int snap = snap_Window(d); if (snap == yMaximized_WindowSnap || snap == left_WindowSnap || snap == right_WindowSnap) { if (!newPos || (d->place.lastHit == SDL_HITTEST_RESIZE_LEFT || @@ -1088,7 +1097,8 @@ static iBool handleWindowEvent_Window_(iWindow *d, const SDL_WindowEvent *ev) { return iFalse; } #if defined (LAGRANGE_CUSTOM_FRAME) - /* Set the snap position depending on where the mouse cursor is. */ { + /* Set the snap position depending on where the mouse cursor is. */ + if (prefs_App()->customFrame) { SDL_Rect usable; iInt2 mouse = cursor_Win32(); /* SDL is unaware of the current cursor pos */ SDL_GetDisplayUsableBounds(SDL_GetWindowDisplayIndex(d->win), &usable); @@ -1281,17 +1291,17 @@ void draw_Window(iWindow *d) { if (d->isDrawFrozen) { return; } -//#if !defined (NDEBUG) -// printf("draw %d\n", d->frameTime); fflush(stdout); -//#endif - /* Clear the window. */ - const int winFlags = SDL_GetWindowFlags(d->win); - const iColor back = - get_Color(winFlags & SDL_WINDOW_INPUT_FOCUS && d->place.snap != maximized_WindowSnap - ? uiAnnotation_ColorId - : uiSeparator_ColorId); - SDL_SetRenderDrawColor(d->render, back.r, back.g, back.b, 255); - SDL_RenderClear(d->render); + const int winFlags = SDL_GetWindowFlags(d->win); + const iBool gotFocus = (winFlags & SDL_WINDOW_INPUT_FOCUS) != 0; + /* Clear the window. The clear color is visible as a border around the window + when the custom frame is being used. */ { + const iColor back = get_Color(gotFocus && d->place.snap != maximized_WindowSnap && + ~winFlags & SDL_WINDOW_FULLSCREEN_DESKTOP + ? uiAnnotation_ColorId + : uiSeparator_ColorId); + SDL_SetRenderDrawColor(d->render, back.r, back.g, back.b, 255); + SDL_RenderClear(d->render); + } /* Draw widgets. */ d->frameTime = SDL_GetTicks(); draw_Widget(d->root); @@ -1302,6 +1312,10 @@ void draw_Window(iWindow *d) { const int size = appIconSize_(); const iRect rect = bounds_Widget(appIcon); const iInt2 mid = mid_Rect(rect); + const iBool isLight = isLight_ColorTheme(colorTheme_App()); + iColor iconColor = get_Color(gotFocus || isLight ? white_ColorId : cyan_ColorId); + SDL_SetTextureColorMod(d->appIcon, iconColor.r, iconColor.g, iconColor.b); + SDL_SetTextureAlphaMod(d->appIcon, gotFocus || !isLight ? 255 : 92); SDL_RenderCopy( d->render, d->appIcon, @@ -1401,38 +1415,25 @@ iWindow *get_Window(void) { return theWindow_; } -#if !defined (LAGRANGE_CUSTOM_FRAME) void setSnap_Window(iWindow *d, int snapMode) { - if (snapMode == maximized_WindowSnap) { - SDL_MaximizeWindow(d->win); - } - else if (snapMode == fullscreen_WindowSnap) { - SDL_SetWindowFullscreen(d->win, SDL_WINDOW_FULLSCREEN_DESKTOP); - } - else { - if (snap_Window(d) == fullscreen_WindowSnap) { - SDL_SetWindowFullscreen(d->win, 0); + if (!prefs_App()->customFrame) { + if (snapMode == maximized_WindowSnap) { + SDL_MaximizeWindow(d->win); + } + else if (snapMode == fullscreen_WindowSnap) { + SDL_SetWindowFullscreen(d->win, SDL_WINDOW_FULLSCREEN_DESKTOP); } else { - SDL_RestoreWindow(d->win); + if (snap_Window(d) == fullscreen_WindowSnap) { + SDL_SetWindowFullscreen(d->win, 0); + } + else { + SDL_RestoreWindow(d->win); + } } + return; } -} - -int snap_Window(const iWindow *d) { - const int flags = SDL_GetWindowFlags(d->win); - if (flags & SDL_WINDOW_FULLSCREEN_DESKTOP) { - return fullscreen_WindowSnap; - } - else if (flags & SDL_WINDOW_MAXIMIZED) { - return maximized_WindowSnap; - } - return none_WindowSnap; -} -#endif - #if defined (LAGRANGE_CUSTOM_FRAME) -void setSnap_Window(iWindow *d, int snapMode) { if (d->place.snap == snapMode) { return; } @@ -1497,9 +1498,19 @@ void setSnap_Window(iWindow *d, int snapMode) { arrange_Widget(d->root); postRefresh_App(); } +#endif /* defined (LAGRANGE_CUSTOM_FRAME) */ } int snap_Window(const iWindow *d) { + if (!prefs_App()->customFrame) { + const int flags = SDL_GetWindowFlags(d->win); + if (flags & SDL_WINDOW_FULLSCREEN_DESKTOP) { + return fullscreen_WindowSnap; + } + else if (flags & SDL_WINDOW_MAXIMIZED) { + return maximized_WindowSnap; + } + return none_WindowSnap; + } return d->place.snap; } -#endif -- cgit v1.2.3