diff options
author | Jaakko Keränen <jaakko.keranen@iki.fi> | 2021-09-20 11:37:23 +0300 |
---|---|---|
committer | Jaakko Keränen <jaakko.keranen@iki.fi> | 2021-09-20 11:37:23 +0300 |
commit | 2d81addf78d6a8b0fb2f2959b04a385c4adffdf2 (patch) | |
tree | 5e0f45b9c945499bc6a6669563de13c5203981a6 /src/ui/util.c | |
parent | 201021092d204680b353c82ce9e9beb76f3044e8 (diff) |
Experimenting with independent popup windows
Toe dipping into multiple window support by allowing popup menu widgets to be displayed in independent windows.
This is not a 100% replacement for native menus, but it gets pretty close.
Diffstat (limited to 'src/ui/util.c')
-rw-r--r-- | src/ui/util.c | 42 |
1 files changed, 40 insertions, 2 deletions
diff --git a/src/ui/util.c b/src/ui/util.c index 721aed2d..38977b96 100644 --- a/src/ui/util.c +++ b/src/ui/util.c | |||
@@ -613,6 +613,8 @@ iBool isAction_Widget(const iWidget *d) { | |||
613 | /*-----------------------------------------------------------------------------------------------*/ | 613 | /*-----------------------------------------------------------------------------------------------*/ |
614 | 614 | ||
615 | static iBool isCommandIgnoredByMenus_(const char *cmd) { | 615 | static iBool isCommandIgnoredByMenus_(const char *cmd) { |
616 | if (equal_Command(cmd, "window.focus.lost") || | ||
617 | equal_Command(cmd, "window.focus.gained")) return iTrue; | ||
616 | /* TODO: Perhaps a common way of indicating which commands are notifications and should not | 618 | /* TODO: Perhaps a common way of indicating which commands are notifications and should not |
617 | be reacted to by menus? */ | 619 | be reacted to by menus? */ |
618 | return equal_Command(cmd, "media.updated") || | 620 | return equal_Command(cmd, "media.updated") || |
@@ -810,6 +812,10 @@ static void updateMenuItemFonts_Widget_(iWidget *d) { | |||
810 | } | 812 | } |
811 | } | 813 | } |
812 | 814 | ||
815 | iLocalDef iBool isUsingMenuPopupWindows_(void) { | ||
816 | return deviceType_App() == desktop_AppDeviceType; | ||
817 | } | ||
818 | |||
813 | void openMenuFlags_Widget(iWidget *d, iInt2 windowCoord, iBool postCommands) { | 819 | void openMenuFlags_Widget(iWidget *d, iInt2 windowCoord, iBool postCommands) { |
814 | const iRect rootRect = rect_Root(d->root); | 820 | const iRect rootRect = rect_Root(d->root); |
815 | const iInt2 rootSize = rootRect.size; | 821 | const iInt2 rootSize = rootRect.size; |
@@ -822,6 +828,26 @@ void openMenuFlags_Widget(iWidget *d, iInt2 windowCoord, iBool postCommands) { | |||
822 | processEvents_App(postedEventsOnly_AppEventMode); | 828 | processEvents_App(postedEventsOnly_AppEventMode); |
823 | setFlags_Widget(d, hidden_WidgetFlag, iFalse); | 829 | setFlags_Widget(d, hidden_WidgetFlag, iFalse); |
824 | setFlags_Widget(d, commandOnMouseMiss_WidgetFlag, iTrue); | 830 | setFlags_Widget(d, commandOnMouseMiss_WidgetFlag, iTrue); |
831 | if (isUsingMenuPopupWindows_()) { | ||
832 | if (postCommands) { | ||
833 | postCommand_Widget(d, "menu.opened"); | ||
834 | } | ||
835 | updateMenuItemFonts_Widget_(d); | ||
836 | iRoot *oldRoot = current_Root(); | ||
837 | setFlags_Widget(d, keepOnTop_WidgetFlag, iFalse); | ||
838 | setUserData_Object(d, parent_Widget(d)); | ||
839 | removeChild_Widget(parent_Widget(d), d); /* we'll borrow the widget for a while */ | ||
840 | iInt2 mousePos; | ||
841 | SDL_GetGlobalMouseState(&mousePos.x, &mousePos.y); | ||
842 | iWindow *win = newPopup_Window(sub_I2(mousePos, divi_I2(gap2_UI, 2)), d); | ||
843 | SDL_SetWindowTitle(win->win, "Menu"); | ||
844 | addPopup_App(win); /* window takes the widget */ | ||
845 | SDL_ShowWindow(win->win); | ||
846 | draw_Window(win); | ||
847 | setCurrent_Window(mainWindow_App()); | ||
848 | setCurrent_Root(oldRoot); | ||
849 | return; | ||
850 | } | ||
825 | raise_Widget(d); | 851 | raise_Widget(d); |
826 | setFlags_Widget(findChild_Widget(d, "menu.cancel"), disabled_WidgetFlag, iFalse); | 852 | setFlags_Widget(findChild_Widget(d, "menu.cancel"), disabled_WidgetFlag, iFalse); |
827 | if (isPortraitPhone) { | 853 | if (isPortraitPhone) { |
@@ -836,7 +862,7 @@ void openMenuFlags_Widget(iWidget *d, iInt2 windowCoord, iBool postCommands) { | |||
836 | arrange_Widget(d); | 862 | arrange_Widget(d); |
837 | if (isPortraitPhone) { | 863 | if (isPortraitPhone) { |
838 | if (isSlidePanel) { | 864 | if (isSlidePanel) { |
839 | d->rect.pos = zero_I2(); //neg_I2(bounds_Widget(parent_Widget(d)).pos); | 865 | d->rect.pos = zero_I2(); |
840 | } | 866 | } |
841 | else { | 867 | else { |
842 | d->rect.pos = init_I2(0, rootSize.y); | 868 | d->rect.pos = init_I2(0, rootSize.y); |
@@ -856,7 +882,7 @@ void openMenuFlags_Widget(iWidget *d, iInt2 windowCoord, iBool postCommands) { | |||
856 | float l, t, r, b; | 882 | float l, t, r, b; |
857 | safeAreaInsets_iOS(&l, &t, &r, &b); | 883 | safeAreaInsets_iOS(&l, &t, &r, &b); |
858 | topExcess += t; | 884 | topExcess += t; |
859 | bottomExcess += iMax(b, get_Window()->keyboardHeight); | 885 | bottomExcess += iMax(b, get_MainWindow()->keyboardHeight); |
860 | leftExcess += l; | 886 | leftExcess += l; |
861 | rightExcess += r; | 887 | rightExcess += r; |
862 | } | 888 | } |
@@ -884,6 +910,18 @@ void closeMenu_Widget(iWidget *d) { | |||
884 | if (d == NULL || flags_Widget(d) & hidden_WidgetFlag) { | 910 | if (d == NULL || flags_Widget(d) & hidden_WidgetFlag) { |
885 | return; /* Already closed. */ | 911 | return; /* Already closed. */ |
886 | } | 912 | } |
913 | if (isUsingMenuPopupWindows_()) { | ||
914 | iWindow *win = window_Widget(d); | ||
915 | iAssert(type_Window(win) == popup_WindowType); | ||
916 | iWidget *originalParent = userData_Object(d); | ||
917 | setUserData_Object(d, NULL); | ||
918 | win->roots[0]->widget = NULL; | ||
919 | setRoot_Widget(d, originalParent->root); | ||
920 | addChild_Widget(originalParent, d); | ||
921 | setFlags_Widget(d, keepOnTop_WidgetFlag, iTrue); | ||
922 | SDL_HideWindow(win->win); | ||
923 | collect_Garbage(win, (iDeleteFunc) delete_Window); /* get rid of it after event processing */ | ||
924 | } | ||
887 | setFlags_Widget(d, hidden_WidgetFlag, iTrue); | 925 | setFlags_Widget(d, hidden_WidgetFlag, iTrue); |
888 | setFlags_Widget(findChild_Widget(d, "menu.cancel"), disabled_WidgetFlag, iTrue); | 926 | setFlags_Widget(findChild_Widget(d, "menu.cancel"), disabled_WidgetFlag, iTrue); |
889 | postRefresh_App(); | 927 | postRefresh_App(); |