From 843ccc1e41504db4ed9ab38b052747b112779332 Mon Sep 17 00:00:00 2001 From: Dave Davenport Date: Wed, 28 Dec 2016 12:21:42 +0100 Subject: Update drawing, background per widget. --- include/widgets/widget-internal.h | 2 + source/theme.c | 8 +++- source/widgets/box.c | 8 ---- source/widgets/listview.c | 1 - source/widgets/scrollbar.c | 2 +- source/widgets/separator.c | 8 ++-- source/widgets/textbox.c | 92 +++++---------------------------------- source/widgets/widget.c | 19 ++++++++ 8 files changed, 43 insertions(+), 97 deletions(-) diff --git a/include/widgets/widget-internal.h b/include/widgets/widget-internal.h index 5d810cf2..940738fc 100644 --- a/include/widgets/widget-internal.h +++ b/include/widgets/widget-internal.h @@ -52,7 +52,9 @@ struct _widget /** Name of widget (used for theming) */ char *name; char *class_name; + const char *state; }; void widget_init ( widget *widget , const char *name, const char *class_name ); +void widget_set_state ( widget *widget, const char *state ); #endif // WIDGET_INTERNAL_H diff --git a/source/theme.c b/source/theme.c index bc5bfe25..bc322461 100644 --- a/source/theme.c +++ b/source/theme.c @@ -4,6 +4,7 @@ #include #include "theme.h" #include "lexer/theme-parser.h" +#include "helper.h" void yyerror ( YYLTYPE *ylloc, const char *); Widget *rofi_theme_find_or_create_class ( Widget *base, const char *class ) @@ -150,13 +151,16 @@ void rofi_theme_widget_add_properties ( Widget *widget, GHashTable *table ) void rofi_theme_parse_file ( const char *file ) { - yyin = fopen ( file, "rb"); + char *filename = rofi_expand_path ( file ); + yyin = fopen ( filename, "rb"); if ( yyin == NULL ){ - fprintf(stderr, "Failed to open file: '%s'\n", strerror ( errno ) ); + fprintf(stderr, "Failed to open file: %s: '%s'\n", filename, strerror ( errno ) ); + g_free(filename); return; } while ( yyparse() ); yylex_destroy(); + g_free(filename); } static Widget *rofi_theme_find_single ( Widget *widget, const char *name) { diff --git a/source/widgets/box.c b/source/widgets/box.c index 54f53f7b..e1b8e92a 100644 --- a/source/widgets/box.c +++ b/source/widgets/box.c @@ -195,18 +195,10 @@ static void hori_calculate_size ( box *b ) static void box_draw ( widget *wid, cairo_t *draw ) { box *b = (box *) wid; - // Store current state. - cairo_save ( draw ); - // Define a clipmask so we won't draw outside out widget. - cairo_rectangle ( draw, wid->x, wid->y, wid->w, wid->h ); - cairo_clip ( draw ); - // Set new x/y possition. - cairo_translate ( draw, wid->x, wid->y ); for ( GList *iter = g_list_first ( b->children ); iter != NULL; iter = g_list_next ( iter ) ) { widget * child = (widget *) iter->data; widget_draw ( child, draw ); } - cairo_restore ( draw ); } static void box_free ( widget *wid ) diff --git a/source/widgets/listview.c b/source/widgets/listview.c index 1c3935ce..99002b24 100644 --- a/source/widgets/listview.c +++ b/source/widgets/listview.c @@ -160,7 +160,6 @@ static void listview_draw ( widget *wid, cairo_t *draw ) if ( lv->cur_elements > 0 && lv->max_rows > 0 ) { cairo_save ( draw ); // Set new x/y possition. - cairo_translate ( draw, wid->x, wid->y ); unsigned int max = MIN ( lv->cur_elements, lv->req_elements - offset ); if ( lv->rchanged ) { unsigned int width = lv->widget.w - lv->spacing * ( lv->cur_columns - 1 ); diff --git a/source/widgets/scrollbar.c b/source/widgets/scrollbar.c index 87e0af07..b359746e 100644 --- a/source/widgets/scrollbar.c +++ b/source/widgets/scrollbar.c @@ -113,7 +113,7 @@ static void scrollbar_draw ( widget *wid, cairo_t *draw ) color_separator ( draw ); rofi_theme_get_color ( "@scrollbar", sb->widget.name, NULL, "foreground", draw ); - cairo_rectangle ( draw, sb->widget.x, sb->widget.y + y, sb->widget.w, height ); + cairo_rectangle ( draw, 0, 0 + y, sb->widget.w, height ); cairo_fill ( draw ); } static gboolean scrollbar_motion_notify ( widget *wid, xcb_motion_notify_event_t *xme ) diff --git a/source/widgets/separator.c b/source/widgets/separator.c index 2f5d7fd0..174768b4 100644 --- a/source/widgets/separator.c +++ b/source/widgets/separator.c @@ -139,15 +139,15 @@ static void separator_draw ( widget *wid, cairo_t *draw ) int height= wid->h-wid->pad.top-wid->pad.bottom; cairo_set_line_width ( draw, height ); double half = height / 2.0; - cairo_move_to ( draw, wid->x+wid->pad.left, wid->y + wid->pad.top +half ); - cairo_line_to ( draw, wid->x+wid->w-wid->pad.right, wid->y +wid->pad.top + half ); + cairo_move_to ( draw, wid->pad.left, wid->pad.top + half ); + cairo_line_to ( draw, wid->w-wid->pad.right, wid->pad.top + half ); } else { int width = wid->w-wid->pad.left-wid->pad.right; cairo_set_line_width ( draw, width); double half = width / 2.0; - cairo_move_to ( draw, wid->x + wid->pad.left + half, wid->y +wid->pad.top); - cairo_line_to ( draw, wid->x + wid->pad.left + half, wid->y + wid->h-wid->pad.bottom ); + cairo_move_to ( draw, wid->pad.left + half, wid->pad.top); + cairo_line_to ( draw, wid->pad.left + half, wid->h-wid->pad.bottom ); } cairo_stroke ( draw ); } diff --git a/source/widgets/textbox.c b/source/widgets/textbox.c index cf535256..1ee5ca4b 100644 --- a/source/widgets/textbox.c +++ b/source/widgets/textbox.c @@ -52,26 +52,6 @@ static int _textbox_get_height ( widget * ); */ static void textbox_cursor_end ( textbox *tb ); -/** - * Font + font color cache. - * Avoid re-loading font on every change on every textbox. - */ -typedef struct -{ - Color fg; - Color bg; - Color bgalt; - Color hlfg; - Color hlbg; -} RowColor; - -/** Number of states */ -#define num_states 3 -/** - * Different colors for the different states - */ -RowColor colors[num_states]; - /** Default pango context */ static PangoContext *p_context = NULL; /** The pango font metrics */ @@ -102,7 +82,8 @@ textbox* textbox_create ( const char *name, TextboxFlags flags, TextBoxFontType { textbox *tb = g_slice_new0 ( textbox ); - tb->widget.name = g_strdup ( name ); + widget_init ( WIDGET (tb), name, "@textbox" ); + tb->widget.draw = textbox_draw; tb->widget.free = textbox_free; tb->widget.resize = textbox_resize; @@ -153,26 +134,19 @@ void textbox_font ( textbox *tb, TextBoxFontType tbft ) if ( t == ( URGENT | ACTIVE ) ) { t = ACTIVE; } - RowColor *color = &( colors[t] ); switch ( ( tbft & FMOD_MASK ) ) { case HIGHLIGHT: - tb->color_bg = color->hlbg; - tb->color_fg = color->hlfg; - tb->theme_name = theme_prop_names[t][1]; + widget_set_state ( WIDGET (tb), theme_prop_names[t][1]); break; case ALT: - tb->color_bg = color->bgalt; - tb->color_fg = color->fg; - tb->theme_name = theme_prop_names[t][2]; + widget_set_state ( WIDGET (tb), theme_prop_names[t][2]); break; default: - tb->color_bg = color->bg; - tb->color_fg = color->fg; - tb->theme_name = theme_prop_names[t][0]; + widget_set_state ( WIDGET (tb), theme_prop_names[t][0]); break; } - if ( tb->tbft != tbft || tb->theme_name == NULL ) { + if ( tb->tbft != tbft || tb->widget.state == NULL ) { tb->update = TRUE; widget_queue_redraw ( WIDGET ( tb ) ); } @@ -361,15 +335,11 @@ static void texbox_update ( textbox *tb ) } y = config.line_padding + ( pango_font_metrics_get_ascent ( p_metrics ) - pango_layout_get_baseline ( tb->layout ) ) / PANGO_SCALE; - // Set ARGB - Color col = tb->color_bg; - cairo_set_source_rgba ( tb->main_draw, col.red, col.green, col.blue, col.alpha ); - rofi_theme_get_color ( "@textbox", tb->widget.name, tb->theme_name, "background", tb->main_draw); + // Set background transparency + cairo_set_source_rgba ( tb->main_draw, 0,0,0,0.0); cairo_paint ( tb->main_draw ); - col = tb->color_fg; - cairo_set_source_rgba ( tb->main_draw, col.red, col.green, col.blue, col.alpha ); - rofi_theme_get_color ( "@textbox",tb->widget.name, tb->theme_name, "foreground", tb->main_draw); + rofi_theme_get_color ( tb->widget.class_name, tb->widget.name, tb->widget.state, "foreground", tb->main_draw); // draw the cursor if ( tb->flags & TB_EDITABLE && tb->blink ) { cairo_rectangle ( tb->main_draw, x + cursor_x, y, cursor_width, font_height ); @@ -405,9 +375,8 @@ static void textbox_draw ( widget *wid, cairo_t *draw ) texbox_update ( tb ); /* Write buffer */ - - cairo_set_source_surface ( draw, tb->main_surface, tb->widget.x, tb->widget.y ); - cairo_rectangle ( draw, tb->widget.x, tb->widget.y, tb->widget.w, tb->widget.h ); + cairo_set_source_surface ( draw, tb->main_surface, 0,0 ); + cairo_rectangle ( draw, 0,0, tb->widget.w, tb->widget.h ); cairo_fill ( draw ); } @@ -718,47 +687,8 @@ gboolean textbox_append_char ( textbox *tb, const char *pad, const int pad_len ) return FALSE; } -/*** - * Font setup. - */ -static void textbox_parse_string ( const char *str, RowColor *color ) -{ - if ( str == NULL ) { - return; - } - char *cstr = g_strdup ( str ); - char *endp = NULL; - char *token; - int index = 0; - const char *const sep = ","; - for ( token = strtok_r ( cstr, sep, &endp ); token != NULL; token = strtok_r ( NULL, sep, &endp ) ) { - switch ( index ) - { - case 0: - color->bg = color_get ( g_strstrip ( token ) ); - break; - case 1: - color->fg = color_get ( g_strstrip ( token ) ); - break; - case 2: - color->bgalt = color_get ( g_strstrip ( token ) ); - break; - case 3: - color->hlbg = color_get ( g_strstrip ( token ) ); - break; - case 4: - color->hlfg = color_get ( g_strstrip ( token ) ); - break; - } - index++; - } - g_free ( cstr ); -} void textbox_setup ( void ) { - textbox_parse_string ( config.color_normal, &( colors[NORMAL] ) ); - textbox_parse_string ( config.color_urgent, &( colors[URGENT] ) ); - textbox_parse_string ( config.color_active, &( colors[ACTIVE] ) ); } void textbox_set_pango_context ( PangoContext *p ) diff --git a/source/widgets/widget.c b/source/widgets/widget.c index 04f52008..2a3dac58 100644 --- a/source/widgets/widget.c +++ b/source/widgets/widget.c @@ -12,6 +12,11 @@ void widget_init ( widget *widget , const char *name, const char *class_name ) } +void widget_set_state ( widget *widget, const char *state ) +{ + widget->state = state; +} + int widget_intersect ( const widget *widget, int x, int y ) { if ( widget == NULL ) { @@ -72,8 +77,22 @@ void widget_draw ( widget *widget, cairo_t *d ) { // Check if enabled and if draw is implemented. if ( widget && widget->enabled && widget->draw ) { + // Store current state. + cairo_save ( d ); + // Define a clipmask so we won't draw outside out widget. + cairo_rectangle ( d, widget->x, widget->y, widget->w, widget->h ); + cairo_clip ( d ); + rofi_theme_get_color ( widget->class_name, widget->name, widget->state, "background", d ); + + cairo_paint( d ) ; + + // Set new x/y possition. + cairo_translate ( d, widget->x, widget->y ); + widget->draw ( widget, d ); widget->need_redraw = FALSE; + + cairo_restore ( d ); } } void widget_free ( widget *wid ) -- cgit v1.2.3