From 713d41f619a1a8b311c3028a97e909e79cf88353 Mon Sep 17 00:00:00 2001 From: Dave Davenport Date: Mon, 9 Jan 2017 00:09:02 +0100 Subject: [PATCH] Allow matching highlighting to be set. Fixes #522 --- doc/themer.md | 2 ++ include/helper.h | 4 +++- include/theme.h | 42 +++++++++++++++++++++++++++++++++++++++++- lexer/theme-lexer.l | 25 +++++++++++++++++++++++-- lexer/theme-parser.y | 19 +++++++++++++++++++ source/helper.c | 37 +++++++++++++++++++++++++++++-------- source/theme.c | 30 ++++++++++++++++++++++++++++++ source/view.c | 4 +++- 8 files changed, 150 insertions(+), 13 deletions(-) diff --git a/doc/themer.md b/doc/themer.md index ffa8d24c..c7c82d92 100644 --- a/doc/themer.md +++ b/doc/themer.md @@ -118,6 +118,7 @@ Value supports the following formats: * {line-style} can be `dash` or `solid` and is optional. * padding: `({distance}){1,4}` * position: (center|north|south|east|west|northeast|northwest|southwest|southeast) + * highlight-style: (none|bold|underline|italic) Each property is closed by a semi-colon `;`; @@ -156,6 +157,7 @@ The following properties are currently supports: * background: color * foreground: color * text: The text color to use (falls back to foreground if not set) + * highlight: highlight {color} * listview: * columns: integer diff --git a/include/helper.h b/include/helper.h index af93aece..3398c0ef 100644 --- a/include/helper.h +++ b/include/helper.h @@ -3,6 +3,7 @@ #include "rofi.h" #include +#include /** * @defgroup HELPERS Helpers */ @@ -195,6 +196,7 @@ char * rofi_force_utf8 ( gchar *data, ssize_t length ); char * rofi_latin_to_utf8_strdup ( const char *input, gssize length ); /** + * @param th The ThemeHighlight * @param tokens Array of regexes used for matching * @param input The input string to find the matches on * @param retv The Attribute list to update with matches @@ -203,6 +205,6 @@ char * rofi_latin_to_utf8_strdup ( const char *input, gssize length ); * * @returns the updated retv list. */ -PangoAttrList *token_match_get_pango_attr ( GRegex **tokens, const char *input, PangoAttrList *retv ); +PangoAttrList *token_match_get_pango_attr ( ThemeHighlight th, GRegex **tokens, const char *input, PangoAttrList *retv ); /*@}*/ #endif // ROFI_HELPER_H diff --git a/include/theme.h b/include/theme.h index c1d187f0..37cdf29c 100644 --- a/include/theme.h +++ b/include/theme.h @@ -5,6 +5,21 @@ #include #include +/** Style of text highlight */ +typedef enum +{ + /** no highlight */ + HL_NONE = 0, + /** bold */ + HL_BOLD = 1, + /** underline */ + HL_UNDERLINE = 2, + /** italic */ + HL_ITALIC = 4, + /** color */ + HL_COLOR = 8 +} HighlightStyle; + /** Style of line */ typedef enum { @@ -69,6 +84,8 @@ typedef enum P_LINK, /** Position */ P_POSITION, + /** Highlight */ + P_HIGHLIGHT, } PropertyType; /** @@ -97,6 +114,16 @@ typedef struct Distance left; } Padding; +/** + * Theme highlight. + */ +typedef struct +{ + /** style to display */ + HighlightStyle style; + /** Color */ + ThemeColor color; +} ThemeHighlight; /** * Property structure. */ @@ -128,7 +155,9 @@ typedef struct Property char *name; /** Cached looked up ref */ struct Property *ref; - } link; + } link; + /** Highlight Style */ + ThemeHighlight highlight; } value; } Property; /** @@ -320,6 +349,17 @@ 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 ); +/** + * @param widget The widget to query + * @param property The property to query. + * @param th The default value. + * + * Obtain the highlight . + * + * @returns The highlight of this property for this widget. + */ +ThemeHighlight rofi_theme_get_highlight ( widget *widget, const char *property, ThemeHighlight th ); + /** * @param d The distance handle. * @param ori The orientation. diff --git a/lexer/theme-lexer.l b/lexer/theme-lexer.l index 5a7540c1..843eeccb 100644 --- a/lexer/theme-lexer.l +++ b/lexer/theme-lexer.l @@ -69,6 +69,11 @@ SOUTH "south" EAST "east" WEST "west" +NONE "none" +BOLD "bold" +UNDERLINE "underline" +ITALIC "italic" + LS_DASH "dash" LS_SOLID "solid" @@ -302,10 +307,26 @@ if ( queue == NULL ){ yylval->ival = WL_NORTH; return T_POSITION; } -NORTH { +{NORTH} { yylval->ival = WL_NORTH; return T_POSITION; } +{NONE} { + yylval->ival = HL_NONE; + return T_HIGHLIGHT_STYLE; +} +{BOLD} { + yylval->ival = HL_BOLD; + return T_HIGHLIGHT_STYLE; +} +{ITALIC} { + yylval->ival = HL_ITALIC; + return T_HIGHLIGHT_STYLE; +} +{UNDERLINE} { + yylval->ival = HL_UNDERLINE; + return T_HIGHLIGHT_STYLE; +} <> { g_queue_free ( queue ); // Reset pointer to NULL @@ -325,7 +346,7 @@ if ( queue == NULL ){ const char *error_msg = "Expected 'root' element or a 'named' element.\n"\ "Place all global properties in a root element:\n"\ " * {\n"\ - " }\n"; + " }\n"; YY_FATAL_ERROR( error_msg ); } <*>. { diff --git a/lexer/theme-parser.y b/lexer/theme-parser.y index 59317b52..055add3b 100644 --- a/lexer/theme-parser.y +++ b/lexer/theme-parser.y @@ -38,6 +38,7 @@ int yylex (YYSTYPE *, YYLTYPE *); %token T_STRING %token N_STRING %token T_POSITION; +%token T_HIGHLIGHT_STYLE %token NAME_ELEMENT "Element name" %token T_BOOLEAN %token T_COLOR @@ -54,6 +55,7 @@ int yylex (YYSTYPE *, YYLTYPE *); %token WHITESPACE "White space"; %token PDEFAULTS "Default settings"; +%type highlight_styles %type entry %type pvalue %type entries @@ -171,8 +173,25 @@ property $$->name = $1; $$->value.i = $3; } +| pvalue PSEP highlight_styles T_COLOR PCLOSE { + $$ = rofi_theme_property_create ( P_HIGHLIGHT ); + $$->name = $1; + $$->value.highlight.style = $3|HL_COLOR; + $$->value.highlight.color = $4; +} +| pvalue PSEP highlight_styles PCLOSE { + $$ = rofi_theme_property_create ( P_HIGHLIGHT ); + $$->name = $1; + $$->value.highlight.style = $3; +} ; +highlight_styles: + T_HIGHLIGHT_STYLE { $$ = $1; } +| highlight_styles T_HIGHLIGHT_STYLE { + $$ = $1 | $2; +} +; pvalue: N_STRING { $$ = $1; } name_path: diff --git a/source/helper.c b/source/helper.c index 84307bdd..48fbf13d 100644 --- a/source/helper.c +++ b/source/helper.c @@ -391,7 +391,7 @@ int find_arg_char ( const char * const key, char *val ) return FALSE; } -PangoAttrList *token_match_get_pango_attr ( GRegex **tokens, const char *input, PangoAttrList *retv ) +PangoAttrList *token_match_get_pango_attr ( ThemeHighlight th, GRegex **tokens, const char *input, PangoAttrList *retv ) { // Do a tokenized match. if ( tokens ) { @@ -401,14 +401,35 @@ PangoAttrList *token_match_get_pango_attr ( GRegex **tokens, const char *input, while ( g_match_info_matches ( gmi ) ) { int count = g_match_info_get_match_count ( gmi ); for ( int index = ( count > 1 ) ? 1 : 0; index < count; index++ ) { - int start, end; + int start, end; g_match_info_fetch_pos ( gmi, index, &start, &end ); - PangoAttribute *pa = pango_attr_underline_new ( PANGO_UNDERLINE_SINGLE ); - PangoAttribute *pa2 = pango_attr_weight_new ( PANGO_WEIGHT_BOLD ); - pa2->start_index = pa->start_index = start; - pa2->end_index = pa->end_index = end; - pango_attr_list_insert ( retv, pa ); - pango_attr_list_insert ( retv, pa2 ); + if ( th.style & HL_BOLD ) { + PangoAttribute *pa = pango_attr_weight_new ( PANGO_WEIGHT_BOLD ); + pa->start_index = start; + pa->end_index = end; + pango_attr_list_insert ( retv, pa ); + } + if ( th.style & HL_UNDERLINE ) { + PangoAttribute *pa = pango_attr_underline_new ( PANGO_UNDERLINE_SINGLE ); + pa->start_index = start; + pa->end_index = end; + pango_attr_list_insert ( retv, pa ); + } + if ( th.style & HL_ITALIC ) { + PangoAttribute *pa = pango_attr_style_new ( PANGO_STYLE_ITALIC ); + pa->start_index = start; + pa->end_index = end; + pango_attr_list_insert ( retv, pa ); + } + if ( th.style & HL_COLOR ) { + PangoAttribute *pa = pango_attr_foreground_new ( + th.color.red * 65535, + th.color.green * 65535, + th.color.blue * 65535 ); + pa->start_index = start; + pa->end_index = end; + pango_attr_list_insert ( retv, pa ); + } } g_match_info_next ( gmi, NULL ); } diff --git a/source/theme.c b/source/theme.c index 0defa28b..b7e89ec9 100644 --- a/source/theme.c +++ b/source/theme.c @@ -111,6 +111,25 @@ static void rofi_theme_print_property_index ( size_t pnl, int depth, Property *p printf ( "%*s%s:%*s ", depth, "", p->name, (int) pnl - pl, "" ); switch ( p->type ) { + case P_HIGHLIGHT: + if ( p->value.highlight.style & HL_BOLD ) { + printf ( "bold " ); + } + if ( p->value.highlight.style & HL_UNDERLINE ) { + printf ( "underline " ); + } + if ( p->value.highlight.style & HL_ITALIC ) { + printf ( "italic " ); + } + if ( p->value.highlight.style & HL_COLOR ) { + printf ( "#%02X%02X%02X%02X", + (unsigned char) ( p->value.highlight.color.alpha * 255.0 ), + (unsigned char) ( p->value.highlight.color.red * 255.0 ), + (unsigned char) ( p->value.highlight.color.green * 255.0 ), + (unsigned char) ( p->value.highlight.color.blue * 255.0 ) ); + } + printf ( ";" ); + break; case P_POSITION: printf ( "%s;", WindowLocationStr[p->value.i] ); break; @@ -486,6 +505,17 @@ Padding rofi_theme_get_padding ( const widget *widget, const char *property, Pad g_log ( LOG_DOMAIN, G_LOG_LEVEL_DEBUG, "Theme entry: #%s %s property %s unset.", widget->name, widget->state ? widget->state : "", property ); return pad; } +ThemeHighlight rofi_theme_get_highlight ( widget *widget, const char *property, ThemeHighlight th ) +{ + ThemeWidget *wid = rofi_theme_find_widget ( widget->name, widget->state, FALSE ); + Property *p = rofi_theme_find_property ( wid, P_HIGHLIGHT, property, FALSE ); + if ( p ) { + return p->value.highlight; + } + g_log ( LOG_DOMAIN, G_LOG_LEVEL_DEBUG, "Theme entry: #%s %s property %s unset.", widget->name, widget->state ? widget->state : "", property ); + return th; +} + int distance_get_pixel ( Distance d, Orientation ori ) { if ( d.type == PW_EM ) { diff --git a/source/view.c b/source/view.c index 814a18c3..e0b5c46c 100644 --- a/source/view.c +++ b/source/view.c @@ -834,7 +834,9 @@ static void update_callback ( textbox *t, unsigned int index, void *udata, TextB else{ list = pango_attr_list_new (); } - token_match_get_pango_attr ( state->tokens, textbox_get_visible_text ( t ), list ); + ThemeHighlight th = { HL_BOLD | HL_UNDERLINE, { 0.0, 0.0, 0.0, 0.0 } }; + th = rofi_theme_get_highlight ( WIDGET ( t ), "highlight", th ); + token_match_get_pango_attr ( th, state->tokens, textbox_get_visible_text ( t ), list ); textbox_set_pango_attributes ( t, list ); pango_attr_list_unref ( list ); }