summaryrefslogtreecommitdiff
path: root/src/ui
diff options
context:
space:
mode:
authorJaakko Keränen <jaakko.keranen@iki.fi>2020-11-14 12:40:17 +0200
committerJaakko Keränen <jaakko.keranen@iki.fi>2020-11-14 12:40:17 +0200
commitc9b1a0d3e42d27ec2786103ec3bc812a5d38da6c (patch)
tree5455f1354e4911d6a52a3ddfba2f405f48e0a1f8 /src/ui
parente093892eddf5481b310aac5d66b775d3e1c013cf (diff)
Navigating to parent directory or site root
Added keyboard shortcuts for navigating up to the parent directory and to the site root. Clicking the top banner also navigates to the site root. IssueID #29
Diffstat (limited to 'src/ui')
-rw-r--r--src/ui/documentwidget.c70
-rw-r--r--src/ui/keys.h4
-rw-r--r--src/ui/util.c6
-rw-r--r--src/ui/window.c4
4 files changed, 64 insertions, 20 deletions
diff --git a/src/ui/documentwidget.c b/src/ui/documentwidget.c
index c71758be..3fc7e841 100644
--- a/src/ui/documentwidget.c
+++ b/src/ui/documentwidget.c
@@ -225,6 +225,8 @@ void init_DocumentWidget(iDocumentWidget *d) {
225#endif 225#endif
226 addAction_Widget(w, navigateBack_KeyShortcut, "navigate.back"); 226 addAction_Widget(w, navigateBack_KeyShortcut, "navigate.back");
227 addAction_Widget(w, navigateForward_KeyShortcut, "navigate.forward"); 227 addAction_Widget(w, navigateForward_KeyShortcut, "navigate.forward");
228 addAction_Widget(w, navigateParent_KeyShortcut, "navigate.parent");
229 addAction_Widget(w, navigateRoot_KeyShortcut, "navigate.root");
228} 230}
229 231
230void deinit_DocumentWidget(iDocumentWidget *d) { 232void deinit_DocumentWidget(iDocumentWidget *d) {
@@ -259,13 +261,6 @@ static void requestUpdated_DocumentWidget_(iAnyObject *obj) {
259 } 261 }
260} 262}
261 263
262#if 0
263static void requestTimedOut_DocumentWidget_(iAnyObject *obj) {
264 iDocumentWidget *d = obj;
265 postCommandf_App("document.request.timeout doc:%p request:%p", d, d->request);
266}
267#endif
268
269static void requestFinished_DocumentWidget_(iAnyObject *obj) { 264static void requestFinished_DocumentWidget_(iAnyObject *obj) {
270 iDocumentWidget *d = obj; 265 iDocumentWidget *d = obj;
271 postCommand_Widget(obj, "document.request.finished doc:%p request:%p", d, d->request); 266 postCommand_Widget(obj, "document.request.finished doc:%p request:%p", d, d->request);
@@ -301,6 +296,16 @@ static iRect documentBounds_DocumentWidget_(const iDocumentWidget *d) {
301 return rect; 296 return rect;
302} 297}
303 298
299static iRect siteBannerRect_DocumentWidget_(const iDocumentWidget *d) {
300 const iGmRun *banner = siteBanner_GmDocument(d->doc);
301 if (!banner) {
302 return zero_Rect();
303 }
304 const iRect docBounds = documentBounds_DocumentWidget_(d);
305 const iInt2 origin = addY_I2(topLeft_Rect(docBounds), -value_Anim(&d->scrollY));
306 return moved_Rect(banner->visBounds, origin);
307}
308
304static int forceBreakWidth_DocumentWidget_(const iDocumentWidget *d) { 309static int forceBreakWidth_DocumentWidget_(const iDocumentWidget *d) {
305 if (equalCase_Rangecc(urlScheme_String(d->mod.url), "gopher")) { 310 if (equalCase_Rangecc(urlScheme_String(d->mod.url), "gopher")) {
306 return documentWidth_DocumentWidget_(d); 311 return documentWidth_DocumentWidget_(d);
@@ -1397,13 +1402,6 @@ static iBool handleCommand_DocumentWidget_(iDocumentWidget *d, const char *cmd)
1397 postCommandf_App("document.changed url:%s", cstr_String(d->mod.url)); 1402 postCommandf_App("document.changed url:%s", cstr_String(d->mod.url));
1398 return iFalse; 1403 return iFalse;
1399 } 1404 }
1400#if 0
1401 else if (equal_Command(cmd, "document.request.timeout") &&
1402 pointerLabel_Command(cmd, "request") == d->request) {
1403 cancel_GmRequest(d->request);
1404 return iFalse;
1405 }
1406#endif
1407 else if (equal_Command(cmd, "media.updated") || equal_Command(cmd, "media.finished")) { 1405 else if (equal_Command(cmd, "media.updated") || equal_Command(cmd, "media.finished")) {
1408 return handleMediaCommand_DocumentWidget_(d, cmd); 1406 return handleMediaCommand_DocumentWidget_(d, cmd);
1409 } 1407 }
@@ -1528,6 +1526,32 @@ static iBool handleCommand_DocumentWidget_(iDocumentWidget *d, const char *cmd)
1528 goForward_History(d->mod.history); 1526 goForward_History(d->mod.history);
1529 return iTrue; 1527 return iTrue;
1530 } 1528 }
1529 else if (equal_Command(cmd, "navigate.parent") && document_App() == d) {
1530 iUrl parts;
1531 init_Url(&parts, d->mod.url);
1532 /* Remove the last path segment. */
1533 if (size_Range(&parts.path) > 1) {
1534 if (parts.path.end[-1] == '/') {
1535 parts.path.end--;
1536 }
1537 while (parts.path.end > parts.path.start) {
1538 if (parts.path.end[-1] == '/') break;
1539 parts.path.end--;
1540 }
1541 postCommandf_App(
1542 "open url:%s",
1543 cstr_Rangecc((iRangecc){ constBegin_String(d->mod.url), parts.path.end }));
1544 }
1545 return iTrue;
1546 }
1547 else if (equal_Command(cmd, "navigate.root") && document_App() == d) {
1548 iUrl parts;
1549 init_Url(&parts, d->mod.url);
1550 postCommandf_App(
1551 "open url:%s/",
1552 cstr_Rangecc((iRangecc){ constBegin_String(d->mod.url), parts.path.start }));
1553 return iTrue;
1554 }
1531 else if (equalWidget_Command(cmd, w, "scroll.moved")) { 1555 else if (equalWidget_Command(cmd, w, "scroll.moved")) {
1532 init_Anim(&d->scrollY, arg_Command(cmd)); 1556 init_Anim(&d->scrollY, arg_Command(cmd));
1533 updateVisible_DocumentWidget_(d); 1557 updateVisible_DocumentWidget_(d);
@@ -1922,11 +1946,15 @@ static iBool processEvent_DocumentWidget_(iDocumentWidget *d, const SDL_Event *e
1922 } 1946 }
1923 else if (ev->type == SDL_MOUSEMOTION) { 1947 else if (ev->type == SDL_MOUSEMOTION) {
1924 iChangeFlags(d->flags, noHoverWhileScrolling_DocumentWidgetFlag, iFalse); 1948 iChangeFlags(d->flags, noHoverWhileScrolling_DocumentWidgetFlag, iFalse);
1949 const iInt2 mpos = init_I2(ev->motion.x, ev->motion.y);
1925 if (isVisible_Widget(d->menu)) { 1950 if (isVisible_Widget(d->menu)) {
1926 setCursor_Window(get_Window(), SDL_SYSTEM_CURSOR_ARROW); 1951 setCursor_Window(get_Window(), SDL_SYSTEM_CURSOR_ARROW);
1927 } 1952 }
1953 else if (contains_Rect(siteBannerRect_DocumentWidget_(d), mpos)) {
1954 setCursor_Window(get_Window(), SDL_SYSTEM_CURSOR_HAND);
1955 }
1928 else { 1956 else {
1929 updateHover_DocumentWidget_(d, init_I2(ev->motion.x, ev->motion.y)); 1957 updateHover_DocumentWidget_(d, mpos);
1930 } 1958 }
1931 updateOutlineOpacity_DocumentWidget_(d); 1959 updateOutlineOpacity_DocumentWidget_(d);
1932 } 1960 }
@@ -2006,11 +2034,13 @@ static iBool processEvent_DocumentWidget_(iDocumentWidget *d, const SDL_Event *e
2006 (iMenuItem[]){ 2034 (iMenuItem[]){
2007 { "Go Back", navigateBack_KeyShortcut, "navigate.back" }, 2035 { "Go Back", navigateBack_KeyShortcut, "navigate.back" },
2008 { "Go Forward", navigateForward_KeyShortcut, "navigate.forward" }, 2036 { "Go Forward", navigateForward_KeyShortcut, "navigate.forward" },
2037 { "Go to Parent", navigateParent_KeyShortcut, "navigate.parent" },
2038 { "Go to Root", navigateRoot_KeyShortcut, "navigate.root" },
2039 { "---", 0, 0, NULL },
2009 { "Reload Page", reload_KeyShortcut, "navigate.reload" }, 2040 { "Reload Page", reload_KeyShortcut, "navigate.reload" },
2010 { "---", 0, 0, NULL }, 2041 { "---", 0, 0, NULL },
2011 { "Copy Page URL", 0, 0, "document.copylink" }, 2042 { "Copy Page URL", 0, 0, "document.copylink" } },
2012 { "---", 0, 0, NULL } }, 2043 8);
2013 6);
2014 if (isEmpty_Range(&d->selectMark)) { 2044 if (isEmpty_Range(&d->selectMark)) {
2015 pushBackN_Array( 2045 pushBackN_Array(
2016 &items, 2046 &items,
@@ -2144,6 +2174,10 @@ static iBool processEvent_DocumentWidget_(iDocumentWidget *d, const SDL_Event *e
2144 d->selectMark = iNullRange; 2174 d->selectMark = iNullRange;
2145 refresh_Widget(w); 2175 refresh_Widget(w);
2146 } 2176 }
2177 /* Clicking on the top/side banner navigates to site root. */
2178 if (contains_Rect(siteBannerRect_DocumentWidget_(d), pos_Click(&d->click))) {
2179 postCommand_Widget(d, "navigate.root");
2180 }
2147 } 2181 }
2148 return iTrue; 2182 return iTrue;
2149 case double_ClickResult: 2183 case double_ClickResult:
diff --git a/src/ui/keys.h b/src/ui/keys.h
index a4c8f348..5bc9141c 100644
--- a/src/ui/keys.h
+++ b/src/ui/keys.h
@@ -32,6 +32,8 @@ SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. */
32# define nextTab_KeyShortcut SDLK_RIGHTBRACKET, KMOD_SHIFT | KMOD_PRIMARY 32# define nextTab_KeyShortcut SDLK_RIGHTBRACKET, KMOD_SHIFT | KMOD_PRIMARY
33# define navigateBack_KeyShortcut SDLK_LEFT, KMOD_PRIMARY 33# define navigateBack_KeyShortcut SDLK_LEFT, KMOD_PRIMARY
34# define navigateForward_KeyShortcut SDLK_RIGHT, KMOD_PRIMARY 34# define navigateForward_KeyShortcut SDLK_RIGHT, KMOD_PRIMARY
35# define navigateParent_KeyShortcut SDLK_UP, KMOD_PRIMARY
36# define navigateRoot_KeyShortcut SDLK_UP, KMOD_SHIFT | KMOD_PRIMARY
35# define byWord_KeyModifier KMOD_ALT 37# define byWord_KeyModifier KMOD_ALT
36# define byLine_KeyModifier KMOD_PRIMARY 38# define byLine_KeyModifier KMOD_PRIMARY
37#else 39#else
@@ -40,6 +42,8 @@ SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. */
40# define nextTab_KeyShortcut SDLK_PAGEDOWN, KMOD_PRIMARY 42# define nextTab_KeyShortcut SDLK_PAGEDOWN, KMOD_PRIMARY
41# define navigateBack_KeyShortcut SDLK_LEFT, KMOD_ALT 43# define navigateBack_KeyShortcut SDLK_LEFT, KMOD_ALT
42# define navigateForward_KeyShortcut SDLK_RIGHT, KMOD_ALT 44# define navigateForward_KeyShortcut SDLK_RIGHT, KMOD_ALT
45# define navigateParent_KeyShortcut SDLK_UP, KMOD_ALT
46# define navigateRoot_KeyShortcut SDLK_UP, KMOD_SHIFT | KMOD_ALT
43# define byWord_KeyModifier KMOD_CTRL 47# define byWord_KeyModifier KMOD_CTRL
44# define byLine_KeyModifier 0 48# define byLine_KeyModifier 0
45#endif 49#endif
diff --git a/src/ui/util.c b/src/ui/util.c
index ae3ddb18..bf044c03 100644
--- a/src/ui/util.c
+++ b/src/ui/util.c
@@ -92,6 +92,12 @@ void toString_Sym(int key, int kmods, iString *str) {
92 else if (key == SDLK_RIGHT) { 92 else if (key == SDLK_RIGHT) {
93 appendChar_String(str, 0x2192); 93 appendChar_String(str, 0x2192);
94 } 94 }
95 else if (key == SDLK_UP) {
96 appendChar_String(str, 0x2191);
97 }
98 else if (key == SDLK_DOWN) {
99 appendChar_String(str, 0x2193);
100 }
95 else if (key < 128 && (isalnum(key) || ispunct(key))) { 101 else if (key < 128 && (isalnum(key) || ispunct(key))) {
96 appendChar_String(str, upper_Char(key)); 102 appendChar_String(str, upper_Char(key));
97 } 103 }
diff --git a/src/ui/window.c b/src/ui/window.c
index 115dd04b..a69dd7db 100644
--- a/src/ui/window.c
+++ b/src/ui/window.c
@@ -146,6 +146,8 @@ static const iMenuItem viewMenuItems[] = {
146 { "---", 0, 0, NULL }, 146 { "---", 0, 0, NULL },
147 { "Go Back", SDLK_LEFTBRACKET, KMOD_PRIMARY, "navigate.back" }, 147 { "Go Back", SDLK_LEFTBRACKET, KMOD_PRIMARY, "navigate.back" },
148 { "Go Forward", SDLK_RIGHTBRACKET, KMOD_PRIMARY, "navigate.forward" }, 148 { "Go Forward", SDLK_RIGHTBRACKET, KMOD_PRIMARY, "navigate.forward" },
149 { "Go to Parent", navigateParent_KeyShortcut, "navigate.parent" },
150 { "Go to Root", navigateRoot_KeyShortcut, "navigate.root" },
149 { "Reload Page", reload_KeyShortcut, "navigate.reload" }, 151 { "Reload Page", reload_KeyShortcut, "navigate.reload" },
150 { "---", 0, 0, NULL }, 152 { "---", 0, 0, NULL },
151 { "Zoom In", SDLK_EQUALS, KMOD_PRIMARY, "zoom.delta arg:10" }, 153 { "Zoom In", SDLK_EQUALS, KMOD_PRIMARY, "zoom.delta arg:10" },
@@ -473,14 +475,12 @@ static void setupUserInterface_Window(iWindow *d) {
473 /* Global keyboard shortcuts. */ { 475 /* Global keyboard shortcuts. */ {
474 addAction_Widget(d->root, prevTab_KeyShortcut, "tabs.prev"); 476 addAction_Widget(d->root, prevTab_KeyShortcut, "tabs.prev");
475 addAction_Widget(d->root, nextTab_KeyShortcut, "tabs.next"); 477 addAction_Widget(d->root, nextTab_KeyShortcut, "tabs.next");
476#if !defined (iHaveNativeMenus)
477 addAction_Widget(d->root, 'l', KMOD_PRIMARY, "navigate.focus"); 478 addAction_Widget(d->root, 'l', KMOD_PRIMARY, "navigate.focus");
478 addAction_Widget(d->root, 'f', KMOD_PRIMARY, "focus.set id:find.input"); 479 addAction_Widget(d->root, 'f', KMOD_PRIMARY, "focus.set id:find.input");
479 addAction_Widget(d->root, '1', KMOD_PRIMARY, "sidebar.mode arg:0 toggle:1"); 480 addAction_Widget(d->root, '1', KMOD_PRIMARY, "sidebar.mode arg:0 toggle:1");
480 addAction_Widget(d->root, '2', KMOD_PRIMARY, "sidebar.mode arg:1 toggle:1"); 481 addAction_Widget(d->root, '2', KMOD_PRIMARY, "sidebar.mode arg:1 toggle:1");
481 addAction_Widget(d->root, '3', KMOD_PRIMARY, "sidebar.mode arg:2 toggle:1"); 482 addAction_Widget(d->root, '3', KMOD_PRIMARY, "sidebar.mode arg:2 toggle:1");
482 addAction_Widget(d->root, '4', KMOD_PRIMARY, "sidebar.mode arg:3 toggle:1"); 483 addAction_Widget(d->root, '4', KMOD_PRIMARY, "sidebar.mode arg:3 toggle:1");
483#endif
484 } 484 }
485} 485}
486 486