mirror of
https://github.com/davatorium/rofi.git
synced 2024-11-18 13:54:36 -05:00
[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:
parent
0bbefbf257
commit
47d785758a
10 changed files with 171 additions and 24 deletions
|
@ -262,7 +262,7 @@ Go to the next column
|
|||
Select previous entry
|
||||
|
||||
.PP
|
||||
\fBDefault\fP: Up,Control+p,ISO\_Left\_Tab
|
||||
\fBDefault\fP: Up,Control+p
|
||||
|
||||
.SS \fBkb\-row\-down\fP
|
||||
.PP
|
||||
|
@ -275,9 +275,23 @@ Select next entry
|
|||
.PP
|
||||
Go to next row, if one left, accept it, if no left next mode.
|
||||
|
||||
.PP
|
||||
\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
|
||||
.PP
|
||||
Go to the previous page
|
||||
|
|
|
@ -183,7 +183,7 @@ Go to the next column
|
|||
### **kb-row-up**
|
||||
Select previous entry
|
||||
|
||||
**Default**: Up,Control+p,ISO_Left_Tab
|
||||
**Default**: Up,Control+p
|
||||
|
||||
### **kb-row-down**
|
||||
Select next entry
|
||||
|
@ -193,8 +193,18 @@ Select next entry
|
|||
### **kb-row-tab**
|
||||
Go to next row, if one left, accept it, if no left next mode.
|
||||
|
||||
**Default**:
|
||||
|
||||
### **kb-element-next**
|
||||
Go to next row.
|
||||
|
||||
**Default**: Tab
|
||||
|
||||
### **kb-element-prev**
|
||||
Go to previous row.
|
||||
|
||||
**Default**: ISO_Left_Tab
|
||||
|
||||
### **kb-page-prev**
|
||||
Go to the previous page
|
||||
|
||||
|
|
|
@ -1278,6 +1278,9 @@ Indicate how elements are stacked. Horizontal implements the dmenu style.
|
|||
\fBreverse\fP: boolean
|
||||
Reverse the ordering (top down to bottom up).
|
||||
.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
|
||||
Do not reduce the number of columns shown when number of visible elements is not enough to fill them all.
|
||||
|
||||
|
|
|
@ -794,6 +794,8 @@ The following properties are currently supported:
|
|||
Indicate how elements are stacked. Horizontal implements the dmenu style.
|
||||
* **reverse**: boolean
|
||||
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
|
||||
Do not reduce the number of columns shown when number of visible elements is not enough to fill them all.
|
||||
|
||||
|
|
|
@ -101,6 +101,8 @@ typedef enum {
|
|||
ROW_UP,
|
||||
ROW_DOWN,
|
||||
ROW_TAB,
|
||||
ELEMENT_NEXT,
|
||||
ELEMENT_PREV,
|
||||
PAGE_PREV,
|
||||
PAGE_NEXT,
|
||||
ROW_FIRST,
|
||||
|
|
|
@ -111,6 +111,21 @@ void listview_set_selected(listview *lv, unsigned int selected);
|
|||
*/
|
||||
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
|
||||
*
|
||||
|
|
|
@ -26,10 +26,10 @@
|
|||
*/
|
||||
|
||||
#include <glib.h>
|
||||
#include <string.h>
|
||||
#include "nkutils-bindings.h"
|
||||
#include "rofi.h"
|
||||
#include "xrmoptions.h"
|
||||
#include <string.h>
|
||||
|
||||
typedef struct {
|
||||
guint id;
|
||||
|
@ -145,7 +145,7 @@ ActionBindingEntry rofi_bindings[] = {
|
|||
.comment = "Go to the next column"},
|
||||
{.id = ROW_UP,
|
||||
.name = "kb-row-up",
|
||||
.binding = "Up,Control+p,ISO_Left_Tab",
|
||||
.binding = "Up,Control+p",
|
||||
.comment = "Select previous entry"},
|
||||
{.id = ROW_DOWN,
|
||||
.name = "kb-row-down",
|
||||
|
@ -153,9 +153,17 @@ ActionBindingEntry rofi_bindings[] = {
|
|||
.comment = "Select next entry"},
|
||||
{.id = ROW_TAB,
|
||||
.name = "kb-row-tab",
|
||||
.binding = "Tab",
|
||||
.binding = "",
|
||||
.comment =
|
||||
"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,
|
||||
.name = "kb-page-prev",
|
||||
.binding = "Page_Up",
|
||||
|
|
|
@ -1362,6 +1362,12 @@ static void rofi_view_trigger_global_action(KeyBindingAction action) {
|
|||
state->retv = MENU_CANCEL;
|
||||
state->quit = TRUE;
|
||||
break;
|
||||
case ELEMENT_NEXT:
|
||||
listview_nav_next(state->list_view);
|
||||
break;
|
||||
case ELEMENT_PREV:
|
||||
listview_nav_prev(state->list_view);
|
||||
break;
|
||||
case ROW_UP:
|
||||
listview_nav_up(state->list_view);
|
||||
break;
|
||||
|
|
|
@ -71,6 +71,9 @@ struct _listview {
|
|||
// RChanged
|
||||
// Text needs to be repainted.
|
||||
unsigned int rchanged;
|
||||
|
||||
// The direction we pack the widgets.
|
||||
RofiOrientation pack_direction;
|
||||
// Administration
|
||||
|
||||
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++) {
|
||||
unsigned int ex =
|
||||
left_offset + ((i) / lv->max_rows) * (element_width + spacing_hori);
|
||||
if (lv->pack_direction == ROFI_ORIENTATION_HORIZONTAL) {
|
||||
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->cur_columns == (lv->cur_columns - 1)) {
|
||||
ex += d;
|
||||
}
|
||||
} else {
|
||||
ey = top_offset +
|
||||
((i) / lv->cur_columns) * (lv->element_height + spacing_vert);
|
||||
|
||||
if ((i) / lv->cur_columns == (lv->cur_columns - 1)) {
|
||||
ex += d;
|
||||
}
|
||||
}
|
||||
widget_move(WIDGET(lv->boxes[i].box), ex, ey);
|
||||
widget_resize(WIDGET(lv->boxes[i].box), element_width,
|
||||
lv->element_height);
|
||||
|
||||
} else {
|
||||
unsigned int ex = left_offset + ((i) / lv->max_rows) *
|
||||
(element_width + spacing_hori);
|
||||
|
||||
if ((i) / lv->max_rows == (lv->cur_columns - 1)) {
|
||||
ex += d;
|
||||
}
|
||||
unsigned int ey = 0;
|
||||
if (lv->reverse) {
|
||||
unsigned int ey =
|
||||
wid->h -
|
||||
ey = wid->h -
|
||||
(widget_padding_get_bottom(wid) +
|
||||
((i) % lv->max_rows) * (lv->element_height + spacing_vert)) -
|
||||
lv->element_height;
|
||||
widget_move(WIDGET(lv->boxes[i].box), ex, ey);
|
||||
widget_resize(WIDGET(lv->boxes[i].box), element_width,
|
||||
lv->element_height);
|
||||
} else {
|
||||
unsigned int ey =
|
||||
top_offset +
|
||||
ey = top_offset +
|
||||
((i) % lv->max_rows) * (lv->element_height + spacing_vert);
|
||||
}
|
||||
widget_move(WIDGET(lv->boxes[i].box), ex, ey);
|
||||
widget_resize(WIDGET(lv->boxes[i].box), element_width,
|
||||
lv->element_height);
|
||||
}
|
||||
|
||||
update_element(lv, i, i + offset, TRUE);
|
||||
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) {
|
||||
newne = lv->req_elements;
|
||||
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 {
|
||||
newne = MIN(lv->req_elements, lv->max_elements);
|
||||
lv->cur_columns = lv->menu_columns;
|
||||
|
@ -709,6 +742,8 @@ listview *listview_create(widget *parent, const char *name,
|
|||
config.fixed_num_lines);
|
||||
lv->dynamic = rofi_theme_get_boolean(WIDGET(lv), "dynamic", TRUE);
|
||||
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->fixed_columns =
|
||||
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;
|
||||
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) {
|
||||
if (lv == NULL) {
|
||||
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) {
|
||||
listview_nav_down_int(lv);
|
||||
} else {
|
||||
|
@ -771,6 +839,14 @@ void listview_nav_down(listview *lv) {
|
|||
if (lv == NULL) {
|
||||
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) {
|
||||
listview_nav_up_int(lv);
|
||||
} else {
|
||||
|
@ -782,6 +858,13 @@ void listview_nav_left(listview *lv) {
|
|||
if (lv == NULL) {
|
||||
return;
|
||||
}
|
||||
if (lv->max_rows == 0) {
|
||||
return;
|
||||
}
|
||||
if (lv->pack_direction == ROFI_ORIENTATION_HORIZONTAL) {
|
||||
listview_nav_up_int(lv);
|
||||
return;
|
||||
}
|
||||
if (lv->type == BARVIEW) {
|
||||
listview_nav_up_int(lv);
|
||||
return;
|
||||
|
@ -798,6 +881,10 @@ void listview_nav_right(listview *lv) {
|
|||
if (lv->max_rows == 0) {
|
||||
return;
|
||||
}
|
||||
if (lv->pack_direction == ROFI_ORIENTATION_HORIZONTAL) {
|
||||
listview_nav_down_int(lv);
|
||||
return;
|
||||
}
|
||||
if (lv->type == BARVIEW) {
|
||||
listview_nav_down_int(lv);
|
||||
return;
|
||||
|
|
|
@ -117,7 +117,7 @@ END_TEST
|
|||
|
||||
START_TEST(test_mode_num_items) {
|
||||
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++) {
|
||||
int state = 0;
|
||||
GList *list = NULL;
|
||||
|
|
Loading…
Reference in a new issue