summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorJaakko Keränen <jaakko.keranen@iki.fi>2021-10-22 07:22:15 +0300
committerJaakko Keränen <jaakko.keranen@iki.fi>2021-10-22 07:22:15 +0300
commitd14f9aebe27cd48a8d21c0eb691c8e7bf94722a8 (patch)
treeda58c38b49dba1c45483eec89ea9408432655aea
parent525c0e24dca01a08ae389b271aee7400ebd8c16b (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.
-rw-r--r--src/app.c3
-rw-r--r--src/ui/labelwidget.c10
-rw-r--r--src/ui/labelwidget.h1
-rw-r--r--src/ui/mobile.c3
-rw-r--r--src/ui/util.c15
-rw-r--r--src/ui/util.h1
-rw-r--r--src/ui/widget.c22
-rw-r--r--src/ui/widget.h2
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
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
308static void draw_LabelWidget_(const iLabelWidget *d) { 309static 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
435static void sizeChanged_LabelWidget_(iLabelWidget *d) { 437static 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
572void setChevron_LabelWidget(iLabelWidget *d, iBool chevron) {
573 d->flags.chevron = chevron;
574}
575
570void setWrap_LabelWidget(iLabelWidget *d, iBool wrap) { 576void 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
32void setAlignVisually_LabelWidget(iLabelWidget *, iBool alignVisual); 32void setAlignVisually_LabelWidget(iLabelWidget *, iBool alignVisual);
33void setNoAutoMinHeight_LabelWidget (iLabelWidget *, iBool noAutoMinHeight); 33void setNoAutoMinHeight_LabelWidget (iLabelWidget *, iBool noAutoMinHeight);
34void setNoTopFrame_LabelWidget (iLabelWidget *, iBool noTopFrame); 34void setNoTopFrame_LabelWidget (iLabelWidget *, iBool noTopFrame);
35void setChevron_LabelWidget (iLabelWidget *, iBool chevron);
35void setWrap_LabelWidget (iLabelWidget *, iBool wrap); 36void setWrap_LabelWidget (iLabelWidget *, iBool wrap);
36void setOutline_LabelWidget (iLabelWidget *, iBool drawAsOutline); 37void setOutline_LabelWidget (iLabelWidget *, iBool drawAsOutline);
37void setAllCaps_LabelWidget (iLabelWidget *, iBool allCaps); 38void 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
1439iLabelWidget *tabButtonForPage_Widget_(iWidget *tabs, const iWidget *page) { 1439static 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
1451void 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
1451void showTabPage_Widget(iWidget *tabs, const iWidget *page) { 1464void 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
272iWidget * removeTabPage_Widget (iWidget *tabs, size_t index); /* returns the page */ 272iWidget * removeTabPage_Widget (iWidget *tabs, size_t index); /* returns the page */
273void resizeToLargestPage_Widget (iWidget *tabs); 273void resizeToLargestPage_Widget (iWidget *tabs);
274void showTabPage_Widget (iWidget *tabs, const iWidget *page); 274void showTabPage_Widget (iWidget *tabs, const iWidget *page);
275void addTabCloseButton_Widget(iWidget *tabs, const iWidget *page, const char *command);
275void setTabPageLabel_Widget (iWidget *tabs, const iAnyObject *page, const iString *label); 276void setTabPageLabel_Widget (iWidget *tabs, const iAnyObject *page, const iString *label);
276iWidget * tabPage_Widget (iWidget *tabs, size_t index); 277iWidget * tabPage_Widget (iWidget *tabs, size_t index);
277iLabelWidget * tabPageButton_Widget (iWidget *tabs, const iAnyObject *page); 278iLabelWidget * 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
976iLocalDef 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
984iLocalDef iBool isDrawn_Widget_(const iWidget *d) {
985 return !isHidden_Widget_(d) || d->flags & visualOffset_WidgetFlag;
986}
987
976static iBool filterEvent_Widget_(const iWidget *d, const SDL_Event *ev) { 988static 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
1285iLocalDef iBool isDrawn_Widget_(const iWidget *d) {
1286 return ~d->flags & hidden_WidgetFlag || d->flags & visualOffset_WidgetFlag;
1287}
1288
1289void drawLayerEffects_Widget(const iWidget *d) { 1297void 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
1713iAny *hitChild_Widget(const iWidget *d, iInt2 coord) { 1721iAny *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)