diff options
author | Jaakko Keränen <jaakko.keranen@iki.fi> | 2021-02-13 13:35:39 +0200 |
---|---|---|
committer | Jaakko Keränen <jaakko.keranen@iki.fi> | 2021-02-13 13:35:39 +0200 |
commit | 95df7abfb8ff46fba1bda1e696184682a5766fda (patch) | |
tree | 2f975446d82b84ad281e6ea6b4462d8a19d6e572 /src | |
parent | 9eba54d16f19fc976b64a678c151a6f03883658c (diff) |
Windows: Further custom frame improvements
Saving the window rectangle and snap mode. Frame title alignment.
Diffstat (limited to 'src')
-rw-r--r-- | src/app.c | 21 | ||||
-rw-r--r-- | src/ui/text.c | 1 | ||||
-rw-r--r-- | src/ui/window.c | 37 | ||||
-rw-r--r-- | src/ui/window.h | 1 | ||||
-rw-r--r-- | src/win32.c | 1 |
5 files changed, 39 insertions, 22 deletions
@@ -160,7 +160,6 @@ static iString *serializePrefs_App_(const iApp *d) { | |||
160 | const iSidebarWidget *sidebar2 = findWidget_App("sidebar2"); | 160 | const iSidebarWidget *sidebar2 = findWidget_App("sidebar2"); |
161 | appendFormat_String(str, "window.retain arg:%d\n", d->prefs.retainWindowSize); | 161 | appendFormat_String(str, "window.retain arg:%d\n", d->prefs.retainWindowSize); |
162 | if (d->prefs.retainWindowSize) { | 162 | if (d->prefs.retainWindowSize) { |
163 | const iBool isMaximized = snap_Window(d->window) == maximized_WindowSnap; | ||
164 | int w, h, x, y; | 163 | int w, h, x, y; |
165 | x = d->window->place.normalRect.pos.x; | 164 | x = d->window->place.normalRect.pos.x; |
166 | y = d->window->place.normalRect.pos.y; | 165 | y = d->window->place.normalRect.pos.y; |
@@ -171,12 +170,22 @@ static iString *serializePrefs_App_(const iApp *d) { | |||
171 | appendFormat_String(str, "sidebar2.width arg:%d\n", width_SidebarWidget(sidebar2)); | 170 | appendFormat_String(str, "sidebar2.width arg:%d\n", width_SidebarWidget(sidebar2)); |
172 | /* On macOS, maximization should be applied at creation time or the window will take | 171 | /* On macOS, maximization should be applied at creation time or the window will take |
173 | a moment to animate to its maximized size. */ | 172 | a moment to animate to its maximized size. */ |
174 | #if !defined (iPlatformApple) | 173 | #if defined (LAGRANGE_CUSTOM_FRAME) |
175 | if (isMaximized) { | 174 | if (snap_Window(d->window)) { |
175 | if (~SDL_GetWindowFlags(d->window->win) & SDL_WINDOW_MINIMIZED) { | ||
176 | /* Save the actual visible window position, too, because snapped windows may | ||
177 | still be resized/moved without affecting normalRect. */ | ||
178 | SDL_GetWindowPosition(d->window->win, &x, &y); | ||
179 | SDL_GetWindowSize(d->window->win, &w, &h); | ||
180 | appendFormat_String( | ||
181 | str, "~window.setrect snap:%d width:%d height:%d coord:%d %d\n", | ||
182 | snap_Window(d->window), w, h, x, y); | ||
183 | } | ||
184 | } | ||
185 | #elif !defined (iPlatformApple) | ||
186 | if (snap_Window(d->window) == maximized_WindowSnap) { | ||
176 | appendFormat_String(str, "~window.maximize\n"); | 187 | appendFormat_String(str, "~window.maximize\n"); |
177 | } | 188 | } |
178 | #else | ||
179 | iUnused(isMaximized); | ||
180 | #endif | 189 | #endif |
181 | } | 190 | } |
182 | /* Sidebars. */ { | 191 | /* Sidebars. */ { |
@@ -274,7 +283,7 @@ static void loadPrefs_App_(iApp *d) { | |||
274 | if (equal_Command(cmd, "uiscale")) { | 283 | if (equal_Command(cmd, "uiscale")) { |
275 | setUiScale_Window(get_Window(), argf_Command(cmd)); | 284 | setUiScale_Window(get_Window(), argf_Command(cmd)); |
276 | } | 285 | } |
277 | else if (equal_Command(cmd, "window.setrect")) { | 286 | else if (equal_Command(cmd, "window.setrect") && !argLabel_Command(cmd, "snap")) { |
278 | const iInt2 pos = coord_Command(cmd); | 287 | const iInt2 pos = coord_Command(cmd); |
279 | d->initialWindowRect = init_Rect( | 288 | d->initialWindowRect = init_Rect( |
280 | pos.x, pos.y, argLabel_Command(cmd, "width"), argLabel_Command(cmd, "height")); | 289 | pos.x, pos.y, argLabel_Command(cmd, "width"), argLabel_Command(cmd, "height")); |
diff --git a/src/ui/text.c b/src/ui/text.c index 218e7565..71a26250 100644 --- a/src/ui/text.c +++ b/src/ui/text.c | |||
@@ -1110,6 +1110,7 @@ void drawCentered_Text(int fontId, iRect rect, iBool alignVisual, int color, con | |||
1110 | iRect textBounds = alignVisual ? visualBounds_Text(fontId, text) | 1110 | iRect textBounds = alignVisual ? visualBounds_Text(fontId, text) |
1111 | : (iRect){ zero_I2(), advanceRange_Text(fontId, text) }; | 1111 | : (iRect){ zero_I2(), advanceRange_Text(fontId, text) }; |
1112 | textBounds.pos = sub_I2(mid_Rect(rect), mid_Rect(textBounds)); | 1112 | textBounds.pos = sub_I2(mid_Rect(rect), mid_Rect(textBounds)); |
1113 | textBounds.pos.x = iMax(textBounds.pos.x, left_Rect(rect)); /* keep left edge visible */ | ||
1113 | draw_Text_(fontId, textBounds.pos, color, text); | 1114 | draw_Text_(fontId, textBounds.pos, color, text); |
1114 | deinit_Block(&chars); | 1115 | deinit_Block(&chars); |
1115 | } | 1116 | } |
diff --git a/src/ui/window.c b/src/ui/window.c index 65386e14..a59aa135 100644 --- a/src/ui/window.c +++ b/src/ui/window.c | |||
@@ -93,6 +93,19 @@ static iBool handleRootCommands_(iWidget *root, const char *cmd) { | |||
93 | setTextColor_LabelWidget(findWidget_App("winbar.title"), uiTextStrong_ColorId); | 93 | setTextColor_LabelWidget(findWidget_App("winbar.title"), uiTextStrong_ColorId); |
94 | return iFalse; | 94 | return iFalse; |
95 | } | 95 | } |
96 | else if (equal_Command(cmd, "window.setrect")) { | ||
97 | const int snap = argLabel_Command(cmd, "snap"); | ||
98 | if (snap) { | ||
99 | iWindow *window = get_Window(); | ||
100 | iInt2 coord = coord_Command(cmd); | ||
101 | iInt2 size = init_I2(argLabel_Command(cmd, "width"), | ||
102 | argLabel_Command(cmd, "height")); | ||
103 | SDL_SetWindowPosition(window->win, coord.x, coord.y); | ||
104 | SDL_SetWindowSize(window->win, size.x, size.y); | ||
105 | window->place.snap = snap; | ||
106 | return iTrue; | ||
107 | } | ||
108 | } | ||
96 | else if (equal_Command(cmd, "window.restore")) { | 109 | else if (equal_Command(cmd, "window.restore")) { |
97 | setSnap_Window(get_Window(), none_WindowSnap); | 110 | setSnap_Window(get_Window(), none_WindowSnap); |
98 | return iTrue; | 111 | return iTrue; |
@@ -542,6 +555,7 @@ static void setupUserInterface_Window(iWindow *d) { | |||
542 | const int border = gap_UI / 4; | 555 | const int border = gap_UI / 4; |
543 | setPadding1_Widget(div, border); /* draggable edges */ | 556 | setPadding1_Widget(div, border); /* draggable edges */ |
544 | iWidget *winBar = new_Widget(); | 557 | iWidget *winBar = new_Widget(); |
558 | setPadding_Widget(winBar, 0, gap_UI / 3, 0, 0); | ||
545 | setId_Widget(winBar, "winbar"); | 559 | setId_Widget(winBar, "winbar"); |
546 | setFlags_Widget(winBar, | 560 | setFlags_Widget(winBar, |
547 | arrangeHeight_WidgetFlag | resizeChildren_WidgetFlag | | 561 | arrangeHeight_WidgetFlag | resizeChildren_WidgetFlag | |
@@ -792,13 +806,14 @@ static SDL_HitTestResult hitTest_Window_(SDL_Window *win, const SDL_Point *pos, | |||
792 | if (SDL_GetWindowFlags(d->win) & (SDL_WINDOW_MOUSE_CAPTURE | SDL_WINDOW_FULLSCREEN_DESKTOP)) { | 806 | if (SDL_GetWindowFlags(d->win) & (SDL_WINDOW_MOUSE_CAPTURE | SDL_WINDOW_FULLSCREEN_DESKTOP)) { |
793 | return SDL_HITTEST_NORMAL; | 807 | return SDL_HITTEST_NORMAL; |
794 | } | 808 | } |
809 | const int snap = snap_Window(d); | ||
795 | int w, h; | 810 | int w, h; |
796 | SDL_GetWindowSize(win, &w, &h); | 811 | SDL_GetWindowSize(win, &w, &h); |
797 | /* TODO: Check if inside the caption label widget. */ | 812 | /* TODO: Check if inside the caption label widget. */ |
798 | const iBool isLeft = pos->x < gap_UI; | 813 | const iBool isLeft = pos->x < gap_UI; |
799 | const iBool isRight = pos->x >= w - gap_UI; | 814 | const iBool isRight = pos->x >= w - gap_UI; |
800 | const iBool isTop = pos->y < gap_UI; | 815 | const iBool isTop = pos->y < gap_UI && snap != yMaximized_WindowSnap; |
801 | const iBool isBottom = pos->y >= h - gap_UI; | 816 | const iBool isBottom = pos->y >= h - gap_UI && snap != yMaximized_WindowSnap; |
802 | const int captionHeight = lineHeight_Text(uiContent_FontId) + gap_UI * 2; | 817 | const int captionHeight = lineHeight_Text(uiContent_FontId) + gap_UI * 2; |
803 | const int rightEdge = left_Rect(bounds_Widget(findChild_Widget(d->root, "winbar.min"))); | 818 | const int rightEdge = left_Rect(bounds_Widget(findChild_Widget(d->root, "winbar.min"))); |
804 | d->place.lastHit = SDL_HITTEST_NORMAL; | 819 | d->place.lastHit = SDL_HITTEST_NORMAL; |
@@ -862,6 +877,7 @@ void init_Window(iWindow *d, iRect rect) { | |||
862 | d->isExposed = iFalse; | 877 | d->isExposed = iFalse; |
863 | d->isMinimized = iFalse; | 878 | d->isMinimized = iFalse; |
864 | d->isMouseInside = iTrue; | 879 | d->isMouseInside = iTrue; |
880 | d->ignoreClick = iFalse; | ||
865 | d->focusGainedAt = 0; | 881 | d->focusGainedAt = 0; |
866 | uint32_t flags = 0; | 882 | uint32_t flags = 0; |
867 | #if defined (iPlatformAppleDesktop) | 883 | #if defined (iPlatformAppleDesktop) |
@@ -1180,21 +1196,10 @@ iBool processEvent_Window(iWindow *d, const SDL_Event *ev) { | |||
1180 | As a workaround, ignore these events. */ | 1196 | As a workaround, ignore these events. */ |
1181 | return iTrue; /* won't go to bindings, either */ | 1197 | return iTrue; /* won't go to bindings, either */ |
1182 | } | 1198 | } |
1183 | #if 0 //defined (LAGRANGE_CUSTOM_FRAME) | 1199 | if (event.type == SDL_MOUSEBUTTONDOWN && d->ignoreClick) { |
1184 | if (event.type == SDL_KEYDOWN) { | 1200 | d->ignoreClick = iFalse; |
1185 | if (keyMods_Sym(event.key.keysym.mod) == KMOD_PRIMARY) { | 1201 | return iTrue; |
1186 | printf("got! %x\n", event.key.keysym.sym); fflush(stdout); | ||
1187 | /* Emulate window snapping keys. */ | ||
1188 | switch (event.key.keysym.sym) { | ||
1189 | default: | ||
1190 | break; | ||
1191 | case SDLK_LEFT: | ||
1192 | setSnap_Window(d, left_WindowSnap); | ||
1193 | return iTrue; | ||
1194 | } | ||
1195 | } | ||
1196 | } | 1202 | } |
1197 | #endif | ||
1198 | /* Map mouse pointer coordinate to our coordinate system. */ | 1203 | /* Map mouse pointer coordinate to our coordinate system. */ |
1199 | if (event.type == SDL_MOUSEMOTION) { | 1204 | if (event.type == SDL_MOUSEMOTION) { |
1200 | setCursor_Window(d, SDL_SYSTEM_CURSOR_ARROW); /* default cursor */ | 1205 | setCursor_Window(d, SDL_SYSTEM_CURSOR_ARROW); /* default cursor */ |
diff --git a/src/ui/window.h b/src/ui/window.h index 6063df88..a914cd43 100644 --- a/src/ui/window.h +++ b/src/ui/window.h | |||
@@ -63,6 +63,7 @@ struct Impl_Window { | |||
63 | iBool isExposed; | 63 | iBool isExposed; |
64 | iBool isMinimized; | 64 | iBool isMinimized; |
65 | iBool isMouseInside; | 65 | iBool isMouseInside; |
66 | iBool ignoreClick; | ||
66 | uint32_t focusGainedAt; | 67 | uint32_t focusGainedAt; |
67 | SDL_Renderer *render; | 68 | SDL_Renderer *render; |
68 | iWidget * root; | 69 | iWidget * root; |
diff --git a/src/win32.c b/src/win32.c index 8f7bdc02..04080804 100644 --- a/src/win32.c +++ b/src/win32.c | |||
@@ -153,6 +153,7 @@ void processNativeEvent_Win32(const struct SDL_SysWMmsg *msg, iWindow *window) { | |||
153 | break; | 153 | break; |
154 | case SDL_HITTEST_RESIZE_TOP: | 154 | case SDL_HITTEST_RESIZE_TOP: |
155 | case SDL_HITTEST_RESIZE_BOTTOM: { | 155 | case SDL_HITTEST_RESIZE_BOTTOM: { |
156 | window->ignoreClick = iTrue; /* avoid hitting something inside the window */ | ||
156 | setSnap_Window(window, yMaximized_WindowSnap); | 157 | setSnap_Window(window, yMaximized_WindowSnap); |
157 | break; | 158 | break; |
158 | } | 159 | } |