diff options
author | Jaakko Keränen <jaakko.keranen@iki.fi> | 2021-10-22 07:22:15 +0300 |
---|---|---|
committer | Jaakko Keränen <jaakko.keranen@iki.fi> | 2021-10-22 07:22:15 +0300 |
commit | d14f9aebe27cd48a8d21c0eb691c8e7bf94722a8 (patch) | |
tree | da58c38b49dba1c45483eec89ea9408432655aea /src | |
parent | 525c0e24dca01a08ae389b271aee7400ebd8c16b (diff) |
Working on tab close buttons
An [x] button appears on tab buttons when hovering on them. Still needs a bit of layout tweaks and the first tab doesn't have a button yet.
Diffstat (limited to 'src')
-rw-r--r-- | src/app.c | 3 | ||||
-rw-r--r-- | src/ui/labelwidget.c | 10 | ||||
-rw-r--r-- | src/ui/labelwidget.h | 1 | ||||
-rw-r--r-- | src/ui/mobile.c | 3 | ||||
-rw-r--r-- | src/ui/util.c | 15 | ||||
-rw-r--r-- | src/ui/util.h | 1 | ||||
-rw-r--r-- | src/ui/widget.c | 22 | ||||
-rw-r--r-- | src/ui/widget.h | 2 |
8 files changed, 44 insertions, 13 deletions
@@ -1889,6 +1889,7 @@ iDocumentWidget *newTab_App(const iDocumentWidget *duplicateOf, iBool switchToNe | |||
1889 | } | 1889 | } |
1890 | appendTabPage_Widget(tabs, as_Widget(doc), "", 0, 0); | 1890 | appendTabPage_Widget(tabs, as_Widget(doc), "", 0, 0); |
1891 | iRelease(doc); /* now owned by the tabs */ | 1891 | iRelease(doc); /* now owned by the tabs */ |
1892 | addTabCloseButton_Widget(tabs, as_Widget(doc), "tabs.close"); | ||
1892 | addChild_Widget(findChild_Widget(tabs, "tabs.buttons"), iClob(newTabButton)); | 1893 | addChild_Widget(findChild_Widget(tabs, "tabs.buttons"), iClob(newTabButton)); |
1893 | if (switchToNew) { | 1894 | if (switchToNew) { |
1894 | postCommandf_App("tabs.switch page:%p", doc); | 1895 | postCommandf_App("tabs.switch page:%p", doc); |
@@ -2586,7 +2587,7 @@ iBool handleCommand_App(const char *cmd) { | |||
2586 | else if (equal_Command(cmd, "tabs.close")) { | 2587 | else if (equal_Command(cmd, "tabs.close")) { |
2587 | iWidget *tabs = findWidget_App("doctabs"); | 2588 | iWidget *tabs = findWidget_App("doctabs"); |
2588 | #if defined (iPlatformMobile) | 2589 | #if defined (iPlatformMobile) |
2589 | /* Can't close the last on mobile. */ | 2590 | /* Can't close the last tab on mobile. */ |
2590 | if (tabCount_Widget(tabs) == 1 && numRoots_Window(get_Window()) == 1) { | 2591 | if (tabCount_Widget(tabs) == 1 && numRoots_Window(get_Window()) == 1) { |
2591 | postCommand_App("navigate.home"); | 2592 | postCommand_App("navigate.home"); |
2592 | return iTrue; | 2593 | return iTrue; |
diff --git a/src/ui/labelwidget.c b/src/ui/labelwidget.c index cfc81863..1cbad550 100644 --- a/src/ui/labelwidget.c +++ b/src/ui/labelwidget.c | |||
@@ -51,6 +51,7 @@ struct Impl_LabelWidget { | |||
51 | uint8_t wrap : 1; | 51 | uint8_t wrap : 1; |
52 | uint8_t allCaps : 1; | 52 | uint8_t allCaps : 1; |
53 | uint8_t removeTrailingColon : 1; | 53 | uint8_t removeTrailingColon : 1; |
54 | uint8_t chevron : 1; | ||
54 | } flags; | 55 | } flags; |
55 | }; | 56 | }; |
56 | 57 | ||
@@ -307,7 +308,7 @@ static iRect contentBounds_LabelWidget_(const iLabelWidget *d) { | |||
307 | 308 | ||
308 | static void draw_LabelWidget_(const iLabelWidget *d) { | 309 | static void draw_LabelWidget_(const iLabelWidget *d) { |
309 | const iWidget *w = constAs_Widget(d); | 310 | const iWidget *w = constAs_Widget(d); |
310 | draw_Widget(w); | 311 | drawBackground_Widget(w); |
311 | const iBool isButton = d->click.button != 0; | 312 | const iBool isButton = d->click.button != 0; |
312 | const int64_t flags = flags_Widget(w); | 313 | const int64_t flags = flags_Widget(w); |
313 | const iRect bounds = bounds_Widget(w); | 314 | const iRect bounds = bounds_Widget(w); |
@@ -421,7 +422,7 @@ static void draw_LabelWidget_(const iLabelWidget *d) { | |||
421 | "%s", | 422 | "%s", |
422 | cstr_String(&d->label)); | 423 | cstr_String(&d->label)); |
423 | } | 424 | } |
424 | if (flags & chevron_WidgetFlag) { | 425 | if (d->flags.chevron) { |
425 | const iRect chRect = rect; | 426 | const iRect chRect = rect; |
426 | const int chSize = lineHeight_Text(d->font); | 427 | const int chSize = lineHeight_Text(d->font); |
427 | drawCentered_Text(d->font, | 428 | drawCentered_Text(d->font, |
@@ -430,6 +431,7 @@ static void draw_LabelWidget_(const iLabelWidget *d) { | |||
430 | iTrue, iconColor, rightAngle_Icon); | 431 | iTrue, iconColor, rightAngle_Icon); |
431 | } | 432 | } |
432 | unsetClip_Paint(&p); | 433 | unsetClip_Paint(&p); |
434 | drawChildren_Widget(w); | ||
433 | } | 435 | } |
434 | 436 | ||
435 | static void sizeChanged_LabelWidget_(iLabelWidget *d) { | 437 | static void sizeChanged_LabelWidget_(iLabelWidget *d) { |
@@ -567,6 +569,10 @@ void setNoTopFrame_LabelWidget(iLabelWidget *d, iBool noTopFrame) { | |||
567 | d->flags.noTopFrame = noTopFrame; | 569 | d->flags.noTopFrame = noTopFrame; |
568 | } | 570 | } |
569 | 571 | ||
572 | void setChevron_LabelWidget(iLabelWidget *d, iBool chevron) { | ||
573 | d->flags.chevron = chevron; | ||
574 | } | ||
575 | |||
570 | void setWrap_LabelWidget(iLabelWidget *d, iBool wrap) { | 576 | void setWrap_LabelWidget(iLabelWidget *d, iBool wrap) { |
571 | d->flags.wrap = wrap; | 577 | d->flags.wrap = wrap; |
572 | } | 578 | } |
diff --git a/src/ui/labelwidget.h b/src/ui/labelwidget.h index 6275d2c8..6542ae12 100644 --- a/src/ui/labelwidget.h +++ b/src/ui/labelwidget.h | |||
@@ -32,6 +32,7 @@ iDeclareObjectConstructionArgs(LabelWidget, const char *label, const char *comma | |||
32 | void setAlignVisually_LabelWidget(iLabelWidget *, iBool alignVisual); | 32 | void setAlignVisually_LabelWidget(iLabelWidget *, iBool alignVisual); |
33 | void setNoAutoMinHeight_LabelWidget (iLabelWidget *, iBool noAutoMinHeight); | 33 | void setNoAutoMinHeight_LabelWidget (iLabelWidget *, iBool noAutoMinHeight); |
34 | void setNoTopFrame_LabelWidget (iLabelWidget *, iBool noTopFrame); | 34 | void setNoTopFrame_LabelWidget (iLabelWidget *, iBool noTopFrame); |
35 | void setChevron_LabelWidget (iLabelWidget *, iBool chevron); | ||
35 | void setWrap_LabelWidget (iLabelWidget *, iBool wrap); | 36 | void setWrap_LabelWidget (iLabelWidget *, iBool wrap); |
36 | void setOutline_LabelWidget (iLabelWidget *, iBool drawAsOutline); | 37 | void setOutline_LabelWidget (iLabelWidget *, iBool drawAsOutline); |
37 | void setAllCaps_LabelWidget (iLabelWidget *, iBool allCaps); | 38 | void setAllCaps_LabelWidget (iLabelWidget *, iBool allCaps); |
diff --git a/src/ui/mobile.c b/src/ui/mobile.c index 3cb6e631..1e58cf82 100644 --- a/src/ui/mobile.c +++ b/src/ui/mobile.c | |||
@@ -734,7 +734,8 @@ void initPanels_Mobile(iWidget *panels, iWidget *parentWidget, | |||
734 | iLabelWidget * button = | 734 | iLabelWidget * button = |
735 | addChildFlags_Widget(topPanel, | 735 | addChildFlags_Widget(topPanel, |
736 | iClob(makePanelButton_(cstr_String(label), "panel.open")), | 736 | iClob(makePanelButton_(cstr_String(label), "panel.open")), |
737 | chevron_WidgetFlag | borderTop_WidgetFlag); | 737 | borderTop_WidgetFlag); |
738 | setChevron_LabelWidget(button, iTrue); | ||
738 | const iChar icon = toInt_String(string_Command(item->label, "icon")); | 739 | const iChar icon = toInt_String(string_Command(item->label, "icon")); |
739 | if (icon) { | 740 | if (icon) { |
740 | setIcon_LabelWidget(button, icon); | 741 | setIcon_LabelWidget(button, icon); |
diff --git a/src/ui/util.c b/src/ui/util.c index b18a3292..66704370 100644 --- a/src/ui/util.c +++ b/src/ui/util.c | |||
@@ -1436,7 +1436,7 @@ void resizeToLargestPage_Widget(iWidget *tabs) { | |||
1436 | // puts("... DONE WITH RESIZE TO LARGEST PAGE"); | 1436 | // puts("... DONE WITH RESIZE TO LARGEST PAGE"); |
1437 | } | 1437 | } |
1438 | 1438 | ||
1439 | iLabelWidget *tabButtonForPage_Widget_(iWidget *tabs, const iWidget *page) { | 1439 | static iLabelWidget *tabButtonForPage_Widget_(iWidget *tabs, const iWidget *page) { |
1440 | iWidget *buttons = findChild_Widget(tabs, "tabs.buttons"); | 1440 | iWidget *buttons = findChild_Widget(tabs, "tabs.buttons"); |
1441 | iForEach(ObjectList, i, buttons->children) { | 1441 | iForEach(ObjectList, i, buttons->children) { |
1442 | iAssert(isInstance_Object(i.object, &Class_LabelWidget)); | 1442 | iAssert(isInstance_Object(i.object, &Class_LabelWidget)); |
@@ -1448,6 +1448,19 @@ iLabelWidget *tabButtonForPage_Widget_(iWidget *tabs, const iWidget *page) { | |||
1448 | return NULL; | 1448 | return NULL; |
1449 | } | 1449 | } |
1450 | 1450 | ||
1451 | void addTabCloseButton_Widget(iWidget *tabs, const iWidget *page, const char *command) { | ||
1452 | iLabelWidget *tabButton = tabButtonForPage_Widget_(tabs, page); | ||
1453 | // setPadding1_Widget(as_Widget(tabButton), gap_UI / 8); | ||
1454 | iLabelWidget *close = addChildFlags_Widget( | ||
1455 | as_Widget(tabButton), | ||
1456 | iClob(new_LabelWidget(close_Icon, | ||
1457 | format_CStr("%s id:%s", command, cstr_String(id_Widget(page))))), | ||
1458 | moveToParentRightEdge_WidgetFlag | tight_WidgetFlag | frameless_WidgetFlag | | ||
1459 | hidden_WidgetFlag | visibleOnParentHover_WidgetFlag); | ||
1460 | updateSize_LabelWidget(close); | ||
1461 | printTree_Widget(tabs); | ||
1462 | } | ||
1463 | |||
1451 | void showTabPage_Widget(iWidget *tabs, const iWidget *page) { | 1464 | void showTabPage_Widget(iWidget *tabs, const iWidget *page) { |
1452 | if (!page) { | 1465 | if (!page) { |
1453 | return; | 1466 | return; |
diff --git a/src/ui/util.h b/src/ui/util.h index 94e5d8bd..cf96dfe4 100644 --- a/src/ui/util.h +++ b/src/ui/util.h | |||
@@ -272,6 +272,7 @@ void prependTabPage_Widget (iWidget *tabs, iWidget *page, const cha | |||
272 | iWidget * removeTabPage_Widget (iWidget *tabs, size_t index); /* returns the page */ | 272 | iWidget * removeTabPage_Widget (iWidget *tabs, size_t index); /* returns the page */ |
273 | void resizeToLargestPage_Widget (iWidget *tabs); | 273 | void resizeToLargestPage_Widget (iWidget *tabs); |
274 | void showTabPage_Widget (iWidget *tabs, const iWidget *page); | 274 | void showTabPage_Widget (iWidget *tabs, const iWidget *page); |
275 | void addTabCloseButton_Widget(iWidget *tabs, const iWidget *page, const char *command); | ||
275 | void setTabPageLabel_Widget (iWidget *tabs, const iAnyObject *page, const iString *label); | 276 | void setTabPageLabel_Widget (iWidget *tabs, const iAnyObject *page, const iString *label); |
276 | iWidget * tabPage_Widget (iWidget *tabs, size_t index); | 277 | iWidget * tabPage_Widget (iWidget *tabs, size_t index); |
277 | iLabelWidget * tabPageButton_Widget (iWidget *tabs, const iAnyObject *page); | 278 | iLabelWidget * tabPageButton_Widget (iWidget *tabs, const iAnyObject *page); |
diff --git a/src/ui/widget.c b/src/ui/widget.c index ec92ac5a..75c07c5a 100644 --- a/src/ui/widget.c +++ b/src/ui/widget.c | |||
@@ -973,6 +973,18 @@ iLocalDef iBool isMouseEvent_(const SDL_Event *ev) { | |||
973 | ev->type == SDL_MOUSEBUTTONUP || ev->type == SDL_MOUSEBUTTONDOWN); | 973 | ev->type == SDL_MOUSEBUTTONUP || ev->type == SDL_MOUSEBUTTONDOWN); |
974 | } | 974 | } |
975 | 975 | ||
976 | iLocalDef iBool isHidden_Widget_(const iWidget *d) { | ||
977 | if (d->flags & visibleOnParentHover_WidgetFlag && | ||
978 | (isHover_Widget(d) || isHover_Widget(d->parent))) { | ||
979 | return iFalse; | ||
980 | } | ||
981 | return (d->flags & hidden_WidgetFlag) != 0; | ||
982 | } | ||
983 | |||
984 | iLocalDef iBool isDrawn_Widget_(const iWidget *d) { | ||
985 | return !isHidden_Widget_(d) || d->flags & visualOffset_WidgetFlag; | ||
986 | } | ||
987 | |||
976 | static iBool filterEvent_Widget_(const iWidget *d, const SDL_Event *ev) { | 988 | static iBool filterEvent_Widget_(const iWidget *d, const SDL_Event *ev) { |
977 | if (d->flags & destroyPending_WidgetFlag) { | 989 | if (d->flags & destroyPending_WidgetFlag) { |
978 | return iFalse; /* no more events handled */ | 990 | return iFalse; /* no more events handled */ |
@@ -983,7 +995,7 @@ static iBool filterEvent_Widget_(const iWidget *d, const SDL_Event *ev) { | |||
983 | d->flags & disabledWhenHidden_WidgetFlag)) { | 995 | d->flags & disabledWhenHidden_WidgetFlag)) { |
984 | if (isKey || isMouse) return iFalse; | 996 | if (isKey || isMouse) return iFalse; |
985 | } | 997 | } |
986 | if (d->flags & hidden_WidgetFlag) { | 998 | if (isHidden_Widget_(d)) { |
987 | if (isMouse) return iFalse; | 999 | if (isMouse) return iFalse; |
988 | } | 1000 | } |
989 | return iTrue; | 1001 | return iTrue; |
@@ -1032,7 +1044,7 @@ iBool dispatchEvent_Widget(iWidget *d, const SDL_Event *ev) { | |||
1032 | else if (ev->type == SDL_MOUSEMOTION && | 1044 | else if (ev->type == SDL_MOUSEMOTION && |
1033 | ev->motion.windowID == SDL_GetWindowID(window_Widget(d)->win) && | 1045 | ev->motion.windowID == SDL_GetWindowID(window_Widget(d)->win) && |
1034 | (!window_Widget(d)->hover || hasParent_Widget(d, window_Widget(d)->hover)) && | 1046 | (!window_Widget(d)->hover || hasParent_Widget(d, window_Widget(d)->hover)) && |
1035 | flags_Widget(d) & hover_WidgetFlag && ~flags_Widget(d) & hidden_WidgetFlag && | 1047 | flags_Widget(d) & hover_WidgetFlag && !isHidden_Widget_(d) && |
1036 | ~flags_Widget(d) & disabled_WidgetFlag) { | 1048 | ~flags_Widget(d) & disabled_WidgetFlag) { |
1037 | if (contains_Widget(d, init_I2(ev->motion.x, ev->motion.y))) { | 1049 | if (contains_Widget(d, init_I2(ev->motion.x, ev->motion.y))) { |
1038 | setHover_Widget(d); | 1050 | setHover_Widget(d); |
@@ -1282,10 +1294,6 @@ int backgroundFadeColor_Widget(void) { | |||
1282 | } | 1294 | } |
1283 | } | 1295 | } |
1284 | 1296 | ||
1285 | iLocalDef iBool isDrawn_Widget_(const iWidget *d) { | ||
1286 | return ~d->flags & hidden_WidgetFlag || d->flags & visualOffset_WidgetFlag; | ||
1287 | } | ||
1288 | |||
1289 | void drawLayerEffects_Widget(const iWidget *d) { | 1297 | void drawLayerEffects_Widget(const iWidget *d) { |
1290 | /* Layered effects are not buffered, so they are drawn here separately. */ | 1298 | /* Layered effects are not buffered, so they are drawn here separately. */ |
1291 | iAssert(isDrawn_Widget_(d)); | 1299 | iAssert(isDrawn_Widget_(d)); |
@@ -1711,7 +1719,7 @@ size_t childIndex_Widget(const iWidget *d, const iAnyObject *child) { | |||
1711 | } | 1719 | } |
1712 | 1720 | ||
1713 | iAny *hitChild_Widget(const iWidget *d, iInt2 coord) { | 1721 | iAny *hitChild_Widget(const iWidget *d, iInt2 coord) { |
1714 | if (d->flags & hidden_WidgetFlag) { | 1722 | if (isHidden_Widget_(d)) { |
1715 | return NULL; | 1723 | return NULL; |
1716 | } | 1724 | } |
1717 | /* Check for on-top widgets first. */ | 1725 | /* Check for on-top widgets first. */ |
diff --git a/src/ui/widget.h b/src/ui/widget.h index 9243c00a..b119610a 100644 --- a/src/ui/widget.h +++ b/src/ui/widget.h | |||
@@ -109,7 +109,7 @@ enum iWidgetFlag { | |||
109 | #define extraPadding_WidgetFlag iBit64(49) | 109 | #define extraPadding_WidgetFlag iBit64(49) |
110 | #define borderBottom_WidgetFlag iBit64(50) | 110 | #define borderBottom_WidgetFlag iBit64(50) |
111 | #define horizontalOffset_WidgetFlag iBit64(51) /* default is vertical offset */ | 111 | #define horizontalOffset_WidgetFlag iBit64(51) /* default is vertical offset */ |
112 | #define chevron_WidgetFlag iBit64(52) | 112 | #define visibleOnParentHover_WidgetFlag iBit64(52) |
113 | #define drawBackgroundToBottom_WidgetFlag iBit64(53) | 113 | #define drawBackgroundToBottom_WidgetFlag iBit64(53) |
114 | #define dragged_WidgetFlag iBit64(54) | 114 | #define dragged_WidgetFlag iBit64(54) |
115 | #define hittable_WidgetFlag iBit64(55) | 115 | #define hittable_WidgetFlag iBit64(55) |