diff options
author | Jaakko Keränen <jaakko.keranen@iki.fi> | 2021-04-30 12:17:07 +0300 |
---|---|---|
committer | Jaakko Keränen <jaakko.keranen@iki.fi> | 2021-04-30 12:17:07 +0300 |
commit | 1495d08163a4bfcd5db5f6c3b06f031032c5461f (patch) | |
tree | 7538e5ca6f054afd292ca9c4b7b7ff81a3d1222f /src/ui/root.c | |
parent | fed2b149aeb5c5cd692421602e0fe77ceffb8b28 (diff) |
Revising and fixing widget layout
Some of the logic for arranging widgets was invalid, leading to problems with the navbar:
- cannot resize children if own size depends on their size
- expanding children won't expand unless resizing all children
Diffstat (limited to 'src/ui/root.c')
-rw-r--r-- | src/ui/root.c | 130 |
1 files changed, 70 insertions, 60 deletions
diff --git a/src/ui/root.c b/src/ui/root.c index a97c8d49..287b641e 100644 --- a/src/ui/root.c +++ b/src/ui/root.c | |||
@@ -541,59 +541,63 @@ iBool isNarrow_Root(const iRoot *d) { | |||
541 | return width_Rect(safeRect_Root(d)) / gap_UI < 140; | 541 | return width_Rect(safeRect_Root(d)) / gap_UI < 140; |
542 | } | 542 | } |
543 | 543 | ||
544 | static iBool handleNavBarCommands_(iWidget *navBar, const char *cmd) { | 544 | static void updateNavBarSize_(iWidget *navBar) { |
545 | if (equal_Command(cmd, "window.resized") || equal_Command(cmd, "metrics.changed")) { | 545 | const iBool isPhone = deviceType_App() == phone_AppDeviceType; |
546 | const iBool isPhone = deviceType_App() == phone_AppDeviceType; | 546 | const iBool isNarrow = !isPhone && isNarrow_Root(navBar->root); |
547 | const iBool isNarrow = !isPhone && isNarrow_Root(navBar->root); | 547 | /* Adjust navbar padding. */ { |
548 | /* Adjust navbar padding. */ { | 548 | int hPad = isPhone && isPortrait_App() ? 0 : (isPhone || isNarrow) ? gap_UI / 2 |
549 | int hPad = isPhone && isPortrait_App() ? 0 : (isPhone || isNarrow) ? gap_UI / 2 | 549 | : gap_UI * 3 / 2; |
550 | : gap_UI * 3 / 2; | 550 | int vPad = gap_UI * 3 / 2; |
551 | int vPad = gap_UI * 3 / 2; | 551 | int topPad = !findWidget_Root("winbar") ? gap_UI / 2 : 0; |
552 | int topPad = !findWidget_App("winbar") ? gap_UI / 2 : 0; | 552 | setPadding_Widget(navBar, hPad, vPad / 3 + topPad, hPad, vPad / 2); |
553 | setPadding_Widget(navBar, hPad, vPad / 3 + topPad, hPad, vPad / 2); | 553 | } |
554 | } | 554 | /* Button sizing. */ |
555 | /* Button sizing. */ | 555 | if (isNarrow ^ ((flags_Widget(navBar) & tight_WidgetFlag) != 0)) { |
556 | if (isNarrow ^ ((flags_Widget(navBar) & tight_WidgetFlag) != 0)) { | 556 | setFlags_Widget(navBar, tight_WidgetFlag, isNarrow); |
557 | setFlags_Widget(navBar, tight_WidgetFlag, isNarrow); | 557 | iForEach(ObjectList, i, navBar->children) { |
558 | iForEach(ObjectList, i, navBar->children) { | 558 | iWidget *child = as_Widget(i.object); |
559 | iWidget *child = as_Widget(i.object); | 559 | setFlags_Widget(child, tight_WidgetFlag, isNarrow); |
560 | setFlags_Widget(child, tight_WidgetFlag, isNarrow); | 560 | if (isInstance_Object(i.object, &Class_LabelWidget)) { |
561 | if (isInstance_Object(i.object, &Class_LabelWidget)) { | 561 | iLabelWidget *label = i.object; |
562 | iLabelWidget *label = i.object; | 562 | updateSize_LabelWidget(label); |
563 | updateSize_LabelWidget(label); | ||
564 | } | ||
565 | } | 563 | } |
566 | /* Note that InputWidget uses the `tight` flag to adjust its inner padding. */ | ||
567 | /* TODO: Is this redundant? See `updateMetrics_Window_()`. */ | ||
568 | const int embedButtonWidth = width_Widget(findChild_Widget(navBar, "navbar.lock")); | ||
569 | setContentPadding_InputWidget(findChild_Widget(navBar, "url"), | ||
570 | embedButtonWidth * 0.75f, | ||
571 | embedButtonWidth * 0.75f); | ||
572 | } | 564 | } |
573 | if (isPhone) { | 565 | /* Note that InputWidget uses the `tight` flag to adjust its inner padding. */ |
574 | static const char *buttons[] = { "navbar.back", "navbar.forward", "navbar.sidebar", | 566 | /* TODO: Is this redundant? See `updateMetrics_Window_()`. */ |
575 | "navbar.ident", "navbar.home", "navbar.menu" }; | 567 | const int embedButtonWidth = width_Widget(findChild_Widget(navBar, "navbar.lock")); |
576 | iWidget *toolBar = findWidget_App("toolbar"); | 568 | setContentPadding_InputWidget(findChild_Widget(navBar, "url"), |
577 | setVisualOffset_Widget(toolBar, 0, 0, 0); | 569 | embedButtonWidth * 0.75f, |
578 | setFlags_Widget(toolBar, hidden_WidgetFlag, isLandscape_App()); | 570 | embedButtonWidth * 0.75f); |
579 | iForIndices(i, buttons) { | 571 | } |
580 | iLabelWidget *btn = findChild_Widget(navBar, buttons[i]); | 572 | if (isPhone) { |
581 | setFlags_Widget(as_Widget(btn), hidden_WidgetFlag, isPortrait_App()); | 573 | static const char *buttons[] = { "navbar.back", "navbar.forward", "navbar.sidebar", |
582 | if (isLandscape_App()) { | 574 | "navbar.ident", "navbar.home", "navbar.menu" }; |
583 | /* Collapsing sets size to zero and the label doesn't know when to update | 575 | iWidget *toolBar = findWidget_App("toolbar"); |
584 | its own size automatically. */ | 576 | setVisualOffset_Widget(toolBar, 0, 0, 0); |
585 | updateSize_LabelWidget(btn); | 577 | setFlags_Widget(toolBar, hidden_WidgetFlag, isLandscape_App()); |
586 | } | 578 | iForIndices(i, buttons) { |
579 | iLabelWidget *btn = findChild_Widget(navBar, buttons[i]); | ||
580 | setFlags_Widget(as_Widget(btn), hidden_WidgetFlag, isPortrait_App()); | ||
581 | if (isLandscape_App()) { | ||
582 | /* Collapsing sets size to zero and the label doesn't know when to update | ||
583 | its own size automatically. */ | ||
584 | updateSize_LabelWidget(btn); | ||
587 | } | 585 | } |
588 | arrange_Widget(navBar->root->widget); | ||
589 | } | 586 | } |
590 | /* Resize the URL input field. */ { | 587 | arrange_Widget(navBar->root->widget); |
591 | iWidget *urlBar = findChild_Widget(navBar, "url"); | 588 | } |
592 | urlBar->rect.size.x = iMini(navBarAvailableSpace_(navBar), 167 * gap_UI); | 589 | /* Resize the URL input field. */ { |
593 | arrange_Widget(navBar); | 590 | iWidget *urlBar = findChild_Widget(navBar, "url"); |
594 | } | 591 | urlBar->rect.size.x = iMini(navBarAvailableSpace_(navBar), 167 * gap_UI); |
595 | refresh_Widget(navBar); | 592 | arrange_Widget(navBar); |
596 | postCommand_Widget(navBar, "layout.changed id:navbar"); | 593 | } |
594 | refresh_Widget(navBar); | ||
595 | postCommand_Widget(navBar, "layout.changed id:navbar"); | ||
596 | } | ||
597 | |||
598 | static iBool handleNavBarCommands_(iWidget *navBar, const char *cmd) { | ||
599 | if (equal_Command(cmd, "window.resized") || equal_Command(cmd, "metrics.changed")) { | ||
600 | updateNavBarSize_(navBar); | ||
597 | return iFalse; | 601 | return iFalse; |
598 | } | 602 | } |
599 | else if (equal_Command(cmd, "window.reload.update")) { | 603 | else if (equal_Command(cmd, "window.reload.update")) { |
@@ -740,16 +744,18 @@ static iBool handleSearchBarCommands_(iWidget *searchBar, const char *cmd) { | |||
740 | else if (equal_Command(cmd, "focus.gained")) { | 744 | else if (equal_Command(cmd, "focus.gained")) { |
741 | if (pointer_Command(cmd) == findChild_Widget(searchBar, "find.input")) { | 745 | if (pointer_Command(cmd) == findChild_Widget(searchBar, "find.input")) { |
742 | if (!isVisible_Widget(searchBar)) { | 746 | if (!isVisible_Widget(searchBar)) { |
743 | setFlags_Widget(searchBar, hidden_WidgetFlag | disabled_WidgetFlag, iFalse); | 747 | // setFlags_Widget(searchBar, hidden_WidgetFlag | disabled_WidgetFlag, iFalse); |
744 | arrange_Widget(root_Widget(searchBar)); | 748 | // arrange_Widget(root_Widget(searchBar)); |
745 | postRefresh_App(); | 749 | // postRefresh_App(); |
750 | showCollapsed_Widget(searchBar, iTrue); | ||
746 | } | 751 | } |
747 | } | 752 | } |
748 | } | 753 | } |
749 | else if (equal_Command(cmd, "find.close")) { | 754 | else if (equal_Command(cmd, "find.close")) { |
750 | if (isVisible_Widget(searchBar)) { | 755 | if (isVisible_Widget(searchBar)) { |
751 | setFlags_Widget(searchBar, hidden_WidgetFlag | disabled_WidgetFlag, iTrue); | 756 | //setFlags_Widget(searchBar, hidden_WidgetFlag | disabled_WidgetFlag, iTrue); |
752 | arrange_Widget(searchBar->parent); | 757 | //arrange_Widget(searchBar->parent); |
758 | showCollapsed_Widget(searchBar, iFalse); | ||
753 | if (isFocused_Widget(findChild_Widget(searchBar, "find.input"))) { | 759 | if (isFocused_Widget(findChild_Widget(searchBar, "find.input"))) { |
754 | setFocus_Widget(NULL); | 760 | setFocus_Widget(NULL); |
755 | } | 761 | } |
@@ -886,6 +892,7 @@ void updateMetrics_Root(iRoot *d) { | |||
886 | 892 | ||
887 | void createUserInterface_Root(iRoot *d) { | 893 | void createUserInterface_Root(iRoot *d) { |
888 | iWidget *root = d->widget = new_Widget(); | 894 | iWidget *root = d->widget = new_Widget(); |
895 | root->rect.size = get_Window()->size; | ||
889 | iAssert(root->root == d); | 896 | iAssert(root->root == d); |
890 | setId_Widget(root, "root"); | 897 | setId_Widget(root, "root"); |
891 | /* Children of root cover the entire window. */ | 898 | /* Children of root cover the entire window. */ |
@@ -944,13 +951,14 @@ void createUserInterface_Root(iRoot *d) { | |||
944 | setBackgroundColor_Widget(winBar, uiBackground_ColorId); | 951 | setBackgroundColor_Widget(winBar, uiBackground_ColorId); |
945 | } | 952 | } |
946 | #endif | 953 | #endif |
954 | iWidget *navBar; | ||
947 | /* Navigation bar. */ { | 955 | /* Navigation bar. */ { |
948 | iWidget *navBar = new_Widget(); | 956 | navBar = new_Widget(); |
949 | setId_Widget(navBar, "navbar"); | 957 | setId_Widget(navBar, "navbar"); |
950 | setFlags_Widget(navBar, | 958 | setFlags_Widget(navBar, |
951 | hittable_WidgetFlag | /* context menu */ | 959 | hittable_WidgetFlag | /* context menu */ |
952 | arrangeHeight_WidgetFlag | | 960 | arrangeHeight_WidgetFlag | |
953 | resizeChildren_WidgetFlag | | 961 | resizeWidthOfChildren_WidgetFlag | |
954 | arrangeHorizontal_WidgetFlag | | 962 | arrangeHorizontal_WidgetFlag | |
955 | drawBackgroundToHorizontalSafeArea_WidgetFlag | | 963 | drawBackgroundToHorizontalSafeArea_WidgetFlag | |
956 | drawBackgroundToVerticalSafeArea_WidgetFlag, | 964 | drawBackgroundToVerticalSafeArea_WidgetFlag, |
@@ -958,7 +966,8 @@ void createUserInterface_Root(iRoot *d) { | |||
958 | addChild_Widget(div, iClob(navBar)); | 966 | addChild_Widget(div, iClob(navBar)); |
959 | setBackgroundColor_Widget(navBar, uiBackground_ColorId); | 967 | setBackgroundColor_Widget(navBar, uiBackground_ColorId); |
960 | setCommandHandler_Widget(navBar, handleNavBarCommands_); | 968 | setCommandHandler_Widget(navBar, handleNavBarCommands_); |
961 | setId_Widget(addChildFlags_Widget(navBar, iClob(newIcon_LabelWidget(backArrow_Icon, 0, 0, "navigate.back")), collapse_WidgetFlag), "navbar.back"); | 969 | iWidget *navBack; |
970 | setId_Widget(navBack = addChildFlags_Widget(navBar, iClob(newIcon_LabelWidget(backArrow_Icon, 0, 0, "navigate.back")), collapse_WidgetFlag), "navbar.back"); | ||
962 | setId_Widget(addChildFlags_Widget(navBar, iClob(newIcon_LabelWidget(forwardArrow_Icon, 0, 0, "navigate.forward")), collapse_WidgetFlag), "navbar.forward"); | 971 | setId_Widget(addChildFlags_Widget(navBar, iClob(newIcon_LabelWidget(forwardArrow_Icon, 0, 0, "navigate.forward")), collapse_WidgetFlag), "navbar.forward"); |
963 | /* Mobile devices have a button for easier access to the left sidebar. */ | 972 | /* Mobile devices have a button for easier access to the left sidebar. */ |
964 | if (deviceType_App() != desktop_AppDeviceType) { | 973 | if (deviceType_App() != desktop_AppDeviceType) { |
@@ -999,7 +1008,7 @@ void createUserInterface_Root(iRoot *d) { | |||
999 | setId_Widget(rightEmbed, "url.rightembed"); | 1008 | setId_Widget(rightEmbed, "url.rightembed"); |
1000 | addChildFlags_Widget(as_Widget(url), | 1009 | addChildFlags_Widget(as_Widget(url), |
1001 | iClob(rightEmbed), | 1010 | iClob(rightEmbed), |
1002 | arrangeHorizontal_WidgetFlag | arrangeSize_WidgetFlag | | 1011 | arrangeHorizontal_WidgetFlag | arrangeWidth_WidgetFlag | |
1003 | resizeHeightOfChildren_WidgetFlag | | 1012 | resizeHeightOfChildren_WidgetFlag | |
1004 | moveToParentRightEdge_WidgetFlag); | 1013 | moveToParentRightEdge_WidgetFlag); |
1005 | /* Feeds refresh indicator is inside the input field. */ { | 1014 | /* Feeds refresh indicator is inside the input field. */ { |
@@ -1132,8 +1141,8 @@ void createUserInterface_Root(iRoot *d) { | |||
1132 | iWidget *searchBar = new_Widget(); | 1141 | iWidget *searchBar = new_Widget(); |
1133 | setId_Widget(searchBar, "search"); | 1142 | setId_Widget(searchBar, "search"); |
1134 | setFlags_Widget(searchBar, | 1143 | setFlags_Widget(searchBar, |
1135 | hidden_WidgetFlag | disabled_WidgetFlag | collapse_WidgetFlag | | 1144 | hidden_WidgetFlag | disabledWhenHidden_WidgetFlag | collapse_WidgetFlag | |
1136 | arrangeHeight_WidgetFlag | resizeChildren_WidgetFlag | | 1145 | arrangeHeight_WidgetFlag | resizeWidthOfChildren_WidgetFlag | |
1137 | arrangeHorizontal_WidgetFlag, | 1146 | arrangeHorizontal_WidgetFlag, |
1138 | iTrue); | 1147 | iTrue); |
1139 | if (deviceType_App() == desktop_AppDeviceType) { | 1148 | if (deviceType_App() == desktop_AppDeviceType) { |
@@ -1270,6 +1279,7 @@ void createUserInterface_Root(iRoot *d) { | |||
1270 | addAction_Widget(root, SDLK_j, KMOD_PRIMARY, "splitmenu.open"); | 1279 | addAction_Widget(root, SDLK_j, KMOD_PRIMARY, "splitmenu.open"); |
1271 | } | 1280 | } |
1272 | updateMetrics_Root(d); | 1281 | updateMetrics_Root(d); |
1282 | updateNavBarSize_(navBar); | ||
1273 | } | 1283 | } |
1274 | 1284 | ||
1275 | void showToolbars_Root(iRoot *d, iBool show) { | 1285 | void showToolbars_Root(iRoot *d, iBool show) { |