From af8a6541a2608c387c6df95b4e0bd57a1fade6e6 Mon Sep 17 00:00:00 2001 From: Dave Davenport Date: Fri, 6 Jan 2017 16:41:23 +0100 Subject: [PATCH] Order entries in box based on index, allow theme to override. --- include/theme.h | 10 ++++++ include/widgets/box.h | 4 +-- include/widgets/widget-internal.h | 2 ++ source/theme.c | 55 ++++++++++++++++------------ source/view.c | 18 +++++----- source/widgets/box.c | 59 ++++++++++--------------------- source/widgets/listview.c | 21 ++++++++--- 7 files changed, 91 insertions(+), 78 deletions(-) diff --git a/include/theme.h b/include/theme.h index a0b55675..ee5acb6f 100644 --- a/include/theme.h +++ b/include/theme.h @@ -202,6 +202,16 @@ Distance rofi_theme_get_distance ( const widget *widget, const char *property, i * @returns The integer value of this property for this widget. */ int rofi_theme_get_integer ( const widget *widget, const char *property, int def ); +/** + * @param widget The widget to query + * @param property The property to query. + * @param def The default value. + * + * Obtain the integer of the widget. + * + * @returns The integer value of this property for this widget. + */ +int rofi_theme_get_integer_exact ( const widget *widget, const char *property, int def ); /** * @param widget The widget to query diff --git a/include/widgets/box.h b/include/widgets/box.h index b0688c83..2c067598 100644 --- a/include/widgets/box.h +++ b/include/widgets/box.h @@ -43,11 +43,11 @@ box * box_create ( const char *name, boxType type ); * @param box Handle to the box widget. * @param child Handle to the child widget to pack. * @param expand If the child widget should expand and use all available space. - * @param end If the child widget should be packed at the end. + * @param index The position index. * * Add a widget to the box. */ -void box_add ( box *box, widget *child, gboolean expand, gboolean end ); +void box_add ( box *box, widget *child, gboolean expand, int index ); /** * @param box Handle to the box widget. diff --git a/include/widgets/widget-internal.h b/include/widgets/widget-internal.h index cdd9d2f9..e26fb8f2 100644 --- a/include/widgets/widget-internal.h +++ b/include/widgets/widget-internal.h @@ -24,6 +24,8 @@ struct _widget gboolean enabled; /** Expand the widget when packed */ gboolean expand; + /*** The packing index */ + int index; /** Place widget at end of parent */ gboolean end; /** Parent widget */ diff --git a/source/theme.c b/source/theme.c index 9ec22732..3e37cbfe 100644 --- a/source/theme.c +++ b/source/theme.c @@ -308,7 +308,7 @@ static void rofi_theme_resolve_link_property ( Property *p, int depth ) p->value.link.ref = p; } -static Property *rofi_theme_find_property ( ThemeWidget *widget, PropertyType type, const char *property ) +static Property *rofi_theme_find_property ( ThemeWidget *widget, PropertyType type, const char *property, gboolean exact ) { while ( widget ) { if ( widget->properties && g_hash_table_contains ( widget->properties, property) ) { @@ -330,38 +330,47 @@ static Property *rofi_theme_find_property ( ThemeWidget *widget, PropertyType ty return p; } } + if ( exact ) { + return NULL; + } widget = widget->parent; } return NULL; } -static ThemeWidget *rofi_theme_find_widget ( const char *name, const char *state ) +static ThemeWidget *rofi_theme_find_widget ( const char *name, const char *state, gboolean exact ) { // First find exact match based on name. - ThemeWidget *widget = rofi_theme_find ( rofi_theme, name, TRUE ); - widget = rofi_theme_find ( widget, state, TRUE ); + ThemeWidget *widget = rofi_theme_find ( rofi_theme, name, exact ); + widget = rofi_theme_find ( widget, state, exact ); - if ( widget == NULL ){ - // Fuzzy finder - widget = rofi_theme_find ( rofi_theme, name, FALSE ); - widget = rofi_theme_find ( widget, state, FALSE ); - } return widget; } int rofi_theme_get_integer ( const widget *widget, const char *property, int def ) { - ThemeWidget *wid = rofi_theme_find_widget ( widget->name, widget->state ); - Property *p = rofi_theme_find_property ( wid, P_INTEGER, property ); + ThemeWidget *wid = rofi_theme_find_widget ( widget->name, widget->state, FALSE ); + Property *p = rofi_theme_find_property ( wid, P_INTEGER, property, FALSE ); if ( p ){ return p->value.i; } g_log ( LOG_DOMAIN, G_LOG_LEVEL_DEBUG, "Theme entry: #%s %s property %s unset.", widget->name, widget->state?widget->state:"", property ); return def; } +int rofi_theme_get_integer_exact ( const widget *widget, const char *property, int def ) +{ + ThemeWidget *wid = rofi_theme_find_widget ( widget->name, widget->state, TRUE ); + Property *p = rofi_theme_find_property ( wid, P_INTEGER, property, TRUE ); + if ( p ){ + return p->value.i; + } + g_log ( LOG_DOMAIN, G_LOG_LEVEL_DEBUG, "Theme entry: #%s %s property %s unset.", widget->name, widget->state?widget->state:"", property ); + return def; +} + Distance rofi_theme_get_distance ( const widget *widget, const char *property, int def ) { - ThemeWidget *wid = rofi_theme_find_widget ( widget->name, widget->state ); - Property *p = rofi_theme_find_property ( wid, P_PADDING, property ); + ThemeWidget *wid = rofi_theme_find_widget ( widget->name, widget->state, FALSE ); + Property *p = rofi_theme_find_property ( wid, P_PADDING, property, FALSE ); if ( p ){ if ( p->type == P_INTEGER ){ return (Distance){p->value.i,PW_PX, SOLID}; @@ -375,8 +384,8 @@ Distance rofi_theme_get_distance ( const widget *widget, const char *property, i int rofi_theme_get_boolean ( const widget *widget, const char *property, int def ) { - ThemeWidget *wid = rofi_theme_find_widget ( widget->name, widget->state ); - Property *p = rofi_theme_find_property ( wid, P_BOOLEAN, property ); + ThemeWidget *wid = rofi_theme_find_widget ( widget->name, widget->state, FALSE ); + Property *p = rofi_theme_find_property ( wid, P_BOOLEAN, property, FALSE ); if ( p ){ return p->value.b; } @@ -386,8 +395,8 @@ int rofi_theme_get_boolean ( const widget *widget, const char *property, int def char *rofi_theme_get_string ( const widget *widget, const char *property, char *def ) { - ThemeWidget *wid = rofi_theme_find_widget ( widget->name, widget->state ); - Property *p = rofi_theme_find_property ( wid, P_STRING, property ); + ThemeWidget *wid = rofi_theme_find_widget ( widget->name, widget->state, FALSE ); + Property *p = rofi_theme_find_property ( wid, P_STRING, property, FALSE ); if ( p ){ return p->value.s; } @@ -396,8 +405,8 @@ char *rofi_theme_get_string ( const widget *widget, const char *property, char * } double rofi_theme_get_double ( const widget *widget, const char *property, double def ) { - ThemeWidget *wid = rofi_theme_find_widget ( widget->name, widget->state ); - Property *p = rofi_theme_find_property ( wid, P_DOUBLE, property ); + ThemeWidget *wid = rofi_theme_find_widget ( widget->name, widget->state, FALSE ); + Property *p = rofi_theme_find_property ( wid, P_DOUBLE, property, FALSE ); if ( p ){ return p->value.b; } @@ -406,8 +415,8 @@ double rofi_theme_get_double ( const widget *widget, const char *property, doubl } void rofi_theme_get_color ( const widget *widget, const char *property, cairo_t *d) { - ThemeWidget *wid = rofi_theme_find_widget ( widget->name, widget->state ); - Property *p = rofi_theme_find_property ( wid, P_COLOR, property ); + ThemeWidget *wid = rofi_theme_find_widget ( widget->name, widget->state, FALSE ); + Property *p = rofi_theme_find_property ( wid, P_COLOR, property, FALSE ); if ( p ){ cairo_set_source_rgba ( d, p->value.color.red, @@ -421,8 +430,8 @@ void rofi_theme_get_color ( const widget *widget, const char *property, cairo_t } Padding rofi_theme_get_padding ( const widget *widget, const char *property, Padding pad ) { - ThemeWidget *wid = rofi_theme_find_widget ( widget->name, widget->state ); - Property *p = rofi_theme_find_property ( wid, P_PADDING, property ); + ThemeWidget *wid = rofi_theme_find_widget ( widget->name, widget->state, FALSE ); + Property *p = rofi_theme_find_property ( wid, P_PADDING, property, FALSE ); if ( p ){ if ( p->type == P_PADDING ){ pad = p->value.padding; diff --git a/source/view.c b/source/view.c index dcec9c70..75c6a03d 100644 --- a/source/view.c +++ b/source/view.c @@ -1453,43 +1453,43 @@ RofiViewState *rofi_view_create ( Mode *sw, // Only enable widget when sidebar is enabled. if ( config.sidebar_mode ) { state->sidebar_bar = box_create ( "window.mainbox.sidebar.box", BOX_HORIZONTAL ); - box_add ( state->main_box, WIDGET ( state->sidebar_bar ), FALSE, TRUE ); + box_add ( state->main_box, WIDGET ( state->sidebar_bar ), FALSE, 10 ); state->num_modi = rofi_get_num_enabled_modi (); state->modi = g_malloc0 ( state->num_modi * sizeof ( textbox * ) ); for ( unsigned int j = 0; j < state->num_modi; j++ ) { const Mode * mode = rofi_get_mode ( j ); state->modi[j] = textbox_create ( "window.mainbox.sidebar.button", TB_CENTER|TB_AUTOHEIGHT, ( mode == state->sw ) ? HIGHLIGHT : NORMAL, mode_get_display_name ( mode ) ); - box_add ( state->sidebar_bar, WIDGET ( state->modi[j] ), TRUE, FALSE ); + box_add ( state->sidebar_bar, WIDGET ( state->modi[j] ), TRUE, j ); widget_set_clicked_handler ( WIDGET ( state->modi[j] ), rofi_view_modi_clicked_cb, state ); } } int end = ( config.location == WL_EAST_SOUTH || config.location == WL_SOUTH || config.location == WL_SOUTH_WEST ); - box_add ( state->main_box, WIDGET ( state->input_bar ), FALSE, end ); + box_add ( state->main_box, WIDGET ( state->input_bar ), FALSE, end?9:0 ); state->case_indicator = textbox_create ( "window.mainbox.inputbar.case-indicator", TB_AUTOWIDTH|TB_AUTOHEIGHT, NORMAL, "*" ); // Add small separator between case indicator and text box. - box_add ( state->input_bar, WIDGET ( state->case_indicator ), FALSE, TRUE ); + box_add ( state->input_bar, WIDGET ( state->case_indicator ), FALSE, 3 ); // Prompt box. state->prompt = textbox_create ( "window.mainbox.inputbar.prompt",TB_AUTOWIDTH|TB_AUTOHEIGHT, NORMAL, "" ); rofi_view_update_prompt ( state ); - box_add ( state->input_bar, WIDGET ( state->prompt ), FALSE, FALSE ); + box_add ( state->input_bar, WIDGET ( state->prompt ), FALSE, 1 ); // Entry box TextboxFlags tfl = TB_EDITABLE; tfl |= ( ( menu_flags & MENU_PASSWORD ) == MENU_PASSWORD ) ? TB_PASSWORD : 0; state->text = textbox_create ( "window.mainbox.inputbar.entry", tfl|TB_AUTOHEIGHT, NORMAL, input ); - box_add ( state->input_bar, WIDGET ( state->text ), TRUE, FALSE ); + box_add ( state->input_bar, WIDGET ( state->text ), TRUE, 2 ); textbox_text ( state->case_indicator, get_matching_state () ); if ( message ) { container *box = container_create ( "window.mainbox.message.box" ); textbox *message_tb = textbox_create ( "window.mainbox.message.textbox", TB_AUTOHEIGHT | TB_MARKUP | TB_WRAP, NORMAL, message ); container_add ( box, WIDGET (message_tb) ); - box_add ( state->main_box, WIDGET ( box ), FALSE, end); + box_add ( state->main_box, WIDGET ( box ), FALSE, end?8:2); } state->overlay = textbox_create ( "window.overlay", TB_AUTOWIDTH|TB_AUTOHEIGHT, URGENT, "blaat" ); @@ -1503,7 +1503,7 @@ RofiViewState *rofi_view_create ( Mode *sw, listview_set_num_lines ( state->list_view, config.menu_lines ); listview_set_max_lines ( state->list_view, state->num_lines ); - box_add ( state->main_box, WIDGET ( state->list_view ), TRUE, FALSE ); + box_add ( state->main_box, WIDGET ( state->list_view ), TRUE, 3); // filtered list state->line_map = g_malloc0_n ( state->num_lines, sizeof ( unsigned int ) ); @@ -1544,7 +1544,7 @@ int rofi_view_error_dialog ( const char *msg, int markup ) container_add ( state->main_window, WIDGET ( state->main_box ) ); state->text = textbox_create ( "window.mainbox.message", ( TB_AUTOHEIGHT | TB_WRAP ) + ( ( markup ) ? TB_MARKUP : 0 ), NORMAL, ( msg != NULL ) ? msg : "" ); - box_add ( state->main_box, WIDGET ( state->text ), TRUE, FALSE ); + box_add ( state->main_box, WIDGET ( state->text ), TRUE, 1 ); // Make sure we enable fixed num lines when in normal window mode. diff --git a/source/widgets/box.c b/source/widgets/box.c index 7bd48537..ba1e4eab 100644 --- a/source/widgets/box.c +++ b/source/widgets/box.c @@ -122,7 +122,6 @@ static void vert_calculate_size ( box *b ) return; } if ( active_widgets > 0 ) { - int bottom = b->widget.h - widget_padding_get_bottom ( WIDGET( b ) ); int top = widget_padding_get_top ( WIDGET ( b ) ); double rem = rem_height - b->max_size; int index = 0; @@ -134,26 +133,12 @@ static void vert_calculate_size ( box *b ) if ( child->expand == TRUE ) { // Re-calculate to avoid round issues leaving one pixel left. int expanding_widgets_size = ( rem ) / ( expanding_widgets - index ); - if ( child->end ) { - bottom -= expanding_widgets_size; - widget_move ( child, widget_padding_get_left ( WIDGET ( b ) ), bottom ); - widget_resize ( child, rem_width, expanding_widgets_size ); - bottom -= spacing; - } - else { - widget_move ( child, widget_padding_get_left ( WIDGET ( b ) ), top ); - top += expanding_widgets_size; - widget_resize ( child, rem_width, expanding_widgets_size ); - top += spacing; - } + widget_move ( child, widget_padding_get_left ( WIDGET ( b ) ), top ); + top += expanding_widgets_size; + widget_resize ( child, rem_width, expanding_widgets_size ); + top += spacing; rem -= expanding_widgets_size; index++; - // b->max_size += widget_padding_get_padding_height ( child); - } - else if ( child->end ) { - bottom -= widget_get_height ( child ); - widget_move ( child, widget_padding_get_left ( WIDGET ( b ) ), bottom ); - bottom -= spacing; } else { widget_move ( child, widget_padding_get_left ( WIDGET ( b ) ), top ); @@ -200,7 +185,6 @@ static void hori_calculate_size ( box *b ) return; } if ( active_widgets > 0 ) { - int right = b->widget.w-widget_padding_get_right ( WIDGET (b) ); int left = widget_padding_get_left ( WIDGET (b) ); double rem = rem_width - b->max_size; int index = 0; @@ -212,26 +196,12 @@ static void hori_calculate_size ( box *b ) if ( child->expand == TRUE ) { // Re-calculate to avoid round issues leaving one pixel left. int expanding_widgets_size = ( rem ) / ( expanding_widgets - index ); - if ( child->end ) { - right -= expanding_widgets_size; - widget_move ( child, right, widget_padding_get_top ( WIDGET ( b ) )); - widget_resize ( child, expanding_widgets_size, rem_height ); - right -= spacing; - } - else { - widget_move ( child, left, widget_padding_get_top ( WIDGET ( b ) ) ); - left += expanding_widgets_size; - widget_resize ( child, expanding_widgets_size, rem_height ); - left += spacing; - } + widget_move ( child, left, widget_padding_get_top ( WIDGET ( b ) ) ); + left += expanding_widgets_size; + widget_resize ( child, expanding_widgets_size, rem_height ); + left += spacing; rem -= expanding_widgets_size; index++; - // b->max_size += widget_padding_get_padding_width ( child); - } - else if ( child->end ) { - right -= widget_get_width ( child ); - widget_move ( child, right, widget_padding_get_top ( WIDGET ( b ) ) ); - right -= spacing; } else { widget_move ( child, left, widget_padding_get_top ( WIDGET ( b ) ) ); @@ -264,7 +234,15 @@ static void box_free ( widget *wid ) g_free ( b ); } -void box_add ( box *box, widget *child, gboolean expand, gboolean end ) +static int box_sort_children ( gconstpointer a, gconstpointer b ) +{ + widget *child_a = (widget*)a; + widget *child_b = (widget*)b; + + return child_a->index - child_b->index; +} + +void box_add ( box *box, widget *child, gboolean expand, int index ) { if ( box == NULL ) { return; @@ -280,9 +258,10 @@ void box_add ( box *box, widget *child, gboolean expand, gboolean end ) box->widget.h = height; } child->expand = rofi_theme_get_boolean ( child, "expand", expand); - child->end = rofi_theme_get_boolean ( child, "end", end); + child->index = rofi_theme_get_integer_exact ( child, "index" , index ); child->parent = WIDGET ( box ); box->children = g_list_append ( box->children, (void *) child ); + box->children = g_list_sort ( box->children, box_sort_children ); widget_update ( WIDGET ( box ) ); } diff --git a/source/widgets/listview.c b/source/widgets/listview.c index 031b2cb2..a09e7526 100644 --- a/source/widgets/listview.c +++ b/source/widgets/listview.c @@ -171,6 +171,11 @@ static void listview_draw ( widget *wid, cairo_t *draw ) lv->last_offset = offset; int spacing_vert = distance_get_pixel ( lv->spacing, ORIENTATION_VERTICAL ); int spacing_hori = distance_get_pixel ( lv->spacing, ORIENTATION_HORIZONTAL ); + + int left_offset = widget_padding_get_left ( wid ); + if ( lv->scrollbar->widget.index == 0 ) { + left_offset += spacing_hori + lv->scrollbar->widget.w; + } if ( lv->cur_elements > 0 && lv->max_rows > 0 ) { // Set new x/y possition. unsigned int max = MIN ( lv->cur_elements, lv->req_elements - offset ); @@ -183,7 +188,7 @@ static void listview_draw ( widget *wid, cairo_t *draw ) } unsigned int element_width = ( width ) / lv->cur_columns; for ( unsigned int i = 0; i < max; i++ ) { - unsigned int ex = widget_padding_get_left ( wid ) + ( ( i ) / lv->max_rows ) * ( element_width + spacing_hori ); + unsigned int ex = left_offset + ( ( i ) / lv->max_rows ) * ( element_width + spacing_hori ); if ( lv->reverse ) { unsigned int ey = wid->h-(widget_padding_get_bottom ( wid ) + ( ( i ) % lv->max_rows ) * ( lv->element_height + spacing_vert ))-lv->element_height; textbox_moveresize ( lv->boxes[i], ex, ey, element_width, lv->element_height ); @@ -271,9 +276,15 @@ static void listview_resize ( widget *wid, short w, short h ) lv->max_rows = ( spacing_vert + height ) / ( lv->element_height + spacing_vert ); lv->max_elements = lv->max_rows * lv->menu_columns; - widget_move ( WIDGET ( lv->scrollbar ), - lv->widget.w - widget_padding_get_right ( WIDGET ( lv ) ) - widget_get_width ( WIDGET ( lv->scrollbar ) ), - widget_padding_get_top ( WIDGET (lv ) )); + if ( lv->scrollbar->widget.index == 0 ){ + widget_move ( WIDGET ( lv->scrollbar ), + widget_padding_get_left ( WIDGET ( lv ) ), + widget_padding_get_top ( WIDGET ( lv ) ) ); + } else { + widget_move ( WIDGET ( lv->scrollbar ), + lv->widget.w - widget_padding_get_right ( WIDGET ( lv ) ) - widget_get_width ( WIDGET ( lv->scrollbar ) ), + widget_padding_get_top ( WIDGET (lv ) )); + } widget_resize ( WIDGET ( lv->scrollbar ), widget_get_width ( WIDGET ( lv->scrollbar ) ), height ); listview_recompute_elements ( lv ); @@ -352,6 +363,8 @@ listview *listview_create ( const char *name, listview_update_callback cb, void char *n = g_strjoin(".", lv->widget.name,"scrollbar", NULL); lv->scrollbar = scrollbar_create ( n ); + // Default position on right. + lv->scrollbar->widget.index = rofi_theme_get_integer_exact ( WIDGET (lv->scrollbar), "index", 1); g_free(n); widget_set_clicked_handler ( WIDGET ( lv->scrollbar ), listview_scrollbar_clicked, lv ); lv->scrollbar->widget.parent = WIDGET ( lv );