summaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
-rw-r--r--doc/default_theme.rasi95
-rw-r--r--doc/old-theme-convert-output.rasi97
-rw-r--r--include/view-internal.h2
-rw-r--r--include/widgets/listview.h2
-rw-r--r--include/widgets/textbox.h21
-rw-r--r--include/widgets/widget.h9
-rw-r--r--source/theme.c43
-rw-r--r--source/view.c21
-rw-r--r--source/widgets/box.c4
-rw-r--r--source/widgets/listview.c144
-rw-r--r--source/widgets/scrollbar.c1
-rw-r--r--source/widgets/textbox.c50
-rw-r--r--source/widgets/widget.c7
-rw-r--r--test/scrollbar-test.c1
-rw-r--r--test/theme-parser-test.c22
15 files changed, 299 insertions, 220 deletions
diff --git a/doc/default_theme.rasi b/doc/default_theme.rasi
index 4a1a382c..0b6940ab 100644
--- a/doc/default_theme.rasi
+++ b/doc/default_theme.rasi
@@ -2,63 +2,39 @@
* rofi -dump-theme output.
**/
* {
- selected-normal-foreground: var(lightbg);
- foreground: rgba ( 0, 43, 54, 100 % );
- normal-foreground: var(foreground);
- alternate-normal-background: var(lightbg);
red: rgba ( 220, 50, 47, 100 % );
- selected-urgent-foreground: var(background);
- blue: rgba ( 38, 139, 210, 100 % );
+ selected-active-foreground: var(background);
+ lightfg: rgba ( 88, 104, 117, 100 % );
+ separatorcolor: var(foreground);
urgent-foreground: var(red);
alternate-urgent-background: var(lightbg);
- active-foreground: var(blue);
lightbg: rgba ( 238, 232, 213, 100 % );
- selected-active-foreground: var(background);
- alternate-active-background: var(lightbg);
- background: rgba ( 253, 246, 227, 100 % );
- alternate-normal-foreground: var(foreground);
- normal-background: var(background);
- lightfg: rgba ( 88, 104, 117, 100 % );
- selected-normal-background: var(lightfg);
+ background-color: rgba ( 0, 0, 0, 0 % );
border-color: var(foreground);
+ normal-background: var(background);
+ selected-urgent-background: var(red);
+ alternate-active-background: var(lightbg);
spacing: 2;
- separatorcolor: var(foreground);
+ blue: rgba ( 38, 139, 210, 100 % );
+ alternate-normal-foreground: var(foreground);
urgent-background: var(background);
- selected-urgent-background: var(red);
+ selected-normal-foreground: var(lightbg);
+ active-foreground: var(blue);
+ background: rgba ( 253, 246, 227, 100 % );
+ selected-active-background: var(blue);
+ active-background: var(background);
+ selected-normal-background: var(lightfg);
+ alternate-normal-background: var(lightbg);
+ foreground: rgba ( 0, 43, 54, 100 % );
+ selected-urgent-foreground: var(background);
+ normal-foreground: var(foreground);
alternate-urgent-foreground: var(red);
- background-color: rgba ( 0, 0, 0, 0 % );
alternate-active-foreground: var(blue);
- active-background: var(background);
- selected-active-background: var(blue);
-}
-window {
- background-color: var(background);
- border: 1;
- padding: 5;
-}
-mainbox {
- border: 0;
- padding: 0;
-}
-message {
- border: 2px dash 0px 0px ;
- border-color: var(separatorcolor);
- padding: 1px ;
-}
-textbox {
- text-color: var(foreground);
-}
-listview {
- fixed-height: 0;
- border: 2px dash 0px 0px ;
- border-color: var(separatorcolor);
- spacing: 2px ;
- scrollbar: true;
- padding: 2px 0px 0px ;
}
element {
- border: 0;
padding: 1px ;
+ spacing: 5px ;
+ border: 0;
}
element normal.normal {
background-color: var(normal-background);
@@ -96,16 +72,24 @@ element alternate.active {
background-color: var(alternate-active-background);
text-color: var(alternate-active-foreground);
}
+element-text {
+ background-color: rgba ( 0, 0, 0, 0 % );
+ text-color: inherit;
+}
+element-icon {
+ background-color: rgba ( 0, 0, 0, 0 % );
+ text-color: inherit;
+}
scrollbar {
width: 4px ;
+ padding: 0;
+ handle-width: 8px ;
border: 0;
handle-color: var(normal-foreground);
- handle-width: 8px ;
- padding: 0;
}
mode-switcher {
- border: 2px dash 0px 0px ;
border-color: var(separatorcolor);
+ border: 2px dash 0px 0px ;
}
button {
spacing: 0;
@@ -116,9 +100,9 @@ button selected {
text-color: var(selected-normal-foreground);
}
inputbar {
+ padding: 1px ;
spacing: 0px ;
text-color: var(normal-foreground);
- padding: 1px ;
children: [ prompt,textbox-prompt-colon,entry,overlay,case-indicator ];
}
case-indicator {
@@ -134,12 +118,23 @@ prompt {
text-color: var(normal-foreground);
}
textbox-prompt-colon {
+ margin: 0px 0.3000em 0.0000em 0.0000em ;
expand: false;
str: ":";
- margin: 0px 0.3000em 0.0000em 0.0000em ;
text-color: inherit;
}
error-message {
background-color: rgba ( 0, 0, 0, 0 % );
text-color: var(normal-foreground);
}
+window {
+ padding: 5;
+ border: 1;
+}
+listview {
+ scrollbar: true;
+ spacing: 2px ;
+}
+message {
+ padding: 1px ;
+}
diff --git a/doc/old-theme-convert-output.rasi b/doc/old-theme-convert-output.rasi
index 169f07e4..60ad5dd7 100644
--- a/doc/old-theme-convert-output.rasi
+++ b/doc/old-theme-convert-output.rasi
@@ -2,63 +2,39 @@
* rofi -dump-theme output.
**/
* {
- selected-normal-foreground: rgba ( 2, 20, 63, 100 % );
- foreground: rgba ( 219, 223, 188, 100 % );
- normal-foreground: var(foreground);
- alternate-normal-background: rgba ( 0, 0, 0, 0 % );
red: rgba ( 220, 50, 47, 100 % );
- selected-urgent-foreground: rgba ( 2, 20, 63, 100 % );
- blue: rgba ( 38, 139, 210, 100 % );
+ selected-active-foreground: rgba ( 2, 20, 63, 100 % );
+ lightfg: rgba ( 88, 104, 117, 100 % );
+ separatorcolor: rgba ( 219, 223, 188, 100 % );
urgent-foreground: rgba ( 255, 129, 255, 100 % );
alternate-urgent-background: rgba ( 0, 0, 0, 0 % );
- active-foreground: rgba ( 138, 196, 255, 100 % );
lightbg: rgba ( 238, 232, 213, 100 % );
- selected-active-foreground: rgba ( 2, 20, 63, 100 % );
- alternate-active-background: rgba ( 0, 0, 0, 0 % );
- background: rgba ( 0, 0, 33, 87 % );
- alternate-normal-foreground: var(foreground);
- normal-background: rgba ( 0, 0, 0, 0 % );
- lightfg: rgba ( 88, 104, 117, 100 % );
- selected-normal-background: rgba ( 219, 223, 188, 100 % );
+ background-color: rgba ( 0, 0, 0, 0 % );
border-color: rgba ( 219, 223, 188, 100 % );
+ normal-background: rgba ( 0, 0, 0, 0 % );
+ selected-urgent-background: rgba ( 255, 129, 127, 100 % );
+ alternate-active-background: rgba ( 0, 0, 0, 0 % );
spacing: 2;
- separatorcolor: rgba ( 219, 223, 188, 100 % );
+ blue: rgba ( 38, 139, 210, 100 % );
+ alternate-normal-foreground: var(foreground);
urgent-background: rgba ( 0, 0, 0, 0 % );
- selected-urgent-background: rgba ( 255, 129, 127, 100 % );
+ selected-normal-foreground: rgba ( 2, 20, 63, 100 % );
+ active-foreground: rgba ( 138, 196, 255, 100 % );
+ background: rgba ( 0, 0, 33, 87 % );
+ selected-active-background: rgba ( 138, 196, 255, 100 % );
+ active-background: rgba ( 0, 0, 0, 0 % );
+ selected-normal-background: rgba ( 219, 223, 188, 100 % );
+ alternate-normal-background: rgba ( 0, 0, 0, 0 % );
+ foreground: rgba ( 219, 223, 188, 100 % );
+ selected-urgent-foreground: rgba ( 2, 20, 63, 100 % );
+ normal-foreground: var(foreground);
alternate-urgent-foreground: var(urgent-foreground);
- background-color: rgba ( 0, 0, 0, 0 % );
alternate-active-foreground: var(active-foreground);
- active-background: rgba ( 0, 0, 0, 0 % );
- selected-active-background: rgba ( 138, 196, 255, 100 % );
-}
-window {
- background-color: var(background);
- border: 1;
- padding: 5;
-}
-mainbox {
- border: 0;
- padding: 0;
-}
-message {
- border: 2px 0px 0px ;
- border-color: var(separatorcolor);
- padding: 1px ;
-}
-textbox {
- text-color: var(foreground);
-}
-listview {
- fixed-height: 0;
- border: 2px 0px 0px ;
- border-color: var(separatorcolor);
- spacing: 2px ;
- scrollbar: true;
- padding: 2px 0px 0px ;
}
element {
- border: 0;
padding: 1px ;
+ spacing: 5px ;
+ border: 0;
}
element normal.normal {
background-color: var(normal-background);
@@ -96,16 +72,24 @@ element alternate.active {
background-color: var(alternate-active-background);
text-color: var(alternate-active-foreground);
}
+element-text {
+ background-color: rgba ( 0, 0, 0, 0 % );
+ text-color: inherit;
+}
+element-icon {
+ background-color: rgba ( 0, 0, 0, 0 % );
+ text-color: inherit;
+}
scrollbar {
width: 4px ;
+ padding: 0;
+ handle-width: 8px ;
border: 0;
handle-color: var(normal-foreground);
- handle-width: 8px ;
- padding: 0;
}
mode-switcher {
- border: 2px 0px 0px ;
border-color: var(separatorcolor);
+ border: 2px 0px 0px ;
}
button {
spacing: 0;
@@ -116,9 +100,9 @@ button selected {
text-color: var(selected-normal-foreground);
}
inputbar {
+ padding: 1px ;
spacing: 0px ;
text-color: var(normal-foreground);
- padding: 1px ;
children: [ prompt,textbox-prompt-colon,entry,overlay,case-indicator ];
}
case-indicator {
@@ -134,12 +118,25 @@ prompt {
text-color: var(normal-foreground);
}
textbox-prompt-colon {
+ margin: 0px 0.3000em 0.0000em 0.0000em ;
expand: false;
str: ":";
- margin: 0px 0.3000em 0.0000em 0.0000em ;
text-color: inherit;
}
error-message {
background-color: rgba ( 0, 0, 0, 0 % );
text-color: var(normal-foreground);
}
+window {
+ padding: 5;
+ border: 1;
+}
+listview {
+ scrollbar: true;
+ spacing: 2px ;
+ border: 2px 0px 0px ;
+}
+message {
+ padding: 1px ;
+ border: 2px 0px 0px ;
+}
diff --git a/include/view-internal.h b/include/view-internal.h
index a00bd147..7ebee79d 100644
--- a/include/view-internal.h
+++ b/include/view-internal.h
@@ -30,9 +30,9 @@
#include "widgets/container.h"
#include "widgets/widget.h"
#include "widgets/textbox.h"
-#include "widgets/listview.h"
#include "widgets/box.h"
#include "widgets/icon.h"
+#include "widgets/listview.h"
#include "keyb.h"
#include "xcb.h"
#include "theme.h"
diff --git a/include/widgets/listview.h b/include/widgets/listview.h
index ec5861e1..c10e1831 100644
--- a/include/widgets/listview.h
+++ b/include/widgets/listview.h
@@ -61,7 +61,7 @@ typedef enum
*
* Update callback, this is called to set the value of each (visible) element.
*/
-typedef void ( *listview_update_callback )( textbox *tb, unsigned int entry, void *udata, TextBoxFontType type, gboolean full );
+typedef void ( *listview_update_callback )( textbox *tb,icon *ico, unsigned int entry, void *udata, TextBoxFontType *type, gboolean full );
/**
* Callback when a element is activated.
diff --git a/include/widgets/textbox.h b/include/widgets/textbox.h
index 6d666ff0..83831bfe 100644
--- a/include/widgets/textbox.h
+++ b/include/widgets/textbox.h
@@ -58,9 +58,6 @@ typedef struct
int markup;
int changed;
- cairo_surface_t *icon; // AA TODO - pass in icons for a textbox line if needed
- int icon_index;
-
int blink;
guint blink_timeout;
@@ -69,7 +66,6 @@ typedef struct
PangoFontMetrics *metrics;
PangoEllipsizeMode emode;
- int left_offset;
//
const char *theme_name;
} textbox;
@@ -86,7 +82,6 @@ typedef enum
TB_WRAP = 1 << 21,
TB_PASSWORD = 1 << 22,
TB_INDICATOR = 1 << 23,
- TB_ICON = 1 << 24,
} TextboxFlags;
/**
* Flags indicating current state of the textbox.
@@ -148,14 +143,6 @@ void textbox_font ( textbox *tb, TextBoxFontType tbft );
void textbox_text ( textbox *tb, const char *text );
/**
- * @param tb Handle to the textbox
- * @param icon The icon to show on the textbox
- *
- * Set the text to show. Cursor is moved to end (if visible)
- */
-void textbox_icon ( textbox *tb, cairo_surface_t *icon );
-
-/**
* @param tb Handle to the textbox
* @param action the #KeyBindingAction to execute on textbox
*
@@ -299,14 +286,6 @@ void textbox_set_pango_attributes ( textbox *tb, PangoAttrList *list );
/**
* @param tb Handle to the textbox
- * @param index character index to draw the icon at. -1 for no icon
- *
- * Sets the character index where the icon should be drawn
- */
-void textbox_set_icon_index ( textbox *tb, int index );
-
-/**
- * @param tb Handle to the textbox
*
* Get the list of currently active pango attributes.
*
diff --git a/include/widgets/widget.h b/include/widgets/widget.h
index 9370a49b..abe0c4f6 100644
--- a/include/widgets/widget.h
+++ b/include/widgets/widget.h
@@ -142,6 +142,15 @@ void widget_move ( widget *widget, short x, short y );
*/
WidgetType widget_type ( widget *widget );
+
+/**
+ * @param widget Handle to widget
+ * @param type The widget type.
+ *
+ * Set the widget type.
+ */
+void widget_set_type ( widget *widget, WidgetType type );
+
/**
* @param widget Handle to widget
*
diff --git a/source/theme.c b/source/theme.c
index bf91879f..b031a8a8 100644
--- a/source/theme.c
+++ b/source/theme.c
@@ -124,11 +124,54 @@ void rofi_theme_property_free ( Property *p )
g_slice_free ( Property, p );
}
+/**
+ * This function is a hack to insert backward support for older theme with the updated listvie structure.
+ */
+static void rofi_theme_insert_listview_backwards_fix ( void )
+{
+ GHashTable *table= g_hash_table_new_full ( g_str_hash, g_str_equal, NULL, (GDestroyNotify) rofi_theme_property_free );
+ ThemeWidget *t = rofi_theme_find_or_create_name ( rofi_theme, "element" );
+ ThemeWidget *tt = rofi_theme_find_or_create_name ( rofi_theme, "element-text" );
+ ThemeWidget *ti = rofi_theme_find_or_create_name ( rofi_theme, "element-icon" );
+
+ // Inherit text color
+ Property *ptc = rofi_theme_property_create ( P_INHERIT );
+ ptc->name = g_strdup("text-color");
+ g_hash_table_replace ( table, ptc->name, ptc );
+ // Transparent background
+ Property *ptb = rofi_theme_property_create ( P_COLOR );
+ ptb->name = g_strdup("background-color");
+ ptb->value.color.red = 0.0;
+ ptb->value.color.green = 0.0;
+ ptb->value.color.blue = 0.0;
+ ptb->value.color.alpha = 0.0;
+ g_hash_table_replace ( table, ptb->name, ptb );
+
+
+ rofi_theme_widget_add_properties ( tt, table);
+ rofi_theme_widget_add_properties ( ti, table);
+
+ /** Add spacing between icon and text. */
+ g_hash_table_destroy ( table );
+ table= g_hash_table_new_full ( g_str_hash, g_str_equal, NULL, (GDestroyNotify) rofi_theme_property_free );
+ Property *psp = rofi_theme_property_create ( P_PADDING );
+ psp->name = g_strdup( "spacing" );
+ RofiDistance d = (RofiDistance){5, ROFI_PU_PX, ROFI_HL_SOLID };
+ psp->value.padding = (RofiPadding){d,d,d,d};
+ g_hash_table_replace ( table, psp->name, psp );
+ rofi_theme_widget_add_properties ( t, table);
+ g_hash_table_destroy ( table );
+
+
+}
+
void rofi_theme_reset ( void )
{
rofi_theme_free ( rofi_theme );
rofi_theme = g_slice_new0 ( ThemeWidget );
rofi_theme->name = g_strdup ( "Root" );
+ // Hack to fix backwards compatibility.
+ rofi_theme_insert_listview_backwards_fix ( );
}
void rofi_theme_free ( ThemeWidget *widget )
diff --git a/source/view.c b/source/view.c
index e9b4d8d8..2f6ce5f0 100644
--- a/source/view.c
+++ b/source/view.c
@@ -928,15 +928,16 @@ inline static void rofi_view_nav_last ( RofiViewState * state )
listview_set_selected ( state->list_view, -1 );
}
-static void update_callback ( textbox *t, unsigned int index, void *udata, TextBoxFontType type, gboolean full )
+static void update_callback ( textbox *t,icon *ico, unsigned int index, void *udata, TextBoxFontType *type, gboolean full )
{
RofiViewState *state = (RofiViewState *) udata;
if ( full ) {
GList *add_list = NULL;
int fstate = 0;
char *text = mode_get_display_value ( state->sw, state->line_map[index], &fstate, &add_list, TRUE );
- type |= fstate;
- textbox_font ( t, type );
+ (*type) |= fstate;
+ // TODO needed for markup.
+ textbox_font ( t, *type );
// Move into list view.
textbox_text ( t, text );
PangoAttrList *list = textbox_get_pango_attributes ( t );
@@ -946,10 +947,11 @@ static void update_callback ( textbox *t, unsigned int index, void *udata, TextB
else{
list = pango_attr_list_new ();
}
- int icon_height = textbox_get_font_height ( t );
-
- cairo_surface_t *icon = mode_get_icon ( state->sw, state->line_map[index], icon_height );
- textbox_icon ( t, icon );
+ if( ico ) {
+ int icon_height = widget_get_desired_height( WIDGET(ico) );
+ cairo_surface_t *icon = mode_get_icon ( state->sw, state->line_map[index], icon_height );
+ icon_set_surface ( ico, icon );
+ }
if ( state->tokens && config.show_match ) {
RofiHighlightColorStyle th = { ROFI_HL_BOLD | ROFI_HL_UNDERLINE, { 0.0, 0.0, 0.0, 0.0 } };
@@ -967,8 +969,9 @@ static void update_callback ( textbox *t, unsigned int index, void *udata, TextB
else {
int fstate = 0;
mode_get_display_value ( state->sw, state->line_map[index], &fstate, NULL, FALSE );
- type |= fstate;
- textbox_font ( t, type );
+ (*type) |= fstate;
+ // TODO needed for markup.
+ textbox_font ( t, *type );
}
}
diff --git a/source/widgets/box.c b/source/widgets/box.c
index 11733a6f..874760c6 100644
--- a/source/widgets/box.c
+++ b/source/widgets/box.c
@@ -107,10 +107,6 @@ static int box_get_desired_height ( widget *wid )
continue;
}
active_widgets++;
- if ( child->expand == TRUE ) {
- height += widget_get_desired_height ( child );
- continue;
- }
height += widget_get_desired_height ( child );
}
if ( active_widgets > 0 ) {
diff --git a/source/widgets/listview.c b/source/widgets/listview.c
index cb7f0628..79367cdb 100644
--- a/source/widgets/listview.c
+++ b/source/widgets/listview.c
@@ -29,8 +29,10 @@
#include <glib.h>
#include <widgets/widget.h>
#include <widgets/textbox.h>
-#include <widgets/listview.h>
#include <widgets/scrollbar.h>
+#include <widgets/icon.h>
+#include <widgets/box.h>
+#include <widgets/listview.h>
#include "settings.h"
#include "theme.h"
@@ -58,6 +60,12 @@ typedef enum
RIGHT_TO_LEFT = 1
} MoveDirection;
+typedef struct {
+ box *box;
+ textbox *textbox;
+ icon *icon;
+} _listview_row;
+
struct _listview
{
widget widget;
@@ -78,6 +86,7 @@ struct _listview
unsigned int max_elements;
//
+ gboolean fixed_columns;
unsigned int cur_columns;
unsigned int req_elements;
unsigned int cur_elements;
@@ -95,7 +104,7 @@ struct _listview
ScrollType scroll_type;
- textbox **boxes;
+ _listview_row * boxes;
scrollbar *scrollbar;
listview_update_callback callback;
@@ -119,13 +128,79 @@ struct _listview
} barview;
};
+const char *const listview_theme_prop_names[][3] = {
+ /** Normal row */
+ { "normal.normal", "selected.normal", "alternate.normal" },
+ /** Urgent row */
+ { "normal.urgent", "selected.urgent", "alternate.urgent" },
+ /** Active row */
+ { "normal.active", "selected.active", "alternate.active" },
+};
+
+static void listview_set_style ( widget *w, TextBoxFontType tbft )
+{
+ TextBoxFontType t = tbft & STATE_MASK;
+ if ( w == NULL ) {
+ return;
+ }
+ // ACTIVE has priority over URGENT if both set.
+ if ( t == ( URGENT | ACTIVE ) ) {
+ t = ACTIVE;
+ }
+ switch ( ( tbft & FMOD_MASK ) )
+ {
+ case HIGHLIGHT:
+ widget_set_state ( w, listview_theme_prop_names[t][1] );
+ break;
+ case ALT:
+ widget_set_state ( w, listview_theme_prop_names[t][2] );
+ break;
+ default:
+ widget_set_state ( w, listview_theme_prop_names[t][0] );
+ break;
+ }
+}
+static void listview_create_row ( listview *lv, _listview_row *row )
+{
+ TextboxFlags flags = ( lv->multi_select ) ? TB_INDICATOR : 0;
+ row->box = box_create ( WIDGET ( lv ), "element",ROFI_ORIENTATION_HORIZONTAL );
+ widget_set_type ( WIDGET(row->box), WIDGET_TYPE_LISTVIEW_ELEMENT);
+ GList *list = rofi_theme_get_list ( WIDGET(row->box), "children", "element-icon,element-text");
+
+ row->textbox = NULL;
+ row->icon = NULL;
+
+ for ( GList *iter = g_list_first(list); iter != NULL;iter = g_list_next(iter)){
+ if ( strcasecmp((char *)iter->data, "element-icon") == 0 ) {
+ if ( config.show_icons ) {
+ row->icon = icon_create ( WIDGET ( row->box ), "element-icon" );
+ box_add ( row->box, WIDGET ( row->icon ), FALSE);
+ }
+ } else if ( strcasecmp ((char *)iter->data, "element-text") == 0 ){
+ row->textbox= textbox_create ( WIDGET ( row->box ), WIDGET_TYPE_TEXTBOX_TEXT, "element-text", TB_AUTOHEIGHT|flags, NORMAL, "DDD", 0, 0 );
+ box_add ( row->box, WIDGET ( row->textbox ), TRUE);
+ }
+ }
+ g_list_free_full ( list, g_free );
+}
+
+
+static void listview_set_state ( _listview_row r, TextBoxFontType type )
+{
+ listview_set_style ( WIDGET(r.box), type);
+ listview_set_style ( WIDGET(r.textbox), type);
+ if ( r.icon ) {
+ listview_set_style ( WIDGET(r.icon), type);
+ }
+ widget_queue_redraw ( WIDGET( r.box ) );
+}
static int listview_get_desired_height ( widget *wid );
static void listview_free ( widget *wid )
{
listview *lv = (listview *) wid;
for ( unsigned int i = 0; i < lv->cur_elements; i++ ) {
- widget_free ( WIDGET ( lv->boxes [i] ) );
+ widget_free ( WIDGET ( lv->boxes [i].box ) );
}
g_free ( lv->boxes );
@@ -200,7 +275,8 @@ static void update_element ( listview *lv, unsigned int tb, unsigned int index,
type = ( index ) == lv->selected ? HIGHLIGHT : type;
if ( lv->callback ) {
- lv->callback ( lv->boxes[tb], index, lv->udata, type, full );
+ lv->callback ( lv->boxes[tb].textbox, lv->boxes[tb].icon, index, lv->udata, &type, full );
+ listview_set_state ( lv->boxes[tb], type);
}
}
@@ -226,16 +302,17 @@ static void barview_draw ( widget *wid, cairo_t *draw )
if ( lv->barview.direction == LEFT_TO_RIGHT ) {
for ( unsigned int i = 0; i < max && width > 0; i++ ) {
update_element ( lv, i, i + offset, TRUE );
- int twidth = textbox_get_desired_width ( WIDGET ( lv->boxes[i] ) );
+ int twidth = textbox_get_desired_width ( WIDGET ( lv->boxes[i].textbox ) );
if ( twidth >= width ) {
if ( !first ) {
break;
}
twidth = width;
}
- textbox_moveresize ( lv->boxes[i], left_offset, top_offset, twidth, lv->element_height );
+ widget_move ( WIDGET(lv->boxes[i].box), left_offset, top_offset);
+ widget_resize ( WIDGET (lv->boxes[i].box), twidth, lv->element_height);
- widget_draw ( WIDGET ( lv->boxes[i] ), draw );
+ widget_draw ( WIDGET ( lv->boxes[i].box ), draw );
width -= twidth + spacing_hori;
left_offset += twidth + spacing_hori;
first = FALSE;
@@ -245,7 +322,7 @@ static void barview_draw ( widget *wid, cairo_t *draw )
else {
for ( unsigned int i = 0; i < lv->cur_elements && width > 0 && i <= offset; i++ ) {
update_element ( lv, i, offset - i, TRUE );
- int twidth = textbox_get_desired_width ( WIDGET ( lv->boxes[i] ) );
+ int twidth = textbox_get_desired_width ( WIDGET ( lv->boxes[i].textbox ) );
if ( twidth >= width ) {
if ( !first ) {
break;
@@ -253,9 +330,10 @@ static void barview_draw ( widget *wid, cairo_t *draw )
twidth = width;
}
right_offset -= twidth;
- textbox_moveresize ( lv->boxes[i], right_offset, top_offset, twidth, lv->element_height );
+ widget_move ( WIDGET(lv->boxes[i].box), left_offset, top_offset);
+ widget_resize ( WIDGET (lv->boxes[i].box), twidth, lv->element_height);
- widget_draw ( WIDGET ( lv->boxes[i] ), draw );
+ widget_draw ( WIDGET ( lv->boxes[i].box ), draw );
width -= twidth + spacing_hori;
right_offset -= spacing_hori;
first = FALSE;
@@ -264,7 +342,7 @@ static void barview_draw ( widget *wid, cairo_t *draw )
offset -= lv->barview.cur_visible - 1;
lv->last_offset = offset;
for ( unsigned int i = 0; i < ( lv->barview.cur_visible / 2 ); i++ ) {
- void * temp = lv->boxes[i];
+ _listview_row temp = lv->boxes[i];
int sw = lv->barview.cur_visible - i - 1;
lv->boxes[i] = lv->boxes[sw];
lv->boxes[sw] = temp;
@@ -275,7 +353,7 @@ static void barview_draw ( widget *wid, cairo_t *draw )
else {
for ( unsigned int i = 0; i < lv->barview.cur_visible; i++ ) {
update_element ( lv, i, i + offset, FALSE );
- widget_draw ( WIDGET ( lv->boxes[i] ), draw );
+ widget_draw ( WIDGET ( lv->boxes[i].box ), draw );
}
}
}
@@ -326,22 +404,24 @@ static void listview_draw ( widget *wid, cairo_t *draw )
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 );
+ 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 + ( ( i ) % lv->max_rows ) * ( lv->element_height + spacing_vert );
- textbox_moveresize ( lv->boxes[i], ex, ey, element_width, lv->element_height );
+ 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] ), draw );
+ widget_draw ( WIDGET ( lv->boxes[i].box ), draw );
}
lv->rchanged = FALSE;
}
else {
for ( unsigned int i = 0; i < max; i++ ) {
update_element ( lv, i, i + offset, FALSE );
- widget_draw ( WIDGET ( lv->boxes[i] ), draw );
+ widget_draw ( WIDGET ( lv->boxes[i].box ), draw );
}
}
}
@@ -359,30 +439,32 @@ static void _listview_draw ( widget *wid, cairo_t *draw )
barview_draw ( wid, draw );
}
}
+/**
+ * State names used for theming.
+ */
static void listview_recompute_elements ( listview *lv )
{
unsigned int newne = 0;
if ( lv->max_rows == 0 ) {
return;
}
- if ( lv->req_elements < lv->max_elements ) {
+ if ( !(lv->fixed_columns) && lv->req_elements < lv->max_elements ) {
newne = lv->req_elements;
lv->cur_columns = ( lv->req_elements + ( lv->max_rows - 1 ) ) / lv->max_rows;
}
else {
- newne = lv->max_elements;
+ newne = MIN( lv->req_elements, lv->max_elements);
lv->cur_columns = lv->menu_columns;
}
for ( unsigned int i = newne; i < lv->cur_elements; i++ ) {
- widget_free ( WIDGET ( lv->boxes[i] ) );
+ widget_free ( WIDGET ( lv->boxes[i].box ) );
}
- lv->boxes = g_realloc ( lv->boxes, newne * sizeof ( textbox* ) );
+ lv->boxes = g_realloc ( lv->boxes, newne * sizeof ( _listview_row ) );
if ( newne > 0 ) {
for ( unsigned int i = lv->cur_elements; i < newne; i++ ) {
- TextboxFlags flags = ( lv->multi_select ) ? TB_INDICATOR : 0;
- flags |= ( ( config.show_icons ) ? TB_ICON : 0 );
- lv->boxes[i] = textbox_create ( WIDGET ( lv ), WIDGET_TYPE_LISTVIEW_ELEMENT, "element", flags, NORMAL, "", 0, 0 );
- widget_set_trigger_action_handler ( WIDGET ( lv->boxes[i] ), listview_element_trigger_action, lv );
+ listview_create_row ( lv, &(lv->boxes[i]) );
+ widget_set_trigger_action_handler ( WIDGET ( lv->boxes[i].box ), listview_element_trigger_action, lv );
+ listview_set_state ( lv->boxes[i], NORMAL);
}
}
lv->rchanged = TRUE;
@@ -461,7 +543,7 @@ static widget *listview_find_mouse_target ( widget *wid, WidgetType type, gint x
unsigned int max = MIN ( lv->cur_elements, lv->req_elements - lv->last_offset );
unsigned int i;
for ( i = 0; i < max && target == NULL; i++ ) {
- widget *w = WIDGET ( lv->boxes[i] );
+ widget *w = WIDGET ( lv->boxes[i].box );
if ( widget_intersect ( w, x, y ) ) {
rx = x - widget_get_x_pos ( w );
ry = y - widget_get_y_pos ( w );
@@ -498,7 +580,7 @@ static WidgetTriggerActionResult listview_element_trigger_action ( widget *wid,
listview *lv = (listview *) user_data;
unsigned int max = MIN ( lv->cur_elements, lv->req_elements - lv->last_offset );
unsigned int i;
- for ( i = 0; i < max && WIDGET ( lv->boxes[i] ) != wid; i++ ) {
+ for ( i = 0; i < max && WIDGET ( lv->boxes[i].box) != wid; i++ ) {
}
if ( i == max ) {
return WIDGET_TRIGGER_ACTION_RESULT_IGNORED;
@@ -538,9 +620,10 @@ listview *listview_create ( widget *parent, const char *name, listview_update_ca
lv->scrollbar = scrollbar_create ( WIDGET ( lv ), "scrollbar" );
// Calculate height of an element.
//
- textbox *tb = textbox_create ( WIDGET ( lv ), WIDGET_TYPE_LISTVIEW_ELEMENT, "element", 0, NORMAL, "", 0, 0 );
- lv->element_height = textbox_get_estimated_height ( tb, lv->eh );
- widget_free ( WIDGET ( tb ) );
+ _listview_row row;
+ listview_create_row ( lv, &row);
+ lv->element_height = widget_get_desired_height ( WIDGET(row.box) );
+ widget_free ( WIDGET ( row.box ) );
lv->callback = cb;
lv->udata = udata;
@@ -552,6 +635,7 @@ listview *listview_create ( widget *parent, const char *name, listview_update_ca
lv->dynamic = rofi_theme_get_boolean ( WIDGET ( lv ), "dynamic", TRUE );
lv->reverse = rofi_theme_get_boolean ( WIDGET ( lv ), "reverse", reverse );
lv