diff --git a/include/theme.h b/include/theme.h index 1d906a06..17853177 100644 --- a/include/theme.h +++ b/include/theme.h @@ -1,6 +1,7 @@ #ifndef THEME_H #define THEME_H #include +#include typedef enum { P_INTEGER, P_DOUBLE, @@ -65,4 +66,5 @@ 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 ); +void rofi_theme_get_color ( const char *name, const char *property, cairo_t *d); #endif diff --git a/include/widgets/box.h b/include/widgets/box.h index 10d6a5a2..4e5274fb 100644 --- a/include/widgets/box.h +++ b/include/widgets/box.h @@ -32,6 +32,7 @@ typedef enum } boxType; /** + * @param name The name of the widget. * @param type The packing direction of the newly created box. * @param x The x position of the box relative to its parent. * @param y The y position of the box relative to its parent. @@ -40,7 +41,7 @@ typedef enum * * @returns a newly created box, free with #widget_free */ -box * box_create ( boxType type, short x, short y, short w, short h ); +box * box_create ( const char *name, boxType type, short x, short y, short w, short h ); /** * @param box Handle to the box widget. @@ -61,13 +62,5 @@ void box_add ( box *box, widget *child, gboolean expand, gboolean end ); * @returns the minimum size in pixels. */ int box_get_fixed_pixels ( box *box ); - -/** - * @param box Handle to the box widget. - * @param padding The padding to apply. - * - * Set the padding to apply between the children in pixels. - */ -void box_set_padding ( box * box, unsigned int padding ); /*@}*/ #endif // ROFI_HBOX_H diff --git a/include/widgets/separator.h b/include/widgets/separator.h index f0f27f8e..3d94a989 100644 --- a/include/widgets/separator.h +++ b/include/widgets/separator.h @@ -37,6 +37,7 @@ typedef enum } separator_line_style; /** + * @param name The name of the widget. * @param type The type of separator. * @param sw The thickness of the separator. * @@ -44,22 +45,7 @@ typedef enum * * @returns a new separator, free with ::widget_free */ -separator *separator_create ( separator_type type, short sw ); +separator *separator_create ( const char *name, separator_type type, short sw ); -/** - * @param sp The separator widget handle. - * @param style_str String representation of the style. - * - * Sets the line style based on the string style_str - */ -void separator_set_line_style_from_string ( separator *sp, const char *style_str ); - -/** - * @param sp The separator widget handle. - * @param style The new style. - * - * Sets the line style. - */ -void separator_set_line_style ( separator *sp, separator_line_style style ); /*@}*/ #endif // ROFI_SEPARATOR_H diff --git a/include/widgets/widget-internal.h b/include/widgets/widget-internal.h index a50f3980..1638d9f1 100644 --- a/include/widgets/widget-internal.h +++ b/include/widgets/widget-internal.h @@ -45,5 +45,8 @@ struct _widget /** Free widget callback */ void ( *free )( struct _widget *widget ); + + /** Name of widget (used for theming) */ + char *name; }; #endif // WIDGET_INTERNAL_H diff --git a/include/widgets/widget.h b/include/widgets/widget.h index ba7fa841..02aadb11 100644 --- a/include/widgets/widget.h +++ b/include/widgets/widget.h @@ -173,5 +173,8 @@ void widget_set_clicked_handler ( widget *wid, widget_clicked_cb cb, void *udata * returns TRUE when handled. */ gboolean widget_motion_notify ( widget *wid, xcb_motion_notify_event_t *xme ); + + +void widget_set_name ( widget *wid, const char *name ); /*@}*/ #endif // ROFI_WIDGET_H diff --git a/lexer/theme-lexer.l b/lexer/theme-lexer.l index 90e66b39..8a747545 100644 --- a/lexer/theme-lexer.l +++ b/lexer/theme-lexer.l @@ -24,13 +24,22 @@ int yylex(void); (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 \t]+\" { yytext[yyleng-1] = '\0'; yylval.sval = g_strdup(&yytext[1]); return T_STRING;} -#[0-9A-Fa-f]+ { - union { unsigned int val; struct { unsigned char a,r,g,b;};} val; +#[0-9A-Fa-f]{8} { + union { unsigned int val; struct { unsigned char b,g,r,a;};} val; val.val = (unsigned int)strtoull ( &yytext[1], NULL, 16); yylval.colorval.alpha = val.a/255.0; - yylval.colorval.red = val.r/255.0; + yylval.colorval.red = val.r/255.0; yylval.colorval.green = val.g/255.0; - yylval.colorval.blue = val.b/255.0; + yylval.colorval.blue = val.b/255.0; + return T_COLOR; +} +#[0-9A-Fa-f]{6} { + union { unsigned int val; struct { unsigned char b,g,r,a;};} val; + val.val = (unsigned int)strtoull ( &yytext[1], NULL, 16); + yylval.colorval.alpha = 1.0; + yylval.colorval.red = val.r/255.0; + yylval.colorval.green = val.g/255.0; + yylval.colorval.blue = val.b/255.0; return T_COLOR; } [\r\n]+ ; diff --git a/source/theme.c b/source/theme.c index 7c0ca370..a4017076 100644 --- a/source/theme.c +++ b/source/theme.c @@ -217,3 +217,20 @@ double rofi_theme_get_double ( const char *name, const char *property, double d } return def; } +void rofi_theme_get_color ( const char *name, const char *property, cairo_t *d) +{ + if ( rofi_theme == NULL ) { + return ; + } + Widget *widget = rofi_theme_find ( name ); + Property *p = rofi_theme_find_property ( widget, P_COLOR, property ); + if ( p ){ + cairo_set_source_rgba ( d, + p->value.color.red, + p->value.color.green, + p->value.color.blue, + p->value.color.alpha + ); + + } +} diff --git a/source/view.c b/source/view.c index 01198876..28737d33 100644 --- a/source/view.c +++ b/source/view.c @@ -780,15 +780,18 @@ void rofi_view_update ( RofiViewState *state ) cairo_paint ( d ); cairo_set_operator ( d, CAIRO_OPERATOR_OVER ); color_background ( d ); + rofi_theme_get_color ( "window" , "background", d ); cairo_paint ( d ); } else { // Paint the background. color_background ( d ); + rofi_theme_get_color ( "window" , "background", d ); cairo_paint ( d ); } TICK_N ( "Background" ); color_border ( d ); + rofi_theme_get_color ( "window" , "foreground", d ); if ( config.menu_bw > 0 ) { cairo_save ( d ); @@ -1428,26 +1431,21 @@ RofiViewState *rofi_view_create ( Mode *sw, // Get active monitor size. TICK_N ( "Get active monitor" ); - state->main_box = box_create ( BOX_VERTICAL, + state->main_box = box_create ( "box.mainbox", BOX_VERTICAL, state->border, state->border, state->width - 2 * state->border, state->height - 2 * state->border ); - 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 ); - state->input_bar_separator = separator_create ( S_HORIZONTAL, 2 ); - separator_set_line_style_from_string ( state->input_bar_separator, config.separator_style ); - + state->input_bar = box_create ( "box.inputbar", BOX_HORIZONTAL, 0, 0, state->width - state->border, line_height ); + state->input_bar_separator = separator_create ( "separator.inputbar", S_HORIZONTAL, 2 ); // 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, rofi_theme_get_integer ( "box.sidebar", "padding",config.line_margin ) ); - separator *sep = separator_create ( S_HORIZONTAL, 2 ); - separator_set_line_style_from_string ( sep, config.separator_style ); + state->sidebar_bar = box_create ( "box.sidebar", BOX_HORIZONTAL, 0, 0, state->width - 2 * state->border, line_height ); + separator *sep = separator_create ( "separator.sidebar", S_HORIZONTAL, 2 ); box_add ( state->main_box, WIDGET ( state->sidebar_bar ), FALSE, TRUE ); box_add ( state->main_box, WIDGET ( sep ), FALSE, TRUE ); state->num_modi = rofi_get_num_enabled_modi (); @@ -1484,10 +1482,9 @@ RofiViewState *rofi_view_create ( Mode *sw, if ( message ) { textbox *message_tb = textbox_create ( TB_AUTOHEIGHT | TB_MARKUP | TB_WRAP, 0, 0, state->width - ( 2 * ( state->border ) ), -1, NORMAL, message ); - separator *sep = separator_create ( S_HORIZONTAL, 2 ); + separator *sep = separator_create ( "separator", S_HORIZONTAL, 2 ); box_add ( state->main_box, WIDGET ( sep ), FALSE, end); box_add ( state->main_box, WIDGET ( message_tb ), FALSE, end); - separator_set_line_style_from_string ( sep, config.separator_style ); } box_add ( state->main_box, WIDGET ( state->input_bar_separator ), FALSE, end ); @@ -1553,7 +1550,7 @@ int rofi_view_error_dialog ( const char *msg, int markup ) state->finalize = process_result; rofi_view_calculate_window_and_element_width ( state ); - state->main_box = box_create ( BOX_VERTICAL, + state->main_box = box_create ( "box.mainbox", BOX_VERTICAL, state->border, state->border, state->width - 2 * state->border, state->height - 2 * state->border ); state->text = textbox_create ( ( TB_AUTOHEIGHT | TB_WRAP ) + ( ( markup ) ? TB_MARKUP : 0 ), diff --git a/source/widgets/box.c b/source/widgets/box.c index 828ba832..9fb14f0f 100644 --- a/source/widgets/box.c +++ b/source/widgets/box.c @@ -29,9 +29,19 @@ #include "widgets/widget.h" #include "widgets/widget-internal.h" #include "widgets/box.h" +#include "theme.h" +#include "settings.h" #define LOG_DOMAIN "Widgets.Box" +/** + * @param box Handle to the box widget. + * @param padding The padding to apply. + * + * Set the padding to apply between the children in pixels. + */ +void box_set_padding ( box * box, unsigned int padding ); + struct _box { widget widget; @@ -263,10 +273,11 @@ static gboolean box_motion_notify ( widget *wid, xcb_motion_notify_event_t *xme return FALSE; } -box * box_create ( boxType type, short x, short y, short w, short h ) +box * box_create ( const char *name, boxType type, short x, short y, short w, short h ) { box *b = g_malloc0 ( sizeof ( box ) ); b->type = type; + b->widget.name = g_strdup (name); b->widget.x = x; b->widget.y = y; b->widget.w = w; @@ -279,6 +290,7 @@ box * box_create ( boxType type, short x, short y, short w, short h ) b->widget.motion_notify = box_motion_notify; b->widget.enabled = TRUE; + box_set_padding ( b, rofi_theme_get_integer ( b->widget.name, "padding",config.line_margin )); return b; } diff --git a/source/widgets/separator.c b/source/widgets/separator.c index 9bbd98d7..0ff69554 100644 --- a/source/widgets/separator.c +++ b/source/widgets/separator.c @@ -31,6 +31,23 @@ #include "widgets/separator.h" #include "x11-helper.h" #include "settings.h" +#include "theme.h" + +/** + * @param sp The separator widget handle. + * @param style_str String representation of the style. + * + * Sets the line style based on the string style_str + */ +void separator_set_line_style_from_string ( separator *sp, const char *style_str ); + +/** + * @param sp The separator widget handle. + * @param style The new style. + * + * Sets the line style. + */ +void separator_set_line_style ( separator *sp, separator_line_style style ); /** * Internal structure for the separator. @@ -49,11 +66,11 @@ const char *const _separator_style_dash = "dash"; static void separator_draw ( widget *, cairo_t * ); static void separator_free ( widget * ); -separator *separator_create ( separator_type type, short sw ) +separator *separator_create ( const char *name, separator_type type, short sw ) { separator *sb = g_malloc0 ( sizeof ( separator ) ); sb->type = type; - + sb->widget.name = g_strdup ( name ); sb->widget.x = 0; sb->widget.y = 0; if ( sb->type == S_HORIZONTAL ) { @@ -70,6 +87,9 @@ separator *separator_create ( separator_type type, short sw ) // Enabled by default sb->widget.enabled = TRUE; + + const char *line_style = rofi_theme_get_string ( sb->widget.name, "line-style", "solid"); + separator_set_line_style_from_string ( sb, line_style ); return sb; } @@ -109,6 +129,7 @@ static void separator_draw ( widget *wid, cairo_t *draw ) return; } color_separator ( draw ); + rofi_theme_get_color ( wid->name, "foreground", draw ); if ( sep->line_style == S_LINE_DASH ) { const double dashes[1] = { 4 }; cairo_set_dash ( draw, dashes, 1, 0.0 ); diff --git a/source/widgets/widget.c b/source/widgets/widget.c index c77ef1f9..93c14cff 100644 --- a/source/widgets/widget.c +++ b/source/widgets/widget.c @@ -68,8 +68,13 @@ void widget_draw ( widget *widget, cairo_t *d ) } void widget_free ( widget *wid ) { - if ( wid && wid->free ) { - wid->free ( wid ); + if ( wid ) { + if ( wid->name ) { + g_free ( wid->name ); + } + if ( wid->free ) { + wid->free ( wid ); + } } } @@ -163,3 +168,11 @@ gboolean widget_motion_notify ( widget *wid, xcb_motion_notify_event_t *xme ) return FALSE; } + +void widget_set_name ( widget *wid, const char *name ) +{ + if ( wid->name ) { + g_free(wid); + } + wid->name = g_strdup ( name ); +}