summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorDaniel Silverstone <dsilvers@digital-scurf.org>2019-08-03 17:13:17 +0100
committerDaniel Silverstone <dsilvers@digital-scurf.org>2019-08-03 17:14:14 +0100
commit1866f3a3d1fa710a84bf1ed9b948075156f10c7b (patch)
tree9dc2bd92c079bab0a360fbecd6c10a30555b279d
parenta1951f4c49a44783478c7000bd5ac5d349375488 (diff)
downloadnetsurf-1866f3a3d1fa710a84bf1ed9b948075156f10c7b.tar.gz
netsurf-1866f3a3d1fa710a84bf1ed9b948075156f10c7b.tar.bz2
local_history: Improve up/down navigation
When pressing up/down on a node when you can't go up/down the window will now search for a parent node which is a child of a branching point, and move to that and try again for the up/down movement. This makes it slightly more intuitive to move through the tree. Signed-off-by: Daniel Silverstone <dsilvers@digital-scurf.org>
-rw-r--r--desktop/local_history.c77
1 files changed, 67 insertions, 10 deletions
diff --git a/desktop/local_history.c b/desktop/local_history.c
index ddebbbe58..aa70ebb42 100644
--- a/desktop/local_history.c
+++ b/desktop/local_history.c
@@ -434,6 +434,36 @@ local_history_mouse_action(struct local_history_session *session,
return NSERROR_OK;
}
+/**
+ * Determine the point on the parent line where this history line branches.
+ *
+ * If `branch_point` gets set then there is a guarantee that (a) `ent` is
+ * a transitive child (forward) of that point. and (b) `branch_point` has a
+ * parent.
+ *
+ * \param[in] ent The entry to work backward from
+ * \param[out] branch_point The entry to set to the branch point if one is found
+ */
+static void
+_local_history_find_branch_point(struct history_entry *ent,
+ struct history_entry **branch_point)
+{
+ if (ent->back == NULL) {
+ /* We're at the root, nothing to do */
+ return;
+ }
+ /* Start from our immediate parent */
+ ent = ent->back;
+ while (ent->back != NULL) {
+ if (ent->back->forward != ent->back->forward_last) {
+ /* This point is a branch */
+ *branch_point = ent;
+ break;
+ }
+ ent = ent->back;
+ }
+}
+
/* exported interface documented in desktop/local_history.h */
bool
local_history_keypress(struct local_history_session *session, uint32_t key)
@@ -452,7 +482,7 @@ local_history_keypress(struct local_history_session *session, uint32_t key)
return true;
case NS_KEY_LEFT:
/* Go to parent */
- if (session->cursor->back) {
+ if (session->cursor->back != NULL) {
session->cursor = session->cursor->back;
local_history_scroll_to_cursor(session);
session->cw_t->invalidate(session->core_window_handle, NULL);
@@ -461,7 +491,7 @@ local_history_keypress(struct local_history_session *session, uint32_t key)
return true;
case NS_KEY_RIGHT:
/* Go to preferred child if there is one */
- if (session->cursor->forward_pref) {
+ if (session->cursor->forward_pref != NULL) {
session->cursor = session->cursor->forward_pref;
local_history_scroll_to_cursor(session);
session->cw_t->invalidate(session->core_window_handle, NULL);
@@ -470,25 +500,52 @@ local_history_keypress(struct local_history_session *session, uint32_t key)
return true;
case NS_KEY_DOWN:
/* Go to next sibling down, if there is one */
- if (session->cursor->next) {
+ if (session->cursor->next != NULL) {
session->cursor = session->cursor->next;
- local_history_scroll_to_cursor(session);
- session->cw_t->invalidate(session->core_window_handle, NULL);
+ } else {
+ struct history_entry *branch_point = NULL;
+ _local_history_find_branch_point(
+ session->cursor,
+ &branch_point);
+ if (branch_point != NULL) {
+ if (branch_point->next != NULL) {
+ branch_point = branch_point->next;
+ }
+ session->cursor = branch_point;
+ }
}
/* We have handled this keypress */
+ local_history_scroll_to_cursor(session);
+ session->cw_t->invalidate(session->core_window_handle, NULL);
return true;
case NS_KEY_UP:
/* Go to next sibling up, if there is one */
- if (session->cursor->back) {
+ if (session->cursor->back != NULL) {
struct history_entry *ent = session->cursor->back->forward;
- while (ent->next != NULL && ent->next != session->cursor) {
+ while (ent != session->cursor &&
+ ent->next != NULL &&
+ ent->next != session->cursor) {
ent = ent->next;
}
- session->cursor = ent;
- local_history_scroll_to_cursor(session);
- session->cw_t->invalidate(session->core_window_handle, NULL);
+ if (session->cursor != ent) {
+ session->cursor = ent;
+ } else {
+ struct history_entry *branch_point = NULL;
+ _local_history_find_branch_point(
+ session->cursor,
+ &branch_point);
+ if (branch_point != NULL) {
+ struct history_entry *ent = branch_point->back->forward;
+ while (ent->next != NULL && ent->next != branch_point) {
+ ent = ent->next;
+ }
+ session->cursor = ent;
+ }
+ }
}
/* We have handled this keypress */
+ local_history_scroll_to_cursor(session);
+ session->cw_t->invalidate(session->core_window_handle, NULL);
return true;
}
return false;