From d14f9aebe27cd48a8d21c0eb691c8e7bf94722a8 Mon Sep 17 00:00:00 2001 From: Jaakko Keränen Date: Fri, 22 Oct 2021 07:22:15 +0300 Subject: 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. --- src/app.c | 3 ++- src/ui/labelwidget.c | 10 ++++++++-- src/ui/labelwidget.h | 1 + src/ui/mobile.c | 3 ++- src/ui/util.c | 15 ++++++++++++++- src/ui/util.h | 1 + src/ui/widget.c | 22 +++++++++++++++------- src/ui/widget.h | 2 +- 8 files changed, 44 insertions(+), 13 deletions(-) diff --git a/src/app.c b/src/app.c index b7db6dce..de3f5d74 100644 --- a/src/app.c +++ b/src/app.c @@ -1889,6 +1889,7 @@ iDocumentWidget *newTab_App(const iDocumentWidget *duplicateOf, iBool switchToNe } appendTabPage_Widget(tabs, as_Widget(doc), "", 0, 0); iRelease(doc); /* now owned by the tabs */ + addTabCloseButton_Widget(tabs, as_Widget(doc), "tabs.close"); addChild_Widget(findChild_Widget(tabs, "tabs.buttons"), iClob(newTabButton)); if (switchToNew) { postCommandf_App("tabs.switch page:%p", doc); @@ -2586,7 +2587,7 @@ iBool handleCommand_App(const char *cmd) { else if (equal_Command(cmd, "tabs.close")) { iWidget *tabs = findWidget_App("doctabs"); #if defined (iPlatformMobile) - /* Can't close the last on mobile. */ + /* Can't close the last tab on mobile. */ if (tabCount_Widget(tabs) == 1 && numRoots_Window(get_Window()) == 1) { postCommand_App("navigate.home"); 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 { uint8_t wrap : 1; uint8_t allCaps : 1; uint8_t removeTrailingColon : 1; + uint8_t chevron : 1; } flags; }; @@ -307,7 +308,7 @@ static iRect contentBounds_LabelWidget_(const iLabelWidget *d) { static void draw_LabelWidget_(const iLabelWidget *d) { const iWidget *w = constAs_Widget(d); - draw_Widget(w); + drawBackground_Widget(w); const iBool isButton = d->click.button != 0; const int64_t flags = flags_Widget(w); const iRect bounds = bounds_Widget(w); @@ -421,7 +422,7 @@ static void draw_LabelWidget_(const iLabelWidget *d) { "%s", cstr_String(&d->label)); } - if (flags & chevron_WidgetFlag) { + if (d->flags.chevron) { const iRect chRect = rect; const int chSize = lineHeight_Text(d->font); drawCentered_Text(d->font, @@ -430,6 +431,7 @@ static void draw_LabelWidget_(const iLabelWidget *d) { iTrue, iconColor, rightAngle_Icon); } unsetClip_Paint(&p); + drawChildren_Widget(w); } static void sizeChanged_LabelWidget_(iLabelWidget *d) { @@ -567,6 +569,10 @@ void setNoTopFrame_LabelWidget(iLabelWidget *d, iBool noTopFrame) { d->flags.noTopFrame = noTopFrame; } +void setChevron_LabelWidget(iLabelWidget *d, iBool chevron) { + d->flags.chevron = chevron; +} + void setWrap_LabelWidget(iLabelWidget *d, iBool wrap) { d->flags.wrap = wrap; } 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 void setAlignVisually_LabelWidget(iLabelWidget *, iBool alignVisual); void setNoAutoMinHeight_LabelWidget (iLabelWidget *, iBool noAutoMinHeight); void setNoTopFrame_LabelWidget (iLabelWidget *, iBool noTopFrame); +void setChevron_LabelWidget (iLabelWidget *, iBool chevron); void setWrap_LabelWidget (iLabelWidget *, iBool wrap); void setOutline_LabelWidget (iLabelWidget *, iBool drawAsOutline); 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, iLabelWidget * button = addChildFlags_Widget(topPanel, iClob(makePanelButton_(cstr_String(label), "panel.open")), - chevron_WidgetFlag | borderTop_WidgetFlag); + borderTop_WidgetFlag); + setChevron_LabelWidget(button, iTrue); const iChar icon = toInt_String(string_Command(item->label, "icon")); if (icon) { 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) { // puts("... DONE WITH RESIZE TO LARGEST PAGE"); } -iLabelWidget *tabButtonForPage_Widget_(iWidget *tabs, const iWidget *page) { +static iLabelWidget *tabButtonForPage_Widget_(iWidget *tabs, const iWidget *page) { iWidget *buttons = findChild_Widget(tabs, "tabs.buttons"); iForEach(ObjectList, i, buttons->children) { iAssert(isInstance_Object(i.object, &Class_LabelWidget)); @@ -1448,6 +1448,19 @@ iLabelWidget *tabButtonForPage_Widget_(iWidget *tabs, const iWidget *page) { return NULL; } +void addTabCloseButton_Widget(iWidget *tabs, const iWidget *page, const char *command) { + iLabelWidget *tabButton = tabButtonForPage_Widget_(tabs, page); +// setPadding1_Widget(as_Widget(tabButton), gap_UI / 8); + iLabelWidget *close = addChildFlags_Widget( + as_Widget(tabButton), + iClob(new_LabelWidget(close_Icon, + format_CStr("%s id:%s", command, cstr_String(id_Widget(page))))), + moveToParentRightEdge_WidgetFlag | tight_WidgetFlag | frameless_WidgetFlag | + hidden_WidgetFlag | visibleOnParentHover_WidgetFlag); + updateSize_LabelWidget(close); + printTree_Widget(tabs); +} + void showTabPage_Widget(iWidget *tabs, const iWidget *page) { if (!page) { 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 iWidget * removeTabPage_Widget (iWidget *tabs, size_t index); /* returns the page */ void resizeToLargestPage_Widget (iWidget *tabs); void showTabPage_Widget (iWidget *tabs, const iWidget *page); +void addTabCloseButton_Widget(iWidget *tabs, const iWidget *page, const char *command); void setTabPageLabel_Widget (iWidget *tabs, const iAnyObject *page, const iString *label); iWidget * tabPage_Widget (iWidget *tabs, size_t index); 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) { ev->type == SDL_MOUSEBUTTONUP || ev->type == SDL_MOUSEBUTTONDOWN); } +iLocalDef iBool isHidden_Widget_(const iWidget *d) { + if (d->flags & visibleOnParentHover_WidgetFlag && + (isHover_Widget(d) || isHover_Widget(d->parent))) { + return iFalse; + } + return (d->flags & hidden_WidgetFlag) != 0; +} + +iLocalDef iBool isDrawn_Widget_(const iWidget *d) { + return !isHidden_Widget_(d) || d->flags & visualOffset_WidgetFlag; +} + static iBool filterEvent_Widget_(const iWidget *d, const SDL_Event *ev) { if (d->flags & destroyPending_WidgetFlag) { return iFalse; /* no more events handled */ @@ -983,7 +995,7 @@ static iBool filterEvent_Widget_(const iWidget *d, const SDL_Event *ev) { d->flags & disabledWhenHidden_WidgetFlag)) { if (isKey || isMouse) return iFalse; } - if (d->flags & hidden_WidgetFlag) { + if (isHidden_Widget_(d)) { if (isMouse) return iFalse; } return iTrue; @@ -1032,7 +1044,7 @@ iBool dispatchEvent_Widget(iWidget *d, const SDL_Event *ev) { else if (ev->type == SDL_MOUSEMOTION && ev->motion.windowID == SDL_GetWindowID(window_Widget(d)->win) && (!window_Widget(d)->hover || hasParent_Widget(d, window_Widget(d)->hover)) && - flags_Widget(d) & hover_WidgetFlag && ~flags_Widget(d) & hidden_WidgetFlag && + flags_Widget(d) & hover_WidgetFlag && !isHidden_Widget_(d) && ~flags_Widget(d) & disabled_WidgetFlag) { if (contains_Widget(d, init_I2(ev->motion.x, ev->motion.y))) { setHover_Widget(d); @@ -1282,10 +1294,6 @@ int backgroundFadeColor_Widget(void) { } } -iLocalDef iBool isDrawn_Widget_(const iWidget *d) { - return ~d->flags & hidden_WidgetFlag || d->flags & visualOffset_WidgetFlag; -} - void drawLayerEffects_Widget(const iWidget *d) { /* Layered effects are not buffered, so they are drawn here separately. */ iAssert(isDrawn_Widget_(d)); @@ -1711,7 +1719,7 @@ size_t childIndex_Widget(const iWidget *d, const iAnyObject *child) { } iAny *hitChild_Widget(const iWidget *d, iInt2 coord) { - if (d->flags & hidden_WidgetFlag) { + if (isHidden_Widget_(d)) { return NULL; } /* 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 { #define extraPadding_WidgetFlag iBit64(49) #define borderBottom_WidgetFlag iBit64(50) #define horizontalOffset_WidgetFlag iBit64(51) /* default is vertical offset */ -#define chevron_WidgetFlag iBit64(52) +#define visibleOnParentHover_WidgetFlag iBit64(52) #define drawBackgroundToBottom_WidgetFlag iBit64(53) #define dragged_WidgetFlag iBit64(54) #define hittable_WidgetFlag iBit64(55) -- cgit v1.2.3