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/widget.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/widget.c')
-rw-r--r-- | src/ui/widget.c | 38 |
1 files changed, 29 insertions, 9 deletions
diff --git a/src/ui/widget.c b/src/ui/widget.c index 23c19315..7b33a752 100644 --- a/src/ui/widget.c +++ b/src/ui/widget.c | |||
@@ -271,6 +271,10 @@ iWidget *root_Widget(const iWidget *d) { | |||
271 | return d ? d->root->widget : NULL; | 271 | return d ? d->root->widget : NULL; |
272 | } | 272 | } |
273 | 273 | ||
274 | iWindow *window_Widget(const iAnyObject *d) { | ||
275 | return constAs_Widget(d)->root->window; | ||
276 | } | ||
277 | |||
274 | void showCollapsed_Widget(iWidget *d, iBool show) { | 278 | void showCollapsed_Widget(iWidget *d, iBool show) { |
275 | const iBool isVisible = !(d->flags & hidden_WidgetFlag); | 279 | const iBool isVisible = !(d->flags & hidden_WidgetFlag); |
276 | if ((isVisible && !show) || (!isVisible && show)) { | 280 | if ((isVisible && !show) || (!isVisible && show)) { |
@@ -979,11 +983,10 @@ void unhover_Widget(void) { | |||
979 | } | 983 | } |
980 | 984 | ||
981 | iBool dispatchEvent_Widget(iWidget *d, const SDL_Event *ev) { | 985 | iBool dispatchEvent_Widget(iWidget *d, const SDL_Event *ev) { |
982 | //iAssert(d->root == get_Root()); | ||
983 | if (!d->parent) { | 986 | if (!d->parent) { |
984 | if (get_Window()->focus && get_Window()->focus->root == d->root && isKeyboardEvent_(ev)) { | 987 | if (window_Widget(d)->focus && window_Widget(d)->focus->root == d->root && isKeyboardEvent_(ev)) { |
985 | /* Root dispatches keyboard events directly to the focused widget. */ | 988 | /* Root dispatches keyboard events directly to the focused widget. */ |
986 | if (dispatchEvent_Widget(get_Window()->focus, ev)) { | 989 | if (dispatchEvent_Widget(window_Widget(d)->focus, ev)) { |
987 | return iTrue; | 990 | return iTrue; |
988 | } | 991 | } |
989 | } | 992 | } |
@@ -1012,7 +1015,8 @@ iBool dispatchEvent_Widget(iWidget *d, const SDL_Event *ev) { | |||
1012 | } | 1015 | } |
1013 | } | 1016 | } |
1014 | else if (ev->type == SDL_MOUSEMOTION && | 1017 | else if (ev->type == SDL_MOUSEMOTION && |
1015 | (!get_Window()->hover || hasParent_Widget(d, get_Window()->hover)) && | 1018 | ev->motion.windowID == SDL_GetWindowID(window_Widget(d)->win) && |
1019 | (!window_Widget(d)->hover || hasParent_Widget(d, window_Widget(d)->hover)) && | ||
1016 | flags_Widget(d) & hover_WidgetFlag && ~flags_Widget(d) & hidden_WidgetFlag && | 1020 | flags_Widget(d) & hover_WidgetFlag && ~flags_Widget(d) & hidden_WidgetFlag && |
1017 | ~flags_Widget(d) & disabled_WidgetFlag) { | 1021 | ~flags_Widget(d) & disabled_WidgetFlag) { |
1018 | if (contains_Widget(d, init_I2(ev->motion.x, ev->motion.y))) { | 1022 | if (contains_Widget(d, init_I2(ev->motion.x, ev->motion.y))) { |
@@ -1031,11 +1035,11 @@ iBool dispatchEvent_Widget(iWidget *d, const SDL_Event *ev) { | |||
1031 | iReverseForEach(ObjectList, i, d->children) { | 1035 | iReverseForEach(ObjectList, i, d->children) { |
1032 | iWidget *child = as_Widget(i.object); | 1036 | iWidget *child = as_Widget(i.object); |
1033 | //iAssert(child->root == d->root); | 1037 | //iAssert(child->root == d->root); |
1034 | if (child == get_Window()->focus && isKeyboardEvent_(ev)) { | 1038 | if (child == window_Widget(d)->focus && isKeyboardEvent_(ev)) { |
1035 | continue; /* Already dispatched. */ | 1039 | continue; /* Already dispatched. */ |
1036 | } | 1040 | } |
1037 | if (isVisible_Widget(child) && child->flags & keepOnTop_WidgetFlag) { | 1041 | if (isVisible_Widget(child) && child->flags & keepOnTop_WidgetFlag) { |
1038 | /* Already dispatched. */ | 1042 | /* Already dispatched. */ |
1039 | continue; | 1043 | continue; |
1040 | } | 1044 | } |
1041 | if (dispatchEvent_Widget(child, ev)) { | 1045 | if (dispatchEvent_Widget(child, ev)) { |
@@ -1050,7 +1054,7 @@ iBool dispatchEvent_Widget(iWidget *d, const SDL_Event *ev) { | |||
1050 | #endif | 1054 | #endif |
1051 | #if 0 | 1055 | #if 0 |
1052 | if (ev->type == SDL_MOUSEMOTION) { | 1056 | if (ev->type == SDL_MOUSEMOTION) { |
1053 | printf("[%p] %s:'%s' (on top) ate the motion\n", | 1057 | printf("[%p] %s:'%s' ate the motion\n", |
1054 | child, class_Widget(child)->name, | 1058 | child, class_Widget(child)->name, |
1055 | cstr_String(id_Widget(child))); | 1059 | cstr_String(id_Widget(child))); |
1056 | fflush(stdout); | 1060 | fflush(stdout); |
@@ -1246,7 +1250,7 @@ iBool processEvent_Widget(iWidget *d, const SDL_Event *ev) { | |||
1246 | ev->button.x, | 1250 | ev->button.x, |
1247 | ev->button.y); | 1251 | ev->button.y); |
1248 | } | 1252 | } |
1249 | setCursor_Window(get_Window(), SDL_SYSTEM_CURSOR_ARROW); | 1253 | setCursor_Window(window_Widget(d), SDL_SYSTEM_CURSOR_ARROW); |
1250 | return iTrue; | 1254 | return iTrue; |
1251 | } | 1255 | } |
1252 | return iFalse; | 1256 | return iFalse; |
@@ -1270,6 +1274,7 @@ iLocalDef iBool isDrawn_Widget_(const iWidget *d) { | |||
1270 | void drawLayerEffects_Widget(const iWidget *d) { | 1274 | void drawLayerEffects_Widget(const iWidget *d) { |
1271 | /* Layered effects are not buffered, so they are drawn here separately. */ | 1275 | /* Layered effects are not buffered, so they are drawn here separately. */ |
1272 | iAssert(isDrawn_Widget_(d)); | 1276 | iAssert(isDrawn_Widget_(d)); |
1277 | iAssert(window_Widget(d) == get_Window()); | ||
1273 | iBool shadowBorder = (d->flags & keepOnTop_WidgetFlag && ~d->flags & mouseModal_WidgetFlag) != 0; | 1278 | iBool shadowBorder = (d->flags & keepOnTop_WidgetFlag && ~d->flags & mouseModal_WidgetFlag) != 0; |
1274 | iBool fadeBackground = (d->bgColor >= 0 || d->frameColor >= 0) && d->flags & mouseModal_WidgetFlag; | 1279 | iBool fadeBackground = (d->bgColor >= 0 || d->frameColor >= 0) && d->flags & mouseModal_WidgetFlag; |
1275 | if (deviceType_App() == phone_AppDeviceType) { | 1280 | if (deviceType_App() == phone_AppDeviceType) { |
@@ -1539,6 +1544,7 @@ static void endBufferDraw_Widget_(const iWidget *d) { | |||
1539 | } | 1544 | } |
1540 | 1545 | ||
1541 | void draw_Widget(const iWidget *d) { | 1546 | void draw_Widget(const iWidget *d) { |
1547 | iAssert(window_Widget(d) == get_Window()); | ||
1542 | if (!isDrawn_Widget_(d)) { | 1548 | if (!isDrawn_Widget_(d)) { |
1543 | if (d->drawBuf) { | 1549 | if (d->drawBuf) { |
1544 | // printf("[%p] drawBuffer released\n", d); | 1550 | // printf("[%p] drawBuffer released\n", d); |
@@ -1820,7 +1826,17 @@ iBool equalWidget_Command(const char *cmd, const iWidget *widget, const char *ch | |||
1820 | if (equal_Command(cmd, checkCommand)) { | 1826 | if (equal_Command(cmd, checkCommand)) { |
1821 | const iWidget *src = pointer_Command(cmd); | 1827 | const iWidget *src = pointer_Command(cmd); |
1822 | iAssert(!src || strstr(cmd, " ptr:")); | 1828 | iAssert(!src || strstr(cmd, " ptr:")); |
1823 | return src == widget || hasParent_Widget(src, widget); | 1829 | if (src == widget || hasParent_Widget(src, widget)) { |
1830 | return iTrue; | ||
1831 | } | ||
1832 | // if (src && type_Window(window_Widget(src)) == popup_WindowType) { | ||
1833 | // /* Special case: command was emitted from a popup widget. The popup root widget actually | ||
1834 | // belongs to someone else. */ | ||
1835 | // iWidget *realParent = userData_Object(src->root->widget); | ||
1836 | // iAssert(realParent); | ||
1837 | // iAssert(isInstance_Object(realParent, &Class_Widget)); | ||
1838 | // return realParent == widget || hasParent_Widget(realParent, widget); | ||
1839 | // } | ||
1824 | } | 1840 | } |
1825 | return iFalse; | 1841 | return iFalse; |
1826 | } | 1842 | } |
@@ -1962,6 +1978,10 @@ void postCommand_Widget(const iAnyObject *d, const char *cmd, ...) { | |||
1962 | } | 1978 | } |
1963 | if (!isGlobal) { | 1979 | if (!isGlobal) { |
1964 | iAssert(isInstance_Object(d, &Class_Widget)); | 1980 | iAssert(isInstance_Object(d, &Class_Widget)); |
1981 | if (type_Window(window_Widget(d)) == popup_WindowType) { | ||
1982 | postCommandf_Root(((const iWidget *) d)->root, "cancel popup:1 ptr:%p", d); | ||
1983 | d = userData_Object(root_Widget(d)); | ||
1984 | } | ||
1965 | appendFormat_String(&str, " ptr:%p", d); | 1985 | appendFormat_String(&str, " ptr:%p", d); |
1966 | } | 1986 | } |
1967 | postCommandString_Root(((const iWidget *) d)->root, &str); | 1987 | postCommandString_Root(((const iWidget *) d)->root, &str); |