diff options
Diffstat (limited to 'src/ui/window.c')
-rw-r--r-- | src/ui/window.c | 221 |
1 files changed, 183 insertions, 38 deletions
diff --git a/src/ui/window.c b/src/ui/window.c index 6356b292..37586aab 100644 --- a/src/ui/window.c +++ b/src/ui/window.c | |||
@@ -93,15 +93,6 @@ 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.fullscreen.changed")) { | ||
97 | iWidget *winBar = findWidget_App("winbar"); | ||
98 | if (winBar) { | ||
99 | setFlags_Widget(winBar, hidden_WidgetFlag, arg_Command(cmd)); | ||
100 | arrange_Widget(get_Window()->root); | ||
101 | postRefresh_App(); | ||
102 | } | ||
103 | return iFalse; | ||
104 | } | ||
105 | else if (equal_Command(cmd, "window.minimize")) { | 96 | else if (equal_Command(cmd, "window.minimize")) { |
106 | SDL_MinimizeWindow(get_Window()->win); | 97 | SDL_MinimizeWindow(get_Window()->win); |
107 | return iTrue; | 98 | return iTrue; |
@@ -562,7 +553,7 @@ static void setupUserInterface_Window(iWindow *d) { | |||
562 | setFont_LabelWidget(appButton, uiContentBold_FontId); | 553 | setFont_LabelWidget(appButton, uiContentBold_FontId); |
563 | setId_Widget(addChildFlags_Widget(winBar, | 554 | setId_Widget(addChildFlags_Widget(winBar, |
564 | iClob(appTitle = new_LabelWidget("", NULL)), | 555 | iClob(appTitle = new_LabelWidget("", NULL)), |
565 | expand_WidgetFlag | alignLeft_WidgetFlag | | 556 | expand_WidgetFlag | /*alignLeft_WidgetFlag |*/ |
566 | fixedHeight_WidgetFlag | frameless_WidgetFlag | | 557 | fixedHeight_WidgetFlag | frameless_WidgetFlag | |
567 | commandOnClick_WidgetFlag), | 558 | commandOnClick_WidgetFlag), |
568 | "winbar.title"); | 559 | "winbar.title"); |
@@ -570,7 +561,7 @@ static void setupUserInterface_Window(iWindow *d) { | |||
570 | iLabelWidget *appMin, *appMax, *appClose; | 561 | iLabelWidget *appMin, *appMax, *appClose; |
571 | setId_Widget(addChildFlags_Widget( | 562 | setId_Widget(addChildFlags_Widget( |
572 | winBar, | 563 | winBar, |
573 | iClob(appMin = newLargeIcon_LabelWidget("\u2014", "window.minimize")), | 564 | iClob(appMin = newLargeIcon_LabelWidget("\u2013", "window.minimize")), |
574 | frameless_WidgetFlag), | 565 | frameless_WidgetFlag), |
575 | "winbar.min"); | 566 | "winbar.min"); |
576 | setSize_Widget(as_Widget(appMin), | 567 | setSize_Widget(as_Widget(appMin), |
@@ -582,6 +573,7 @@ static void setupUserInterface_Window(iWindow *d) { | |||
582 | addChildFlags_Widget(winBar, | 573 | addChildFlags_Widget(winBar, |
583 | iClob(appClose = newLargeIcon_LabelWidget("\u2a2f", "window.close")), | 574 | iClob(appClose = newLargeIcon_LabelWidget("\u2a2f", "window.close")), |
584 | frameless_WidgetFlag); | 575 | frameless_WidgetFlag); |
576 | setFont_LabelWidget(appClose, uiContent_FontId); | ||
585 | setSize_Widget(as_Widget(appMax), as_Widget(appMin)->rect.size); | 577 | setSize_Widget(as_Widget(appMax), as_Widget(appMin)->rect.size); |
586 | setSize_Widget(as_Widget(appClose), as_Widget(appMin)->rect.size); | 578 | setSize_Widget(as_Widget(appClose), as_Widget(appMin)->rect.size); |
587 | addChild_Widget(div, iClob(winBar)); | 579 | addChild_Widget(div, iClob(winBar)); |
@@ -744,8 +736,8 @@ static void updateRootSize_Window_(iWindow *d, iBool notifyAlways) { | |||
744 | const iInt2 oldSize = *size; | 736 | const iInt2 oldSize = *size; |
745 | SDL_GetRendererOutputSize(d->render, &size->x, &size->y); | 737 | SDL_GetRendererOutputSize(d->render, &size->x, &size->y); |
746 | if (notifyAlways || !isEqual_I2(oldSize, *size)) { | 738 | if (notifyAlways || !isEqual_I2(oldSize, *size)) { |
747 | const iBool isHoriz = (d->lastNotifiedSize.x != size->x); | 739 | const iBool isHoriz = (d->place.lastNotifiedSize.x != size->x); |
748 | const iBool isVert = (d->lastNotifiedSize.y != size->y); | 740 | const iBool isVert = (d->place.lastNotifiedSize.y != size->y); |
749 | arrange_Widget(d->root); | 741 | arrange_Widget(d->root); |
750 | postCommandf_App("window.resized width:%d height:%d horiz:%d vert:%d", | 742 | postCommandf_App("window.resized width:%d height:%d horiz:%d vert:%d", |
751 | size->x, | 743 | size->x, |
@@ -753,7 +745,7 @@ static void updateRootSize_Window_(iWindow *d, iBool notifyAlways) { | |||
753 | isHoriz, | 745 | isHoriz, |
754 | isVert); | 746 | isVert); |
755 | postRefresh_App(); | 747 | postRefresh_App(); |
756 | d->lastNotifiedSize = *size; | 748 | d->place.lastNotifiedSize = *size; |
757 | } | 749 | } |
758 | } | 750 | } |
759 | 751 | ||
@@ -793,6 +785,9 @@ static void drawBlank_Window_(iWindow *d) { | |||
793 | static SDL_HitTestResult hitTest_Window_(SDL_Window *win, const SDL_Point *pos, void *data) { | 785 | static SDL_HitTestResult hitTest_Window_(SDL_Window *win, const SDL_Point *pos, void *data) { |
794 | iWindow *d = data; | 786 | iWindow *d = data; |
795 | iAssert(d->win == win); | 787 | iAssert(d->win == win); |
788 | if (SDL_GetWindowFlags(d->win) & SDL_WINDOW_MOUSE_CAPTURE) { | ||
789 | return SDL_HITTEST_NORMAL; | ||
790 | } | ||
796 | int w, h; | 791 | int w, h; |
797 | SDL_GetWindowSize(win, &w, &h); | 792 | SDL_GetWindowSize(win, &w, &h); |
798 | /* TODO: Check if inside the caption label widget. */ | 793 | /* TODO: Check if inside the caption label widget. */ |
@@ -802,15 +797,16 @@ static SDL_HitTestResult hitTest_Window_(SDL_Window *win, const SDL_Point *pos, | |||
802 | const iBool isBottom = pos->y >= h - gap_UI; | 797 | const iBool isBottom = pos->y >= h - gap_UI; |
803 | const int captionHeight = lineHeight_Text(uiContent_FontId) + gap_UI * 2; | 798 | const int captionHeight = lineHeight_Text(uiContent_FontId) + gap_UI * 2; |
804 | const int rightEdge = left_Rect(bounds_Widget(findChild_Widget(d->root, "winbar.min"))); | 799 | const int rightEdge = left_Rect(bounds_Widget(findChild_Widget(d->root, "winbar.min"))); |
800 | d->place.lastHit = SDL_HITTEST_NORMAL; | ||
805 | if (isLeft) { | 801 | if (isLeft) { |
806 | return pos->y < captionHeight ? SDL_HITTEST_RESIZE_TOPLEFT | 802 | return pos->y < captionHeight ? SDL_HITTEST_RESIZE_TOPLEFT |
807 | : pos->y > h - captionHeight ? SDL_HITTEST_RESIZE_BOTTOMLEFT | 803 | : pos->y > h - captionHeight ? SDL_HITTEST_RESIZE_BOTTOMLEFT |
808 | : SDL_HITTEST_RESIZE_LEFT; | 804 | : (d->place.lastHit = SDL_HITTEST_RESIZE_LEFT); |
809 | } | 805 | } |
810 | if (isRight) { | 806 | if (isRight) { |
811 | return pos->y < captionHeight ? SDL_HITTEST_RESIZE_TOPRIGHT | 807 | return pos->y < captionHeight ? SDL_HITTEST_RESIZE_TOPRIGHT |
812 | : pos->y > h - captionHeight ? SDL_HITTEST_RESIZE_BOTTOMRIGHT | 808 | : pos->y > h - captionHeight ? SDL_HITTEST_RESIZE_BOTTOMRIGHT |
813 | : SDL_HITTEST_RESIZE_RIGHT; | 809 | : (d->place.lastHit = SDL_HITTEST_RESIZE_RIGHT); |
814 | } | 810 | } |
815 | if (isTop) { | 811 | if (isTop) { |
816 | return pos->x < captionHeight ? SDL_HITTEST_RESIZE_TOPLEFT | 812 | return pos->x < captionHeight ? SDL_HITTEST_RESIZE_TOPLEFT |
@@ -827,6 +823,10 @@ static SDL_HitTestResult hitTest_Window_(SDL_Window *win, const SDL_Point *pos, | |||
827 | } | 823 | } |
828 | return SDL_HITTEST_NORMAL; | 824 | return SDL_HITTEST_NORMAL; |
829 | } | 825 | } |
826 | |||
827 | SDL_HitTestResult hitTest_Window(const iWindow *d, iInt2 pos) { | ||
828 | return hitTest_Window_(d->win, &(SDL_Point){ pos.x, pos.y }, iConstCast(void *, d)); | ||
829 | } | ||
830 | #endif | 830 | #endif |
831 | 831 | ||
832 | iBool create_Window_(iWindow *d, iRect rect, uint32_t flags) { | 832 | iBool create_Window_(iWindow *d, iRect rect, uint32_t flags) { |
@@ -841,7 +841,7 @@ iBool create_Window_(iWindow *d, iRect rect, uint32_t flags) { | |||
841 | } | 841 | } |
842 | #if defined (LAGRANGE_CUSTOM_FRAME) | 842 | #if defined (LAGRANGE_CUSTOM_FRAME) |
843 | /* Register a handler for window hit testing (drag, resize). */ | 843 | /* Register a handler for window hit testing (drag, resize). */ |
844 | SDL_SetWindowHitTest(d->win, hitTest_Window_, d); | 844 | SDL_SetWindowHitTest(d->win, hitTest_Window_, d); |
845 | SDL_SetWindowResizable(d->win, SDL_TRUE); | 845 | SDL_SetWindowResizable(d->win, SDL_TRUE); |
846 | #endif | 846 | #endif |
847 | return iTrue; | 847 | return iTrue; |
@@ -850,12 +850,13 @@ iBool create_Window_(iWindow *d, iRect rect, uint32_t flags) { | |||
850 | void init_Window(iWindow *d, iRect rect) { | 850 | void init_Window(iWindow *d, iRect rect) { |
851 | theWindow_ = d; | 851 | theWindow_ = d; |
852 | iZap(d->cursors); | 852 | iZap(d->cursors); |
853 | d->initialPos = rect.pos; | 853 | d->place.initialPos = rect.pos; |
854 | d->lastRect = rect; | 854 | d->place.normalRect = rect; |
855 | d->lastNotifiedSize = zero_I2(); | 855 | d->place.lastNotifiedSize = zero_I2(); |
856 | d->pendingCursor = NULL; | 856 | d->pendingCursor = NULL; |
857 | d->isDrawFrozen = iTrue; | 857 | d->isDrawFrozen = iTrue; |
858 | d->isExposed = iFalse; | 858 | d->isExposed = iFalse; |
859 | d->isMinimized = iFalse; | ||
859 | d->isMouseInside = iTrue; | 860 | d->isMouseInside = iTrue; |
860 | d->focusGainedAt = 0; | 861 | d->focusGainedAt = 0; |
861 | uint32_t flags = 0; | 862 | uint32_t flags = 0; |
@@ -936,6 +937,9 @@ void init_Window(iWindow *d, iRect rect) { | |||
936 | setupUserInterface_Window(d); | 937 | setupUserInterface_Window(d); |
937 | postCommand_App("bindings.changed"); /* update from bindings */ | 938 | postCommand_App("bindings.changed"); /* update from bindings */ |
938 | updateRootSize_Window_(d, iFalse); | 939 | updateRootSize_Window_(d, iFalse); |
940 | #if defined (LAGRANGE_CUSTOM_FRAME) | ||
941 | SDL_EventState(SDL_SYSWMEVENT, SDL_TRUE); | ||
942 | #endif | ||
939 | } | 943 | } |
940 | 944 | ||
941 | void deinit_Window(iWindow *d) { | 945 | void deinit_Window(iWindow *d) { |
@@ -958,17 +962,8 @@ SDL_Renderer *renderer_Window(const iWindow *d) { | |||
958 | return d->render; | 962 | return d->render; |
959 | } | 963 | } |
960 | 964 | ||
961 | static iBool isMaximized_Window_(const iWindow *d) { | ||
962 | #if !defined (iPlatformApple) | ||
963 | return (SDL_GetWindowFlags(d->win) & (SDL_WINDOW_MINIMIZED | SDL_WINDOW_MAXIMIZED)) != 0; | ||
964 | #else | ||
965 | iUnused(d); | ||
966 | return iFalse; /* There is fullscreen mode but that is not handled at the moment. */ | ||
967 | #endif | ||
968 | } | ||
969 | |||
970 | iBool isFullscreen_Window(const iWindow *d) { | 965 | iBool isFullscreen_Window(const iWindow *d) { |
971 | return (SDL_GetWindowFlags(d->win) & SDL_WINDOW_FULLSCREEN_DESKTOP) != 0; | 966 | return snap_Window(d) == fullscreen_WindowSnap; |
972 | } | 967 | } |
973 | 968 | ||
974 | static void invalidate_Window_(iWindow *d) { | 969 | static void invalidate_Window_(iWindow *d) { |
@@ -976,6 +971,31 @@ static void invalidate_Window_(iWindow *d) { | |||
976 | postCommand_App("theme.changed"); /* forces UI invalidation */ | 971 | postCommand_App("theme.changed"); /* forces UI invalidation */ |
977 | } | 972 | } |
978 | 973 | ||
974 | static iBool isNormalPlacement_Window_(const iWindow *d) { | ||
975 | if (snap_Window(d) || d->isDrawFrozen) return iFalse; | ||
976 | return !(SDL_GetWindowFlags(d->win) & SDL_WINDOW_MINIMIZED); | ||
977 | } | ||
978 | |||
979 | static iBool unsnap_Window_(iWindow *d, const iInt2 *newPos) { | ||
980 | #if defined (LAGRANGE_CUSTOM_FRAME) | ||
981 | const int snap = snap_Window(d); | ||
982 | if (snap == yMaximized_WindowSnap && | ||
983 | (!newPos || (d->place.lastHit == SDL_HITTEST_RESIZE_LEFT || | ||
984 | d->place.lastHit == SDL_HITTEST_RESIZE_RIGHT))) { | ||
985 | return iFalse; | ||
986 | } | ||
987 | if (snap && snap != fullscreen_WindowSnap) { | ||
988 | if (snap_Window(d) == yMaximized_WindowSnap && newPos) { | ||
989 | d->place.normalRect.pos = *newPos; | ||
990 | } | ||
991 | printf("unsnap\n"); fflush(stdout); | ||
992 | setSnap_Window(d, none_WindowSnap); | ||
993 | return iTrue; | ||
994 | } | ||
995 | #endif | ||
996 | return iFalse; | ||
997 | } | ||
998 | |||
979 | static iBool handleWindowEvent_Window_(iWindow *d, const SDL_WindowEvent *ev) { | 999 | static iBool handleWindowEvent_Window_(iWindow *d, const SDL_WindowEvent *ev) { |
980 | switch (ev->event) { | 1000 | switch (ev->event) { |
981 | case SDL_WINDOWEVENT_EXPOSED: | 1001 | case SDL_WINDOWEVENT_EXPOSED: |
@@ -989,33 +1009,62 @@ static iBool handleWindowEvent_Window_(iWindow *d, const SDL_WindowEvent *ev) { | |||
989 | is missing contents until other events trigger a refresh. */ | 1009 | is missing contents until other events trigger a refresh. */ |
990 | postRefresh_App(); | 1010 | postRefresh_App(); |
991 | #if defined (LAGRANGE_ENABLE_WINDOWPOS_FIX) | 1011 | #if defined (LAGRANGE_ENABLE_WINDOWPOS_FIX) |
992 | if (d->initialPos.x >= 0) { | 1012 | if (d->place.initialPos.x >= 0) { |
993 | int bx, by; | 1013 | int bx, by; |
994 | SDL_GetWindowBordersSize(d->win, &by, &bx, NULL, NULL); | 1014 | SDL_GetWindowBordersSize(d->win, &by, &bx, NULL, NULL); |
995 | SDL_SetWindowPosition(d->win, d->initialPos.x + bx, d->initialPos.y + by); | 1015 | SDL_SetWindowPosition(d->win, d->place.initialPos.x + bx, d->place.initialPos.y + by); |
996 | d->initialPos = init1_I2(-1); | 1016 | d->place.initialPos = init1_I2(-1); |
997 | } | 1017 | } |
998 | #endif | 1018 | #endif |
999 | return iFalse; | 1019 | return iFalse; |
1000 | case SDL_WINDOWEVENT_MOVED: { | 1020 | case SDL_WINDOWEVENT_MOVED: { |
1001 | if (!isMaximized_Window_(d) && !isFullscreen_Window(d) && !d->isDrawFrozen) { | 1021 | if (d->isMinimized) { |
1002 | d->lastRect.pos = init_I2(ev->data1, ev->data2); | 1022 | return iFalse; |
1023 | } | ||
1024 | const iInt2 newPos = init_I2(ev->data1, ev->data2); | ||
1025 | if (isEqual_I2(newPos, init1_I2(-32000))) { /* magic! */ | ||
1026 | /* Maybe minimized? Seems like a Windows constant of some kind. */ | ||
1027 | d->isMinimized = iTrue; | ||
1028 | return iFalse; | ||
1029 | } | ||
1030 | //printf("MOVED: %d, %d\n", ev->data1, ev->data2); fflush(stdout); | ||
1031 | if (unsnap_Window_(d, &newPos)) { | ||
1032 | return iTrue; | ||
1033 | } | ||
1034 | if (isNormalPlacement_Window_(d)) { | ||
1035 | d->place.normalRect.pos = newPos; | ||
1036 | //printf("normal rect set (move)\n"); fflush(stdout); | ||
1003 | iInt2 border = zero_I2(); | 1037 | iInt2 border = zero_I2(); |
1004 | #if !defined (iPlatformApple) | 1038 | #if !defined (iPlatformApple) |
1005 | SDL_GetWindowBordersSize(d->win, &border.y, &border.x, NULL, NULL); | 1039 | SDL_GetWindowBordersSize(d->win, &border.y, &border.x, NULL, NULL); |
1006 | #endif | 1040 | #endif |
1007 | d->lastRect.pos = max_I2(zero_I2(), sub_I2(d->lastRect.pos, border)); | 1041 | d->place.normalRect.pos = max_I2(zero_I2(), sub_I2(d->place.normalRect.pos, border)); |
1008 | } | 1042 | } |
1009 | return iTrue; | 1043 | return iTrue; |
1010 | } | 1044 | } |
1011 | case SDL_WINDOWEVENT_RESIZED: | 1045 | case SDL_WINDOWEVENT_RESIZED: |
1012 | if (!isMaximized_Window_(d) && !isFullscreen_Window(d) && !d->isDrawFrozen) { | 1046 | if (d->isMinimized) { |
1013 | d->lastRect.size = init_I2(ev->data1, ev->data2); | 1047 | updateRootSize_Window_(d, iTrue); |
1048 | return iTrue; | ||
1049 | } | ||
1050 | if (unsnap_Window_(d, NULL)) { | ||
1051 | return iTrue; | ||
1052 | } | ||
1053 | if (isNormalPlacement_Window_(d)) { | ||
1054 | d->place.normalRect.size = init_I2(ev->data1, ev->data2); | ||
1055 | //printf("normal rect set (resize)\n"); fflush(stdout); | ||
1014 | } | 1056 | } |
1015 | updateRootSize_Window_(d, iTrue /* we were already redrawing during the resize */); | 1057 | updateRootSize_Window_(d, iTrue /* we were already redrawing during the resize */); |
1016 | return iTrue; | 1058 | return iTrue; |
1017 | case SDL_WINDOWEVENT_RESTORED: | 1059 | case SDL_WINDOWEVENT_RESTORED: |
1060 | //updateRootSize_Window_(d, iTrue); | ||
1018 | invalidate_Window_(d); | 1061 | invalidate_Window_(d); |
1062 | d->isMinimized = iFalse; | ||
1063 | //printf("restored %d\n", snap_Window(d)); fflush(stdout); | ||
1064 | return iTrue; | ||
1065 | case SDL_WINDOWEVENT_MINIMIZED: | ||
1066 | d->isMinimized = iTrue; | ||
1067 | //printf("minimized\n"); fflush(stdout); | ||
1019 | return iTrue; | 1068 | return iTrue; |
1020 | case SDL_WINDOWEVENT_LEAVE: | 1069 | case SDL_WINDOWEVENT_LEAVE: |
1021 | unhover_Widget(); | 1070 | unhover_Widget(); |
@@ -1051,6 +1100,16 @@ static void applyCursor_Window_(iWindow *d) { | |||
1051 | 1100 | ||
1052 | iBool processEvent_Window(iWindow *d, const SDL_Event *ev) { | 1101 | iBool processEvent_Window(iWindow *d, const SDL_Event *ev) { |
1053 | switch (ev->type) { | 1102 | switch (ev->type) { |
1103 | #if defined (LAGRANGE_CUSTOM_FRAME) | ||
1104 | case SDL_SYSWMEVENT: { | ||
1105 | /* We observe native Win32 messages for better user interaction with the | ||
1106 | window frame. Mouse clicks especially will not generate normal SDL | ||
1107 | events if they happen on the custom hit-tested regions. These events | ||
1108 | are processed only there; the UI widgets do not get involved. */ | ||
1109 | processNativeEvent_Win32(ev->syswm.msg, d); | ||
1110 | break; | ||
1111 | } | ||
1112 | #endif | ||
1054 | case SDL_WINDOWEVENT: { | 1113 | case SDL_WINDOWEVENT: { |
1055 | return handleWindowEvent_Window_(d, &ev->window); | 1114 | return handleWindowEvent_Window_(d, &ev->window); |
1056 | } | 1115 | } |
@@ -1232,3 +1291,89 @@ uint32_t frameTime_Window(const iWindow *d) { | |||
1232 | iWindow *get_Window(void) { | 1291 | iWindow *get_Window(void) { |
1233 | return theWindow_; | 1292 | return theWindow_; |
1234 | } | 1293 | } |
1294 | |||
1295 | #if !defined (LAGRANGE_CUSTOM_FRAME) | ||
1296 | void setSnap_Window(iWindow *d, int snapMode) { | ||
1297 | if (snapMode == maximized_WindowSnap) { | ||
1298 | SDL_MaximizeWindow(d->win); | ||
1299 | } | ||
1300 | else if (snapMode == fullscreen_WindowSnap) { | ||
1301 | SDL_SetWindowFullscreen(d->win, SDL_WINDOW_FULLSCREEN_DESKTOP); | ||
1302 | } | ||
1303 | else { | ||
1304 | SDL_RestoreWindow(d->win); | ||
1305 | } | ||
1306 | } | ||
1307 | |||
1308 | int snap_Window(const iWindow *d) { | ||
1309 | const int flags = SDL_GetWindowFlags(d->win); | ||
1310 | if (flags & SDL_WINDOW_FULLSCREEN_DESKTOP) { | ||
1311 | return fullscreen_WindowSnap; | ||
1312 | } | ||
1313 | else if (flags & SDL_WINDOW_MAXIMIZED) { | ||
1314 | return maximized_WindowSnap; | ||
1315 | } | ||
1316 | return none_WindowSnap; | ||
1317 | } | ||
1318 | #endif | ||
1319 | |||
1320 | #if defined (LAGRANGE_CUSTOM_FRAME) | ||
1321 | void setSnap_Window(iWindow *d, int snapMode) { | ||
1322 | if (d->place.snap == snapMode) { | ||
1323 | return; | ||
1324 | } | ||
1325 | iRect newRect = zero_Rect(); | ||
1326 | SDL_Rect usable; | ||
1327 | SDL_GetDisplayUsableBounds(SDL_GetWindowDisplayIndex(d->win), &usable); | ||
1328 | if (d->place.snap == fullscreen_WindowSnap) { | ||
1329 | SDL_SetWindowFullscreen(d->win, 0); | ||
1330 | } | ||
1331 | d->place.snap = snapMode; | ||
1332 | switch (snapMode & mask_WindowSnap) { | ||
1333 | case none_WindowSnap: | ||
1334 | newRect = d->place.normalRect; | ||
1335 | break; | ||
1336 | case left_WindowSnap: | ||
1337 | newRect = init_Rect(usable.x, usable.y, usable.w / 2, usable.h); | ||
1338 | break; | ||
1339 | case right_WindowSnap: | ||
1340 | newRect = init_Rect(usable.x, usable.y + usable.w / 2, usable.w / 2, usable.h); | ||
1341 | break; | ||
1342 | case maximized_WindowSnap: | ||
1343 | newRect = init_Rect(usable.x, usable.y, usable.w, usable.h); | ||
1344 | break; | ||
1345 | case yMaximized_WindowSnap: | ||
1346 | newRect.pos.y = 0; | ||
1347 | newRect.size.y = usable.h; | ||
1348 | SDL_GetWindowPosition(d->win, &newRect.pos.x, NULL); | ||
1349 | SDL_GetWindowSize(d->win, &newRect.size.x, NULL); | ||
1350 | break; | ||
1351 | case fullscreen_WindowSnap: | ||
1352 | SDL_SetWindowFullscreen(d->win, SDL_WINDOW_FULLSCREEN_DESKTOP); | ||
1353 | break; | ||
1354 | } | ||
1355 | if (snapMode & (topBit_WindowSnap | bottomBit_WindowSnap)) { | ||
1356 | newRect.size.y /= 2; | ||
1357 | } | ||
1358 | if (snapMode & bottomBit_WindowSnap) { | ||
1359 | newRect.pos.y += newRect.size.y; | ||
1360 | } | ||
1361 | /* Show and hide the title bar. */ | ||
1362 | iWidget *winBar = findWidget_App("winbar"); | ||
1363 | const iBool wasVisible = isVisible_Widget(winBar); | ||
1364 | setFlags_Widget(winBar, hidden_WidgetFlag, snapMode == fullscreen_WindowSnap); | ||
1365 | if (newRect.size.x) { | ||
1366 | SDL_SetWindowPosition(d->win, newRect.pos.x, newRect.pos.y); | ||
1367 | SDL_SetWindowSize(d->win, newRect.size.x, newRect.size.y); | ||
1368 | postCommand_App("window.resized"); | ||
1369 | } | ||
1370 | if (wasVisible != isVisible_Widget(winBar)) { | ||
1371 | arrange_Widget(d->root); | ||
1372 | postRefresh_App(); | ||
1373 | } | ||
1374 | } | ||
1375 | |||
1376 | int snap_Window(const iWindow *d) { | ||
1377 | return d->place.snap; | ||
1378 | } | ||
1379 | #endif | ||