diff options
author | Jaakko Keränen <jaakko.keranen@iki.fi> | 2020-11-14 12:40:17 +0200 |
---|---|---|
committer | Jaakko Keränen <jaakko.keranen@iki.fi> | 2020-11-14 12:40:17 +0200 |
commit | c9b1a0d3e42d27ec2786103ec3bc812a5d38da6c (patch) | |
tree | 5455f1354e4911d6a52a3ddfba2f405f48e0a1f8 /src/ui | |
parent | e093892eddf5481b310aac5d66b775d3e1c013cf (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.c | 70 | ||||
-rw-r--r-- | src/ui/keys.h | 4 | ||||
-rw-r--r-- | src/ui/util.c | 6 | ||||
-rw-r--r-- | src/ui/window.c | 4 |
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 | ||
230 | void deinit_DocumentWidget(iDocumentWidget *d) { | 232 | void deinit_DocumentWidget(iDocumentWidget *d) { |
@@ -259,13 +261,6 @@ static void requestUpdated_DocumentWidget_(iAnyObject *obj) { | |||
259 | } | 261 | } |
260 | } | 262 | } |
261 | 263 | ||
262 | #if 0 | ||
263 | static 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 | |||
269 | static void requestFinished_DocumentWidget_(iAnyObject *obj) { | 264 | static 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 | ||
299 | static 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 | |||
304 | static int forceBreakWidth_DocumentWidget_(const iDocumentWidget *d) { | 309 | static 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 | ||