diff options
author | Simon Howard | 2009-08-27 23:27:47 +0000 |
---|---|---|
committer | Simon Howard | 2009-08-27 23:27:47 +0000 |
commit | ec81c27ef5af20761afb2295cdd7c92b213a5807 (patch) | |
tree | fb106b5be3eb95ccfba5f39d498ea301cee910f3 /textscreen | |
parent | 1715116ef17946f1c77fb2da220384e7889f1329 (diff) | |
download | chocolate-doom-ec81c27ef5af20761afb2295cdd7c92b213a5807.tar.gz chocolate-doom-ec81c27ef5af20761afb2295cdd7c92b213a5807.tar.bz2 chocolate-doom-ec81c27ef5af20761afb2295cdd7c92b213a5807.zip |
Allow PGUP/PGDN to scroll up and down in scroll panes (thanks
LionsPhil).
Subversion-branch: /trunk/chocolate-doom
Subversion-revision: 1631
Diffstat (limited to 'textscreen')
-rw-r--r-- | textscreen/txt_scrollpane.c | 76 | ||||
-rw-r--r-- | textscreen/txt_table.c | 82 | ||||
-rw-r--r-- | textscreen/txt_table.h | 13 |
3 files changed, 170 insertions, 1 deletions
diff --git a/textscreen/txt_scrollpane.c b/textscreen/txt_scrollpane.c index ef6e4fb3..d81cce4b 100644 --- a/textscreen/txt_scrollpane.c +++ b/textscreen/txt_scrollpane.c @@ -254,10 +254,53 @@ static void ShowSelectedWidget(txt_scrollpane_t *scrollpane) } } +// Another hack for tables - when scrolling in 'pages', the normal key press +// event does not provide children with enough information to know how far +// to move their selection to reach a new page. This function does so. +// Note that it *only* affects scrolling in pages, not with arrows! +// A side-effect of this, rather than 'pulling' the selection to fit within +// the new page, is that we will jump straight over ranges of unselectable +// items longer than a page, but that is also true of arrow-key scrolling. +// The other unfortunate effect of doing things this way is that page keys +// have no effect on tables _not_ in scrollpanes: not even home/end. + +static int PageSelectedWidget(txt_scrollpane_t *scrollpane, int key) +{ + int pagex = 0; // No page left/right yet, but some keyboards have them + int pagey = 0; + + // Subtract one from the absolute page distance as this is slightly more + // intuitive: a page down first jumps to the bottom of the current page, + // then proceeds to scroll onwards. + + switch (key) + { + case KEY_PGUP: + pagey = 1 - scrollpane->h; + break; + + case KEY_PGDN: + pagey = scrollpane->h - 1; + break; + + default: // We shouldn't even be in this function + return 0; + } + + if (scrollpane->child->widget_class == &txt_table_class) + { + return TXT_PageTable(scrollpane->child, pagex, pagey); + } + + return 0; +} + // Interpret arrow key presses as scroll commands static int InterpretScrollKey(txt_scrollpane_t *scrollpane, int key) { + int maxy; + switch (key) { case KEY_UPARROW: @@ -292,6 +335,31 @@ static int InterpretScrollKey(txt_scrollpane_t *scrollpane, int key) } break; + case KEY_PGUP: + if (scrollpane->y > 0) + { + scrollpane->y -= scrollpane->h; + if (scrollpane->y < 0) + { + scrollpane->y = 0; + } + return 1; + } + break; + + case KEY_PGDN: + maxy = FullHeight(scrollpane) - scrollpane->h; + if (scrollpane->y < maxy) + { + scrollpane->y += scrollpane->h; + if (scrollpane->y > maxy) + { + scrollpane->y = maxy; + } + return 1; + } + break; + default: break; } @@ -316,8 +384,14 @@ static int TXT_ScrollPaneKeyPress(TXT_UNCAST_ARG(scrollpane), int key) if (scrollpane->child->widget_class == &txt_table_class && (key == KEY_UPARROW || key == KEY_DOWNARROW - || key == KEY_LEFTARROW || key == KEY_RIGHTARROW)) + || key == KEY_LEFTARROW || key == KEY_RIGHTARROW + || key == KEY_PGUP || key == KEY_PGDN)) { + if (PageSelectedWidget(scrollpane, key)) + { + result = 1; + } + ShowSelectedWidget(scrollpane); } diff --git a/textscreen/txt_table.c b/textscreen/txt_table.c index 0d4d1e35..1b432681 100644 --- a/textscreen/txt_table.c +++ b/textscreen/txt_table.c @@ -770,3 +770,85 @@ void TXT_SetColumnWidths(TXT_UNCAST_ARG(table), ...) va_end(args); } +// Moves the select by at least the given number of characters. +// Currently quietly ignores pagex, as we don't use it. + +int TXT_PageTable(TXT_UNCAST_ARG(table), int pagex, int pagey) +{ + TXT_CAST_ARG(txt_table_t, table); + unsigned int *column_widths; + unsigned int *row_heights; + int rows; + int changed = 0; + + rows = TableRows(table); + + row_heights = malloc(sizeof(int) * rows); + column_widths = malloc(sizeof(int) * table->columns); + + CalcRowColSizes(table, row_heights, column_widths); + + if (pagex) + { + // @todo Jump selection to the left or right as needed + } + + if (pagey) + { + int new_x, new_y; + int distance = 0; + int dir; + + // What direction are we moving? + + if (pagey > 0) + { + dir = 1; + } + else + { + dir = -1; + } + + // Move the cursor until the desired distance is reached. + + new_y = table->selected_y; + + while (new_y >= 0 && new_y < rows) + { + // We are about to travel a distance equal to the height of the row + // we are about to leave. + + distance += row_heights[new_y]; + + // *Now* increment the loop. + + new_y += dir; + + new_x = FindSelectableColumn(table, new_y, table->selected_x); + + if (new_x >= 0) + { + // Found a selectable widget in this column! + // Select it anyway in case we don't find something better. + + table->selected_x = new_x; + table->selected_y = new_y; + changed = 1; + + // ...but is it far enough away? + + if (distance >= abs(pagey)) + { + break; + } + } + } + } + + free(row_heights); + free(column_widths); + + return changed; +} + diff --git a/textscreen/txt_table.h b/textscreen/txt_table.h index 0e7fbe94..0166abee 100644 --- a/textscreen/txt_table.h +++ b/textscreen/txt_table.h @@ -178,6 +178,19 @@ void TXT_SetColumnWidths(TXT_UNCAST_ARG(table), ...); void TXT_ClearTable(TXT_UNCAST_ARG(table)); +/** + * Hack to move the selection in a table by a 'page', triggered by the + * scrollpane. This acts as per the keyboard events for the arrows, but moves + * the selection by at least the specified number of characters. + * + * @param table The table. + * @param pagex Minimum distance to move the selection horizontally. + * @param pagey Minimum distance to move the selection vertically. + * @return Non-zero if the selection has been changed. + */ + +int TXT_PageTable(TXT_UNCAST_ARG(table), int pagex, int pagey); + #endif /* #ifndef TXT_TABLE_T */ |