diff options
author | Jaakko Keränen <jaakko.keranen@iki.fi> | 2021-03-12 20:03:21 +0200 |
---|---|---|
committer | Jaakko Keränen <jaakko.keranen@iki.fi> | 2021-03-12 20:05:46 +0200 |
commit | 088eb5f137c38bdcde4fc2e80fd40cf7c07fce9b (patch) | |
tree | 7b08fd3df1fb8f9efd0865b3d9fc49a38b3ad7f3 /src/ui | |
parent | 9d73378d21f4644bf0e39fb09025553a0fff7cc4 (diff) |
Window: Embed reload button; sidebar context menu
Diffstat (limited to 'src/ui')
-rw-r--r-- | src/ui/widget.c | 11 | ||||
-rw-r--r-- | src/ui/widget.h | 1 | ||||
-rw-r--r-- | src/ui/window.c | 103 |
3 files changed, 83 insertions, 32 deletions
diff --git a/src/ui/widget.c b/src/ui/widget.c index e9a162e3..4d2728b7 100644 --- a/src/ui/widget.c +++ b/src/ui/widget.c | |||
@@ -972,9 +972,9 @@ iAny *hitChild_Widget(const iWidget *d, iInt2 coord) { | |||
972 | if (found) return found; | 972 | if (found) return found; |
973 | } | 973 | } |
974 | } | 974 | } |
975 | if ((d->flags & overflowScrollable_WidgetFlag || class_Widget(d) != &Class_Widget || | 975 | if ((d->flags & (overflowScrollable_WidgetFlag | hittable_WidgetFlag) || |
976 | d->flags & mouseModal_WidgetFlag) && ~d->flags & unhittable_WidgetFlag && | 976 | class_Widget(d) != &Class_Widget || d->flags & mouseModal_WidgetFlag) && |
977 | contains_Widget(d, coord)) { | 977 | ~d->flags & unhittable_WidgetFlag && contains_Widget(d, coord)) { |
978 | return iConstCast(iWidget *, d); | 978 | return iConstCast(iWidget *, d); |
979 | } | 979 | } |
980 | return NULL; | 980 | return NULL; |
@@ -1199,8 +1199,9 @@ static void printTree_Widget_(const iWidget *d, int indent) { | |||
1199 | cstr_String(text_LabelWidget((const iLabelWidget *) d)), | 1199 | cstr_String(text_LabelWidget((const iLabelWidget *) d)), |
1200 | cstr_String(command_LabelWidget((const iLabelWidget *) d))); | 1200 | cstr_String(command_LabelWidget((const iLabelWidget *) d))); |
1201 | } | 1201 | } |
1202 | printf("size:%dx%d flags:%08llx\n", d->rect.size.x, d->rect.size.y, | 1202 | printf("size:%dx%d [%d..%d %d:%d] flags:%08llx%s\n", d->rect.size.x, d->rect.size.y, |
1203 | (long long unsigned int) d->flags); | 1203 | d->padding[0], d->padding[2], d->padding[1], d->padding[3], |
1204 | (long long unsigned int) d->flags, d->flags & tight_WidgetFlag ? " tight" : ""); | ||
1204 | iConstForEach(ObjectList, i, d->children) { | 1205 | iConstForEach(ObjectList, i, d->children) { |
1205 | printTree_Widget_(i.object, indent + 1); | 1206 | printTree_Widget_(i.object, indent + 1); |
1206 | } | 1207 | } |
diff --git a/src/ui/widget.h b/src/ui/widget.h index 94a2d4a1..37c8efdc 100644 --- a/src/ui/widget.h +++ b/src/ui/widget.h | |||
@@ -107,6 +107,7 @@ enum iWidgetFlag { | |||
107 | #define chevron_WidgetFlag iBit64(52) | 107 | #define chevron_WidgetFlag iBit64(52) |
108 | #define drawBackgroundToBottom_WidgetFlag iBit64(53) | 108 | #define drawBackgroundToBottom_WidgetFlag iBit64(53) |
109 | #define dragged_WidgetFlag iBit64(54) | 109 | #define dragged_WidgetFlag iBit64(54) |
110 | #define hittable_WidgetFlag iBit64(55) | ||
110 | 111 | ||
111 | enum iWidgetAddPos { | 112 | enum iWidgetAddPos { |
112 | back_WidgetAddPos, | 113 | back_WidgetAddPos, |
diff --git a/src/ui/window.c b/src/ui/window.c index 2f7a2988..16f217a3 100644 --- a/src/ui/window.c +++ b/src/ui/window.c | |||
@@ -86,6 +86,26 @@ static iBool handleRootCommands_(iWidget *root, const char *cmd) { | |||
86 | } | 86 | } |
87 | return iTrue; | 87 | return iTrue; |
88 | } | 88 | } |
89 | else if (equal_Command(cmd, "contextclick")) { | ||
90 | iBool showBarMenu = iFalse; | ||
91 | if (equal_Rangecc(range_Command(cmd, "id"), "buttons")) { | ||
92 | const iWidget *sidebar = findWidget_App("sidebar"); | ||
93 | const iWidget *sidebar2 = findWidget_App("sidebar2"); | ||
94 | const iWidget *buttons = pointer_Command(cmd); | ||
95 | if (hasParent_Widget(buttons, sidebar) || | ||
96 | hasParent_Widget(buttons, sidebar2)) { | ||
97 | showBarMenu = iTrue; | ||
98 | } | ||
99 | } | ||
100 | if (equal_Rangecc(range_Command(cmd, "id"), "navbar")) { | ||
101 | showBarMenu = iTrue; | ||
102 | } | ||
103 | if (showBarMenu) { | ||
104 | openMenu_Widget(findWidget_App("barmenu"), coord_Command(cmd)); | ||
105 | return iTrue; | ||
106 | } | ||
107 | return iFalse; | ||
108 | } | ||
89 | else if (equal_Command(cmd, "focus.set")) { | 109 | else if (equal_Command(cmd, "focus.set")) { |
90 | setFocus_Widget(findWidget_App(cstr_Rangecc(range_Command(cmd, "id")))); | 110 | setFocus_Widget(findWidget_App(cstr_Rangecc(range_Command(cmd, "id")))); |
91 | return iTrue; | 111 | return iTrue; |
@@ -495,8 +515,9 @@ static iBool willPerformSearchQuery_(const iString *userInput) { | |||
495 | static void showSearchQueryIndicator_(iBool show) { | 515 | static void showSearchQueryIndicator_(iBool show) { |
496 | iWidget *indicator = findWidget_App("input.indicator.search"); | 516 | iWidget *indicator = findWidget_App("input.indicator.search"); |
497 | setFlags_Widget(indicator, hidden_WidgetFlag, !show); | 517 | setFlags_Widget(indicator, hidden_WidgetFlag, !show); |
498 | setContentPadding_InputWidget( | 518 | iInputWidget *url = (iInputWidget *) parent_Widget(indicator); |
499 | (iInputWidget *) parent_Widget(indicator), -1, show ? width_Widget(indicator) : 0); | 519 | setContentPadding_InputWidget(url, -1, contentPadding_InputWidget(url).left + |
520 | (show ? width_Widget(indicator) : 0)); | ||
500 | } | 521 | } |
501 | 522 | ||
502 | static int navBarAvailableSpace_(iWidget *navBar) { | 523 | static int navBarAvailableSpace_(iWidget *navBar) { |
@@ -527,17 +548,18 @@ static iBool handleNavBarCommands_(iWidget *navBar, const char *cmd) { | |||
527 | setFlags_Widget(navBar, tight_WidgetFlag, isNarrow); | 548 | setFlags_Widget(navBar, tight_WidgetFlag, isNarrow); |
528 | iForEach(ObjectList, i, navBar->children) { | 549 | iForEach(ObjectList, i, navBar->children) { |
529 | iWidget *child = as_Widget(i.object); | 550 | iWidget *child = as_Widget(i.object); |
530 | setFlags_Widget( | 551 | setFlags_Widget(child, tight_WidgetFlag, isNarrow); |
531 | child, tight_WidgetFlag, isNarrow); | ||
532 | if (isInstance_Object(i.object, &Class_LabelWidget)) { | 552 | if (isInstance_Object(i.object, &Class_LabelWidget)) { |
533 | iLabelWidget *label = i.object; | 553 | iLabelWidget *label = i.object; |
534 | updateSize_LabelWidget(label); | 554 | updateSize_LabelWidget(label); |
535 | } | 555 | } |
536 | } | 556 | } |
537 | /* Note that InputWidget uses the `tight` flag to adjust its inner padding. */ | 557 | /* Note that InputWidget uses the `tight` flag to adjust its inner padding. */ |
558 | /* TODO: Is this redundant? See `updateMetrics_Window_()`. */ | ||
559 | const int embedButtonWidth = width_Widget(findChild_Widget(navBar, "navbar.lock")); | ||
538 | setContentPadding_InputWidget(findChild_Widget(navBar, "url"), | 560 | setContentPadding_InputWidget(findChild_Widget(navBar, "url"), |
539 | width_Widget(findChild_Widget(navBar, "navbar.lock")) * 0.75, | 561 | embedButtonWidth * 0.75f, |
540 | -1); | 562 | embedButtonWidth * 0.75f); |
541 | } | 563 | } |
542 | if (isPhone) { | 564 | if (isPhone) { |
543 | static const char *buttons[] = { | 565 | static const char *buttons[] = { |
@@ -559,6 +581,7 @@ static iBool handleNavBarCommands_(iWidget *navBar, const char *cmd) { | |||
559 | iWidget *urlBar = findChild_Widget(navBar, "url"); | 581 | iWidget *urlBar = findChild_Widget(navBar, "url"); |
560 | urlBar->rect.size.x = iMini(navBarAvailableSpace_(navBar), 167 * gap_UI); | 582 | urlBar->rect.size.x = iMini(navBarAvailableSpace_(navBar), 167 * gap_UI); |
561 | arrange_Widget(navBar); | 583 | arrange_Widget(navBar); |
584 | printTree_Widget(urlBar); | ||
562 | } | 585 | } |
563 | refresh_Widget(navBar); | 586 | refresh_Widget(navBar); |
564 | postCommand_Widget(navBar, "layout.changed id:navbar"); | 587 | postCommand_Widget(navBar, "layout.changed id:navbar"); |
@@ -833,10 +856,11 @@ static void updateMetrics_Window_(iWindow *d) { | |||
833 | iWidget *fprog = findChild_Widget(navBar, "feeds.progress"); | 856 | iWidget *fprog = findChild_Widget(navBar, "feeds.progress"); |
834 | iWidget *docProg = findChild_Widget(navBar, "document.progress"); | 857 | iWidget *docProg = findChild_Widget(navBar, "document.progress"); |
835 | iWidget *indSearch = findChild_Widget(navBar, "input.indicator.search"); | 858 | iWidget *indSearch = findChild_Widget(navBar, "input.indicator.search"); |
836 | setPadding_Widget(as_Widget(url), 0, gap_UI, gap_UI, gap_UI); | 859 | setPadding_Widget(as_Widget(url), 0, gap_UI, 0, gap_UI); |
837 | navBar->rect.size.y = 0; /* recalculate height based on children (FIXME: shouldn't be needed) */ | 860 | navBar->rect.size.y = 0; /* recalculate height based on children (FIXME: shouldn't be needed) */ |
838 | updateSize_LabelWidget((iLabelWidget *) lock); | 861 | updateSize_LabelWidget((iLabelWidget *) lock); |
839 | setContentPadding_InputWidget((iInputWidget *) url, width_Widget(lock) * 0.75, -1); | 862 | setContentPadding_InputWidget((iInputWidget *) url, width_Widget(lock) * 0.75, |
863 | width_Widget(lock) * 0.75); | ||
840 | fprog->rect.pos.y = gap_UI; | 864 | fprog->rect.pos.y = gap_UI; |
841 | docProg->rect.pos.y = gap_UI; | 865 | docProg->rect.pos.y = gap_UI; |
842 | indSearch->rect.pos.y = gap_UI; | 866 | indSearch->rect.pos.y = gap_UI; |
@@ -909,6 +933,7 @@ static void setupUserInterface_Window(iWindow *d) { | |||
909 | iWidget *navBar = new_Widget(); | 933 | iWidget *navBar = new_Widget(); |
910 | setId_Widget(navBar, "navbar"); | 934 | setId_Widget(navBar, "navbar"); |
911 | setFlags_Widget(navBar, | 935 | setFlags_Widget(navBar, |
936 | hittable_WidgetFlag | /* context menu */ | ||
912 | arrangeHeight_WidgetFlag | | 937 | arrangeHeight_WidgetFlag | |
913 | resizeChildren_WidgetFlag | | 938 | resizeChildren_WidgetFlag | |
914 | arrangeHorizontal_WidgetFlag | | 939 | arrangeHorizontal_WidgetFlag | |
@@ -925,8 +950,9 @@ static void setupUserInterface_Window(iWindow *d) { | |||
925 | "\U0001f464", identityButtonMenuItems_, iElemCount(identityButtonMenuItems_)); | 950 | "\U0001f464", identityButtonMenuItems_, iElemCount(identityButtonMenuItems_)); |
926 | setAlignVisually_LabelWidget(idMenu, iTrue); | 951 | setAlignVisually_LabelWidget(idMenu, iTrue); |
927 | setId_Widget(addChildFlags_Widget(navBar, iClob(idMenu), collapse_WidgetFlag), "navbar.ident"); | 952 | setId_Widget(addChildFlags_Widget(navBar, iClob(idMenu), collapse_WidgetFlag), "navbar.ident"); |
953 | iInputWidget *url; | ||
928 | /* URL input field. */ { | 954 | /* URL input field. */ { |
929 | iInputWidget *url = new_InputWidget(0); | 955 | url = new_InputWidget(0); |
930 | setFlags_Widget(as_Widget(url), resizeHeightOfChildren_WidgetFlag, iTrue); | 956 | setFlags_Widget(as_Widget(url), resizeHeightOfChildren_WidgetFlag, iTrue); |
931 | setSelectAllOnFocus_InputWidget(url, iTrue); | 957 | setSelectAllOnFocus_InputWidget(url, iTrue); |
932 | setId_Widget(as_Widget(url), "url"); | 958 | setId_Widget(as_Widget(url), "url"); |
@@ -934,13 +960,14 @@ static void setupUserInterface_Window(iWindow *d) { | |||
934 | setNotifyEdits_InputWidget(url, iTrue); | 960 | setNotifyEdits_InputWidget(url, iTrue); |
935 | setTextCStr_InputWidget(url, "gemini://"); | 961 | setTextCStr_InputWidget(url, "gemini://"); |
936 | addChildFlags_Widget(navBar, iClob(url), 0); | 962 | addChildFlags_Widget(navBar, iClob(url), 0); |
963 | const int64_t embedFlags = | ||
964 | noBackground_WidgetFlag | frameless_WidgetFlag | unpadded_WidgetFlag | | ||
965 | (deviceType_App() == desktop_AppDeviceType ? tight_WidgetFlag : 0); | ||
937 | /* Page information/certificate warning. */ { | 966 | /* Page information/certificate warning. */ { |
938 | iLabelWidget *lock = | 967 | iLabelWidget *lock = |
939 | addChildFlags_Widget(as_Widget(url), | 968 | addChildFlags_Widget(as_Widget(url), |
940 | iClob(newIcon_LabelWidget("\U0001f513", SDLK_i, KMOD_PRIMARY, "document.info")), | 969 | iClob(newIcon_LabelWidget("\U0001f513", SDLK_i, KMOD_PRIMARY, "document.info")), |
941 | noBackground_WidgetFlag | frameless_WidgetFlag | moveToParentLeftEdge_WidgetFlag | | 970 | embedFlags | moveToParentLeftEdge_WidgetFlag); |
942 | unpadded_WidgetFlag | | ||
943 | (deviceType_App() == desktop_AppDeviceType ? tight_WidgetFlag : 0)); | ||
944 | setId_Widget(as_Widget(lock), "navbar.lock"); | 971 | setId_Widget(as_Widget(lock), "navbar.lock"); |
945 | setFont_LabelWidget(lock, defaultSymbols_FontId); | 972 | setFont_LabelWidget(lock, defaultSymbols_FontId); |
946 | updateTextCStr_LabelWidget(lock, "\U0001f512"); | 973 | updateTextCStr_LabelWidget(lock, "\U0001f512"); |
@@ -979,10 +1006,12 @@ static void setupUserInterface_Window(iWindow *d) { | |||
979 | iClob(queryInd), | 1006 | iClob(queryInd), |
980 | moveToParentRightEdge_WidgetFlag | hidden_WidgetFlag); | 1007 | moveToParentRightEdge_WidgetFlag | hidden_WidgetFlag); |
981 | } | 1008 | } |
1009 | /* Reload button. */ | ||
1010 | iLabelWidget *reload = newIcon_LabelWidget(reloadCStr_, 0, 0, "navigate.reload"); | ||
1011 | setId_Widget(as_Widget(reload), "reload"); | ||
1012 | addChildFlags_Widget(as_Widget(url), iClob(reload), embedFlags | moveToParentRightEdge_WidgetFlag); | ||
1013 | updateSize_LabelWidget(reload); | ||
982 | } | 1014 | } |
983 | setId_Widget(addChild_Widget( | ||
984 | navBar, iClob(newIcon_LabelWidget(reloadCStr_, 0, 0, "navigate.reload"))), | ||
985 | "reload"); | ||
986 | addChildFlags_Widget(navBar, iClob(new_Widget()), expand_WidgetFlag); | 1015 | addChildFlags_Widget(navBar, iClob(new_Widget()), expand_WidgetFlag); |
987 | setId_Widget(addChildFlags_Widget(navBar, | 1016 | setId_Widget(addChildFlags_Widget(navBar, |
988 | iClob(newIcon_LabelWidget( | 1017 | iClob(newIcon_LabelWidget( |
@@ -1028,7 +1057,7 @@ static void setupUserInterface_Window(iWindow *d) { | |||
1028 | addChild_Widget(buttons, iClob(newIcon_LabelWidget(add_Icon, 0, 0, "tabs.new"))), | 1057 | addChild_Widget(buttons, iClob(newIcon_LabelWidget(add_Icon, 0, 0, "tabs.new"))), |
1029 | "newtab"); | 1058 | "newtab"); |
1030 | } | 1059 | } |
1031 | /* Side bars. */ { | 1060 | /* Sidebars. */ { |
1032 | iWidget *content = findChild_Widget(d->root, "tabs.content"); | 1061 | iWidget *content = findChild_Widget(d->root, "tabs.content"); |
1033 | iSidebarWidget *sidebar1 = new_SidebarWidget(left_SideBarSide); | 1062 | iSidebarWidget *sidebar1 = new_SidebarWidget(left_SideBarSide); |
1034 | addChildPos_Widget(content, iClob(sidebar1), front_WidgetAddPos); | 1063 | addChildPos_Widget(content, iClob(sidebar1), front_WidgetAddPos); |
@@ -1105,17 +1134,25 @@ static void setupUserInterface_Window(iWindow *d) { | |||
1105 | } | 1134 | } |
1106 | #endif | 1135 | #endif |
1107 | updatePadding_Window_(d); | 1136 | updatePadding_Window_(d); |
1108 | iWidget *tabsMenu = makeMenu_Widget(d->root, | 1137 | /* Context menus. */ { |
1109 | (iMenuItem[]){ | 1138 | iWidget *tabsMenu = makeMenu_Widget(d->root, |
1110 | { close_Icon " Close Tab", 0, 0, "tabs.close" }, | 1139 | (iMenuItem[]){ |
1111 | { copy_Icon " Duplicate Tab", 0, 0, "tabs.new duplicate:1" }, | 1140 | { close_Icon " Close Tab", 0, 0, "tabs.close" }, |
1112 | { "---", 0, 0, NULL }, | 1141 | { copy_Icon " Duplicate Tab", 0, 0, "tabs.new duplicate:1" }, |
1113 | { "Close Other Tabs", 0, 0, "tabs.close toleft:1 toright:1" }, | 1142 | { "---", 0, 0, NULL }, |
1114 | { barLeftArrow_Icon " Close Tabs To Left", 0, 0, "tabs.close toleft:1" }, | 1143 | { "Close Other Tabs", 0, 0, "tabs.close toleft:1 toright:1" }, |
1115 | { barRightArrow_Icon " Close Tabs To Right", 0, 0, "tabs.close toright:1" }, | 1144 | { barLeftArrow_Icon " Close Tabs To Left", 0, 0, "tabs.close toleft:1" }, |
1116 | }, | 1145 | { barRightArrow_Icon " Close Tabs To Right", 0, 0, "tabs.close toright:1" }, |
1117 | 6); | 1146 | }, |
1118 | setId_Widget(tabsMenu, "doctabs.menu"); | 1147 | 6); |
1148 | setId_Widget(tabsMenu, "doctabs.menu"); | ||
1149 | iWidget *barMenu = makeMenu_Widget(d->root, | ||
1150 | (iMenuItem[]) { | ||
1151 | { "Toggle Left Sidebar", 0, 0, "sidebar.toggle" }, | ||
1152 | { "Toggle Right Sidebar", 0, 0, "sidebar2.toggle" }, | ||
1153 | }, 2); | ||
1154 | setId_Widget(barMenu, "barmenu"); | ||
1155 | } | ||
1119 | /* Global keyboard shortcuts. */ { | 1156 | /* Global keyboard shortcuts. */ { |
1120 | addAction_Widget(d->root, 'l', KMOD_PRIMARY, "navigate.focus"); | 1157 | addAction_Widget(d->root, 'l', KMOD_PRIMARY, "navigate.focus"); |
1121 | addAction_Widget(d->root, 'f', KMOD_PRIMARY, "focus.set id:find.input"); | 1158 | addAction_Widget(d->root, 'f', KMOD_PRIMARY, "focus.set id:find.input"); |
@@ -1695,6 +1732,18 @@ iBool processEvent_Window(iWindow *d, const SDL_Event *ev) { | |||
1695 | paste.key.timestamp = SDL_GetTicks(); | 1732 | paste.key.timestamp = SDL_GetTicks(); |
1696 | wasUsed = dispatchEvent_Widget(widget, &paste); | 1733 | wasUsed = dispatchEvent_Widget(widget, &paste); |
1697 | } | 1734 | } |
1735 | if (event.type == SDL_MOUSEBUTTONDOWN && event.button.button == SDL_BUTTON_RIGHT) { | ||
1736 | /* A context menu may still get triggered here. */ | ||
1737 | const iWidget *hit = hitChild_Widget(d->root, init_I2(event.button.x, event.button.y)); | ||
1738 | while (hit && isEmpty_String(id_Widget(hit))) { | ||
1739 | hit = parent_Widget(hit); | ||
1740 | } | ||
1741 | if (hit) { | ||
1742 | postCommandf_App("contextclick id:%s ptr:%p coord:%d %d", | ||
1743 | cstr_String(id_Widget(hit)), hit, | ||
1744 | event.button.x, event.button.y); | ||
1745 | } | ||
1746 | } | ||
1698 | } | 1747 | } |
1699 | if (isMetricsChange_UserEvent(&event)) { | 1748 | if (isMetricsChange_UserEvent(&event)) { |
1700 | updateMetrics_Window_(d); | 1749 | updateMetrics_Window_(d); |