diff options
-rw-r--r-- | include/theme.h | 11 | ||||
-rw-r--r-- | include/widgets/listview.h | 2 | ||||
-rw-r--r-- | lexer/theme-lexer.l | 6 | ||||
-rw-r--r-- | lexer/theme-parser.y | 44 | ||||
-rw-r--r-- | source/theme.c | 95 | ||||
-rw-r--r-- | source/view.c | 23 | ||||
-rw-r--r-- | source/widgets/listview.c | 2 |
7 files changed, 140 insertions, 43 deletions
diff --git a/include/theme.h b/include/theme.h index dae85d9c..6d0db4b8 100644 --- a/include/theme.h +++ b/include/theme.h @@ -3,7 +3,7 @@ #include <glib.h> typedef enum { P_INTEGER, - P_FLOAT, + P_DOUBLE, P_STRING, P_BOOLEAN, P_COLOR @@ -43,4 +43,13 @@ Property *rofi_theme_property_create ( PropertyType type ); void rofi_theme_property_free ( Property *p ); void rofi_theme_free ( Widget * ); void rofi_theme_parse_file ( const char *file ); + +/** + * Public API + */ + +int rofi_theme_get_integer ( const char *name, const char *property, int def ); +int rofi_theme_get_boolean ( const char *name, const char *property, int def ); +char *rofi_theme_get_string ( const char *name, const char *property, char *def ); +double rofi_theme_get_double ( const char *name, const char *property, double def ); #endif diff --git a/include/widgets/listview.h b/include/widgets/listview.h index 21ebe758..ba104e60 100644 --- a/include/widgets/listview.h +++ b/include/widgets/listview.h @@ -168,7 +168,7 @@ void listview_set_fixed_num_lines ( listview *lv, gboolean enabled ); * * Hide the scrollbar. */ -void listview_set_hide_scrollbar ( listview *lv, gboolean enabled ); +void listview_set_show_scrollbar ( listview *lv, gboolean enabled ); /** * @param lv Handler to the listview object * @param width Width in pixels diff --git a/lexer/theme-lexer.l b/lexer/theme-lexer.l index 60cf5680..59c67c28 100644 --- a/lexer/theme-lexer.l +++ b/lexer/theme-lexer.l @@ -19,11 +19,11 @@ int yylex(void); ";" { return PCLOSE;} "." { return NSEP; } [ \t] ; // ignore all whitespace -[0-9]+\.[0-9]+ { yylval.fval = g_ascii_strtod(yytext, NULL); return T_FLOAT;} +[0-9]+\.[0-9]+ { yylval.fval = g_ascii_strtod(yytext, NULL); return T_DOUBLE;} [0-9]+ { yylval.ival = (int)g_ascii_strtoll(yytext, NULL, 10); return T_INT;} (true|false) { yylval.bval= g_strcmp0(yytext, "true") == 0; return T_BOOLEAN;} -[a-zA-Z0-9]+ { yylval.sval = g_strdup(yytext); return N_STRING;} -\"[a-zA-Z0-9]+\" { yylval.sval = g_strdup(yytext); return T_STRING;} +[_\-a-zA-Z0-9]+ { yylval.sval = g_strdup(yytext); return N_STRING;} +\"[_\-a-zA-Z0-9 \t]+\" { yytext[yyleng-1] = '\0'; yylval.sval = g_strdup(&yytext[1]); return T_STRING;} #[0-9A-Fa-f]+ { yylval.colorval = (unsigned int)strtoull ( &yytext[1], NULL, 16); return T_COLOR;} [\r\n]+ ; diff --git a/lexer/theme-parser.y b/lexer/theme-parser.y index b30803cc..2079ddd1 100644 --- a/lexer/theme-parser.y +++ b/lexer/theme-parser.y @@ -29,7 +29,7 @@ Widget *rofi_theme = NULL; } %token <ival> T_INT -%token <fval> T_FLOAT +%token <fval> T_DOUBLE %token <sval> T_STRING %token <sval> N_STRING %token <bval> T_BOOLEAN @@ -43,22 +43,22 @@ Widget *rofi_theme = NULL; %token NSEP "Name separator"; %type <sval> class -%type <sval> entry +%type <sval> entry %type <sval> pvalue -%type <theme> entries -%type <theme> start +%type <theme> entries +%type <theme> start %type <name_path> name_path %type <property> property %type <property_list> property_list %type <property_list> properties %type <property_list> optional_properties -%start start +%start start %% start: optional_properties - entries { + entries { $$ = $2; if ( $1 != NULL ) { $$->properties = $1; @@ -66,7 +66,7 @@ start: } ; entries: - %empty { + %empty { // There is always a base widget. $$ = rofi_theme = (Widget*)g_malloc0 (sizeof(Widget)); rofi_theme->name = g_strdup ( "Window" ); @@ -77,12 +77,12 @@ entries: entry: class name_path - properties + properties { Widget *widget = rofi_theme_find_or_create_class ( rofi_theme , $1 ); g_free($1); for ( GList *iter = g_list_first ( $2 ); iter ; iter = g_list_next ( iter ) ) { - widget = rofi_theme_find_or_create_class ( widget, iter->data ); + widget = rofi_theme_find_or_create_class ( widget, iter->data ); } g_list_foreach ( $2, (GFunc)g_free , NULL ); g_list_free ( $2 ); @@ -100,15 +100,15 @@ entry: optional_properties : %empty { $$ = NULL; } | property_list { $$ = $1; } -; +; properties: BOPEN property_list BCLOSE { $$ = $2;} | BOPEN BCLOSE { $$ = NULL; } | %empty { $$ = NULL; } ; -property_list: +property_list: property { - $$ = g_hash_table_new_full ( g_str_hash, g_str_equal, NULL, (GDestroyNotify)rofi_theme_property_free ); + $$ = g_hash_table_new_full ( g_str_hash, g_str_equal, NULL, (GDestroyNotify)rofi_theme_property_free ); g_hash_table_replace ( $$, $1->name, $1 ); } | property_list property { @@ -121,27 +121,27 @@ property : pvalue PSEP T_INT PCLOSE { $$ = rofi_theme_property_create ( P_INTEGER ); $$->name = $1; - $$->value.i = $3; + $$->value.i = $3; } -| pvalue PSEP T_FLOAT PCLOSE { - $$ = rofi_theme_property_create ( P_FLOAT ); +| pvalue PSEP T_DOUBLE PCLOSE { + $$ = rofi_theme_property_create ( P_DOUBLE ); $$->name = $1; - $$->value.f = $3; + $$->value.f = $3; } -| pvalue PSEP T_COLOR PCLOSE { +| pvalue PSEP T_COLOR PCLOSE { $$ = rofi_theme_property_create ( P_COLOR ); $$->name = $1; - $$->value.color = $3; + $$->value.color = $3; } -| pvalue PSEP T_STRING PCLOSE { +| pvalue PSEP T_STRING PCLOSE { $$ = rofi_theme_property_create ( P_STRING ); $$->name = $1; - $$->value.s = $3; + $$->value.s = $3; } | pvalue PSEP T_BOOLEAN PCLOSE { $$ = rofi_theme_property_create ( P_BOOLEAN ); $$->name = $1; - $$->value.b = $3; + $$->value.b = $3; } ; @@ -155,7 +155,7 @@ class: name_path: %empty { $$ = NULL; } | N_STRING { $$ = g_list_append ( NULL, $1 );} -| name_path NSEP N_STRING { $$ = g_list_append ( $1, $3);} +| name_path NSEP N_STRING { $$ = g_list_append ( $1, $3);} ; diff --git a/source/theme.c b/source/theme.c index 7fb05816..16ec8dec 100644 --- a/source/theme.c +++ b/source/theme.c @@ -72,7 +72,7 @@ static void rofi_theme_print_property_index ( int depth, Property *p ) case P_INTEGER: printf("%d", p->value.i); break; - case P_FLOAT: + case P_DOUBLE: printf("%.2f", p->value.f); break; case P_BOOLEAN: @@ -112,6 +112,14 @@ extern int yyparse(); extern FILE* yyin; extern Widget *rofi_theme; +void yyerror(const char* s) { + fprintf(stderr, "Parse error: %s\n", s); + exit(EXIT_FAILURE); +} +/** + * Public API + */ + void rofi_theme_parse_file ( const char *file ) { yyin = fopen ( file, "rb"); @@ -122,7 +130,86 @@ void rofi_theme_parse_file ( const char *file ) while ( yyparse() ); } -void yyerror(const char* s) { - fprintf(stderr, "Parse error: %s\n", s); - exit(EXIT_FAILURE); +static Widget *rofi_theme_find ( const char *name ) +{ + Widget *widget = rofi_theme; + char **names = g_strsplit ( name, "." , 0 ); + int found = TRUE; + for ( unsigned int i = 0; found && names && names[i]; i++ ){ + found = FALSE; + for ( unsigned int j = 0; j < widget ->num_widgets;j++){ + if ( g_strcmp0(widget->widgets[j]->name, names[i]) == 0 ){ + widget = widget->widgets[j]; + found = TRUE; + break; + } + } + } + g_strfreev(names); + return widget; +} + +static Property *rofi_theme_find_property ( Widget *widget, PropertyType type, const char *property ) +{ + while ( widget ) { + if ( widget->properties && g_hash_table_contains ( widget->properties, property) ) { + Property *p = g_hash_table_lookup ( widget->properties, property); + if ( p->type == type ){ + return p; + } + } + widget = widget->parent; + } + return NULL; +} + +int rofi_theme_get_integer ( const char *name, const char *property, int def ) +{ + if ( rofi_theme == NULL ) { + return def; + } + Widget *widget = rofi_theme_find ( name ); + Property *p = rofi_theme_find_property ( widget, P_INTEGER, property ); + if ( p ){ + return p->value.i; + } + return def; +} + +int rofi_theme_get_boolean ( const char *name, const char *property, int def ) +{ + if ( rofi_theme == NULL ) { + return def; + } + Widget *widget = rofi_theme_find ( name ); + Property *p = rofi_theme_find_property ( widget, P_BOOLEAN, property ); + if ( p ){ + return p->value.b; + } + return def; +} + +char *rofi_theme_get_string ( const char *name, const char *property, char *def ) +{ + if ( rofi_theme == NULL ) { + return def; + } + Widget *widget = rofi_theme_find ( name ); + Property *p = rofi_theme_find_property ( widget, P_STRING, property ); + if ( p ){ + return p->value.s; + } + return def; +} +double rofi_theme_get_double ( const char *name, const char *property, double def ) +{ + if ( rofi_theme == NULL ) { + return def; + } + Widget *widget = rofi_theme_find ( name ); + Property *p = rofi_theme_find_property ( widget, P_DOUBLE, property ); + if ( p ){ + return p->value.b; + } + return def; } diff --git a/source/view.c b/source/view.c index ab88e13f..feec10da 100644 --- a/source/view.c +++ b/source/view.c @@ -58,6 +58,8 @@ #include "view.h" #include "view-internal.h" +#include "theme.h" + /** The Rofi View log domain */ #define LOG_DOMAIN "View" @@ -1426,16 +1428,15 @@ RofiViewState *rofi_view_create ( Mode *sw, state->main_box = box_create ( BOX_VERTICAL, state->border, state->border, state->width - 2 * state->border, state->height - 2 * state->border ); - box_set_padding ( state->main_box, config.line_margin ); + box_set_padding ( state->main_box, rofi_theme_get_integer ( "box.main_box", "padding",config.line_margin )); // we need this at this point so we can get height. unsigned int line_height = textbox_get_estimated_char_height (); rofi_view_calculate_window_and_element_width ( state ); state->input_bar = box_create ( BOX_HORIZONTAL, 0, 0, state->width - state->border, line_height ); - //box_set_padding ( state->input_bar, config.line_margin ); state->input_bar_separator = separator_create ( S_HORIZONTAL, 2 ); - separator_set_line_style_from_string ( state->input_bar_separator, config.separator_style ); + separator_set_line_style_from_string ( state->input_bar_separator, rofi_theme_get_string ( "separator.input_bar", "style", config.separator_style )); 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 ); @@ -1473,13 +1474,13 @@ RofiViewState *rofi_view_create ( Mode *sw, state->list_view = listview_create ( update_callback, state, config.element_height ); // Set configuration listview_set_multi_select ( state->list_view, ( state->menu_flags & MENU_INDICATOR ) == MENU_INDICATOR ); - listview_set_padding ( state->list_view, config.line_margin ); - listview_set_max_lines ( state->list_view, config.menu_lines ); - listview_set_max_columns ( state->list_view, config.menu_columns ); - listview_set_fixed_num_lines ( state->list_view, config.fixed_num_lines ); - listview_set_hide_scrollbar ( state->list_view, !config.hide_scrollbar ); - listview_set_scrollbar_width ( state->list_view, config.scrollbar_width ); - listview_set_cycle ( state->list_view, config.cycle ); + listview_set_padding ( state->list_view, rofi_theme_get_integer ( "listview", "padding", config.line_margin )); + listview_set_max_lines ( state->list_view, rofi_theme_get_integer ( "listview", "lines", config.menu_lines )); + listview_set_max_columns ( state->list_view, rofi_theme_get_integer ( "listview", "columns", config.menu_columns)); + listview_set_fixed_num_lines ( state->list_view, rofi_theme_get_boolean ( "listview", "fixed-height", config.fixed_num_lines )); + listview_set_show_scrollbar ( state->list_view, rofi_theme_get_boolean ( "listview", "scrollbar", !config.hide_scrollbar )); + listview_set_scrollbar_width ( state->list_view, rofi_theme_get_integer ( "listview", "scrollbar-width", config.scrollbar_width )); + listview_set_cycle ( state->list_view, rofi_theme_get_boolean ( "listview" , "cycle", config.cycle )); listview_set_scroll_type ( state->list_view, config.scroll_method ); listview_set_mouse_activated_cb ( state->list_view, rofi_view_listview_mouse_activated_cb, state ); @@ -1488,7 +1489,7 @@ RofiViewState *rofi_view_create ( Mode *sw, // Only enable widget when sidebar is enabled. if ( config.sidebar_mode ) { state->sidebar_bar = box_create ( BOX_HORIZONTAL, 0, 0, state->width - 2 * state->border, line_height ); - box_set_padding ( state->sidebar_bar, config.line_margin ); + box_set_padding ( state->sidebar_bar, rofi_theme_get_integer ( "box.sidebar", "padding",config.line_margin ) ); separator *sep = separator_create ( S_HORIZONTAL, 2 ); box_add ( state->main_box, WIDGET ( sep ), FALSE, TRUE ); separator_set_line_style_from_string ( sep, config.separator_style ); diff --git a/source/widgets/listview.c b/source/widgets/listview.c index d5f0efe0..47280d17 100644 --- a/source/widgets/listview.c +++ b/source/widgets/listview.c @@ -466,7 +466,7 @@ void listview_set_fixed_num_lines ( listview *lv, gboolean enabled ) lv->fixed_num_lines = enabled; } } -void listview_set_hide_scrollbar ( listview *lv, gboolean enabled ) +void listview_set_show_scrollbar ( listview *lv, gboolean enabled ) { if ( lv ) { if ( enabled ) { |