[listview] Allow settings of flow direction of elements (#1605)

* [Listview] Initial implementation for left to right packing.
* [Listview] fix movement in pack-left-to-right.
* Add element-next/prev keybinding and remap tab.
* [Listview] Change option name to 'flow' and use rofi orientation type.
* [Listview] Make listview work with reverse property.
* Update test for 2 new keybindings.

fixes: #1058
This commit is contained in:
Dave Davenport 2022-03-07 20:37:58 +01:00 committed by GitHub
parent 0bbefbf257
commit 47d785758a
No known key found for this signature in database
GPG Key ID: 4AEE18F83AFDEB23
10 changed files with 171 additions and 24 deletions

View File

@ -262,7 +262,7 @@ Go to the next column
Select previous entry Select previous entry
.PP .PP
\fBDefault\fP: Up,Control+p,ISO\_Left\_Tab \fBDefault\fP: Up,Control+p
.SS \fBkb\-row\-down\fP .SS \fBkb\-row\-down\fP
.PP .PP
@ -276,7 +276,21 @@ Select next entry
Go to next row, if one left, accept it, if no left next mode. Go to next row, if one left, accept it, if no left next mode.
.PP .PP
\fBDefault\fP: Tab \fBDefault\fP:
.SS \fBkb\-element\-next\fP
.PP
Go to next row.
.PP
\fBDefault\fP: Tab
.SS \fBkb\-element\-prev\fP
.PP
Go to previous row.
.PP
\fBDefault\fP: ISO\_Left\_Tab
.SS \fBkb\-page\-prev\fP .SS \fBkb\-page\-prev\fP
.PP .PP

View File

@ -183,7 +183,7 @@ Go to the next column
### **kb-row-up** ### **kb-row-up**
Select previous entry Select previous entry
**Default**: Up,Control+p,ISO_Left_Tab **Default**: Up,Control+p
### **kb-row-down** ### **kb-row-down**
Select next entry Select next entry
@ -193,7 +193,17 @@ Select next entry
### **kb-row-tab** ### **kb-row-tab**
Go to next row, if one left, accept it, if no left next mode. Go to next row, if one left, accept it, if no left next mode.
**Default**: Tab **Default**:
### **kb-element-next**
Go to next row.
**Default**: Tab
### **kb-element-prev**
Go to previous row.
**Default**: ISO_Left_Tab
### **kb-page-prev** ### **kb-page-prev**
Go to the previous page Go to the previous page

View File

@ -1278,6 +1278,9 @@ Indicate how elements are stacked. Horizontal implements the dmenu style.
\fBreverse\fP: boolean \fBreverse\fP: boolean
Reverse the ordering (top down to bottom up). Reverse the ordering (top down to bottom up).
.IP \(bu 2 .IP \(bu 2
\fBflow\fP: orientation
The order the elements are layed out. Vertical is the original 'column' view.
.IP \(bu 2
\fBfixed\-columns\fP: boolean \fBfixed\-columns\fP: boolean
Do not reduce the number of columns shown when number of visible elements is not enough to fill them all. Do not reduce the number of columns shown when number of visible elements is not enough to fill them all.

View File

@ -794,6 +794,8 @@ The following properties are currently supported:
Indicate how elements are stacked. Horizontal implements the dmenu style. Indicate how elements are stacked. Horizontal implements the dmenu style.
* **reverse**: boolean * **reverse**: boolean
Reverse the ordering (top down to bottom up). Reverse the ordering (top down to bottom up).
* **flow**: orientation
The order the elements are layed out. Vertical is the original 'column' view.
* **fixed-columns**: boolean * **fixed-columns**: boolean
Do not reduce the number of columns shown when number of visible elements is not enough to fill them all. Do not reduce the number of columns shown when number of visible elements is not enough to fill them all.

View File

@ -101,6 +101,8 @@ typedef enum {
ROW_UP, ROW_UP,
ROW_DOWN, ROW_DOWN,
ROW_TAB, ROW_TAB,
ELEMENT_NEXT,
ELEMENT_PREV,
PAGE_PREV, PAGE_PREV,
PAGE_NEXT, PAGE_NEXT,
ROW_FIRST, ROW_FIRST,

View File

@ -111,6 +111,21 @@ void listview_set_selected(listview *lv, unsigned int selected);
*/ */
unsigned int listview_get_selected(listview *lv); unsigned int listview_get_selected(listview *lv);
/**
* @param lv The listview handle
*
* Move the selection next element.
* - Wrap around.
*/
void listview_nav_next(listview *lv);
/**
* @param lv The listview handle
*
* Move the selection previous element.
* - Wrap around.
*/
void listview_nav_prev(listview *lv);
/** /**
* @param lv The listview handle * @param lv The listview handle
* *

View File

@ -26,10 +26,10 @@
*/ */
#include <glib.h> #include <glib.h>
#include <string.h>
#include "nkutils-bindings.h" #include "nkutils-bindings.h"
#include "rofi.h" #include "rofi.h"
#include "xrmoptions.h" #include "xrmoptions.h"
#include <string.h>
typedef struct { typedef struct {
guint id; guint id;
@ -145,7 +145,7 @@ ActionBindingEntry rofi_bindings[] = {
.comment = "Go to the next column"}, .comment = "Go to the next column"},
{.id = ROW_UP, {.id = ROW_UP,
.name = "kb-row-up", .name = "kb-row-up",
.binding = "Up,Control+p,ISO_Left_Tab", .binding = "Up,Control+p",
.comment = "Select previous entry"}, .comment = "Select previous entry"},
{.id = ROW_DOWN, {.id = ROW_DOWN,
.name = "kb-row-down", .name = "kb-row-down",
@ -153,9 +153,17 @@ ActionBindingEntry rofi_bindings[] = {
.comment = "Select next entry"}, .comment = "Select next entry"},
{.id = ROW_TAB, {.id = ROW_TAB,
.name = "kb-row-tab", .name = "kb-row-tab",
.binding = "Tab", .binding = "",
.comment = .comment =
"Go to next row, if one left, accept it, if no left next mode."}, "Go to next row, if one left, accept it, if no left next mode."},
{.id = ELEMENT_NEXT,
.name = "kb-element-next",
.binding = "Tab",
.comment = "Go to next element (in logical order)."},
{.id = ELEMENT_PREV,
.name = "kb-element-prev",
.binding = "ISO_Left_Tab",
.comment = "Go to next previous element (in logical order)."},
{.id = PAGE_PREV, {.id = PAGE_PREV,
.name = "kb-page-prev", .name = "kb-page-prev",
.binding = "Page_Up", .binding = "Page_Up",

View File

@ -1362,6 +1362,12 @@ static void rofi_view_trigger_global_action(KeyBindingAction action) {
state->retv = MENU_CANCEL; state->retv = MENU_CANCEL;
state->quit = TRUE; state->quit = TRUE;
break; break;
case ELEMENT_NEXT:
listview_nav_next(state->list_view);
break;
case ELEMENT_PREV:
listview_nav_prev(state->list_view);
break;
case ROW_UP: case ROW_UP:
listview_nav_up(state->list_view); listview_nav_up(state->list_view);
break; break;

View File

@ -71,6 +71,9 @@ struct _listview {
// RChanged // RChanged
// Text needs to be repainted. // Text needs to be repainted.
unsigned int rchanged; unsigned int rchanged;
// The direction we pack the widgets.
RofiOrientation pack_direction;
// Administration // Administration
unsigned int cur_page; unsigned int cur_page;
@ -433,30 +436,53 @@ static void listview_draw(widget *wid, cairo_t *draw) {
} }
} }
for (unsigned int i = 0; i < max; i++) { for (unsigned int i = 0; i < max; i++) {
unsigned int ex = if (lv->pack_direction == ROFI_ORIENTATION_HORIZONTAL) {
left_offset + ((i) / lv->max_rows) * (element_width + spacing_hori); unsigned int ex = left_offset + ((i) % lv->cur_columns) *
(element_width + spacing_hori);
unsigned int ey = 0;
if (lv->reverse) {
ey = wid->h -
(widget_padding_get_bottom(wid) +
((i) / lv->cur_columns) *
(lv->element_height + spacing_vert)) -
lv->element_height;
if ((i) / lv->max_rows == (lv->cur_columns - 1)) { if ((i) / lv->cur_columns == (lv->cur_columns - 1)) {
ex += d; ex += d;
} }
if (lv->reverse) { } else {
unsigned int ey = ey = top_offset +
wid->h - ((i) / lv->cur_columns) * (lv->element_height + spacing_vert);
(widget_padding_get_bottom(wid) +
((i) % lv->max_rows) * (lv->element_height + spacing_vert)) - if ((i) / lv->cur_columns == (lv->cur_columns - 1)) {
lv->element_height; ex += d;
}
}
widget_move(WIDGET(lv->boxes[i].box), ex, ey); widget_move(WIDGET(lv->boxes[i].box), ex, ey);
widget_resize(WIDGET(lv->boxes[i].box), element_width, widget_resize(WIDGET(lv->boxes[i].box), element_width,
lv->element_height); lv->element_height);
} else { } else {
unsigned int ey = unsigned int ex = left_offset + ((i) / lv->max_rows) *
top_offset + (element_width + spacing_hori);
((i) % lv->max_rows) * (lv->element_height + spacing_vert);
if ((i) / lv->max_rows == (lv->cur_columns - 1)) {
ex += d;
}
unsigned int ey = 0;
if (lv->reverse) {
ey = wid->h -
(widget_padding_get_bottom(wid) +
((i) % lv->max_rows) * (lv->element_height + spacing_vert)) -
lv->element_height;
} else {
ey = top_offset +
((i) % lv->max_rows) * (lv->element_height + spacing_vert);
}
widget_move(WIDGET(lv->boxes[i].box), ex, ey); widget_move(WIDGET(lv->boxes[i].box), ex, ey);
widget_resize(WIDGET(lv->boxes[i].box), element_width, widget_resize(WIDGET(lv->boxes[i].box), element_width,
lv->element_height); lv->element_height);
} }
update_element(lv, i, i + offset, TRUE); update_element(lv, i, i + offset, TRUE);
widget_draw(WIDGET(lv->boxes[i].box), draw); widget_draw(WIDGET(lv->boxes[i].box), draw);
} }
@ -494,7 +520,14 @@ static void listview_recompute_elements(listview *lv) {
} }
if (!(lv->fixed_columns) && lv->req_elements < lv->max_elements) { if (!(lv->fixed_columns) && lv->req_elements < lv->max_elements) {
newne = lv->req_elements; newne = lv->req_elements;
lv->cur_columns = (lv->req_elements + (lv->max_rows - 1)) / lv->max_rows; if (lv->pack_direction == ROFI_ORIENTATION_VERTICAL) {
lv->cur_columns = (lv->req_elements + (lv->max_rows - 1)) / lv->max_rows;
} else {
lv->cur_columns = lv->menu_columns;
if (lv->req_elements < lv->menu_columns) {
lv->cur_columns = lv->req_elements;
}
}
} else { } else {
newne = MIN(lv->req_elements, lv->max_elements); newne = MIN(lv->req_elements, lv->max_elements);
lv->cur_columns = lv->menu_columns; lv->cur_columns = lv->menu_columns;
@ -709,6 +742,8 @@ listview *listview_create(widget *parent, const char *name,
config.fixed_num_lines); config.fixed_num_lines);
lv->dynamic = rofi_theme_get_boolean(WIDGET(lv), "dynamic", TRUE); lv->dynamic = rofi_theme_get_boolean(WIDGET(lv), "dynamic", TRUE);
lv->reverse = rofi_theme_get_boolean(WIDGET(lv), "reverse", reverse); lv->reverse = rofi_theme_get_boolean(WIDGET(lv), "reverse", reverse);
lv->pack_direction =
rofi_theme_get_orientation(WIDGET(lv), "flow", ROFI_ORIENTATION_VERTICAL);
lv->cycle = rofi_theme_get_boolean(WIDGET(lv), "cycle", config.cycle); lv->cycle = rofi_theme_get_boolean(WIDGET(lv), "cycle", config.cycle);
lv->fixed_columns = lv->fixed_columns =
rofi_theme_get_boolean(WIDGET(lv), "fixed-columns", FALSE); rofi_theme_get_boolean(WIDGET(lv), "fixed-columns", FALSE);
@ -756,11 +791,44 @@ static void listview_nav_down_int(listview *lv) {
lv->barview.direction = LEFT_TO_RIGHT; lv->barview.direction = LEFT_TO_RIGHT;
widget_queue_redraw(WIDGET(lv)); widget_queue_redraw(WIDGET(lv));
} }
void listview_nav_next(listview *lv) {
if (lv == NULL) {
return;
}
listview_nav_down_int(lv);
}
void listview_nav_prev(listview *lv) {
if (lv == NULL) {
return;
}
listview_nav_up_int(lv);
}
static void listview_nav_column_left_int(listview *lv) {
if (lv->selected >= lv->cur_columns) {
lv->selected -= lv->cur_columns;
widget_queue_redraw(WIDGET(lv));
}
}
static void listview_nav_column_right_int(listview *lv) {
if ((lv->selected + lv->cur_columns) < lv->req_elements) {
lv->selected += lv->cur_columns;
widget_queue_redraw(WIDGET(lv));
}
}
void listview_nav_up(listview *lv) { void listview_nav_up(listview *lv) {
if (lv == NULL) { if (lv == NULL) {
return; return;
} }
if (lv->pack_direction == ROFI_ORIENTATION_HORIZONTAL) {
if (lv->reverse) {
listview_nav_column_right_int(lv);
} else {
listview_nav_column_left_int(lv);
}
return;
}
if (lv->reverse) { if (lv->reverse) {
listview_nav_down_int(lv); listview_nav_down_int(lv);
} else { } else {
@ -771,6 +839,14 @@ void listview_nav_down(listview *lv) {
if (lv == NULL) { if (lv == NULL) {
return; return;
} }
if (lv->pack_direction == ROFI_ORIENTATION_HORIZONTAL) {
if (lv->reverse) {
listview_nav_column_left_int(lv);
} else {
listview_nav_column_right_int(lv);
}
return;
}
if (lv->reverse) { if (lv->reverse) {
listview_nav_up_int(lv); listview_nav_up_int(lv);
} else { } else {
@ -782,6 +858,13 @@ void listview_nav_left(listview *lv) {
if (lv == NULL) { if (lv == NULL) {
return; return;
} }
if (lv->max_rows == 0) {
return;
}
if (lv->pack_direction == ROFI_ORIENTATION_HORIZONTAL) {
listview_nav_up_int(lv);
return;
}
if (lv->type == BARVIEW) { if (lv->type == BARVIEW) {
listview_nav_up_int(lv); listview_nav_up_int(lv);
return; return;
@ -798,6 +881,10 @@ void listview_nav_right(listview *lv) {
if (lv->max_rows == 0) { if (lv->max_rows == 0) {
return; return;
} }
if (lv->pack_direction == ROFI_ORIENTATION_HORIZONTAL) {
listview_nav_down_int(lv);
return;
}
if (lv->type == BARVIEW) { if (lv->type == BARVIEW) {
listview_nav_down_int(lv); listview_nav_down_int(lv);
return; return;

View File

@ -117,7 +117,7 @@ END_TEST
START_TEST(test_mode_num_items) { START_TEST(test_mode_num_items) {
unsigned int rows = mode_get_num_entries(&help_keys_mode); unsigned int rows = mode_get_num_entries(&help_keys_mode);
ck_assert_int_eq(rows, 74); ck_assert_int_eq(rows, 76);
for (unsigned int i = 0; i < rows; i++) { for (unsigned int i = 0; i < rows; i++) {
int state = 0; int state = 0;
GList *list = NULL; GList *list = NULL;