From 55b043bcfaaadba44a7139fe8a9ab97db495eb46 Mon Sep 17 00:00:00 2001 From: Dave Davenport Date: Mon, 24 Jan 2022 19:43:08 +0100 Subject: [PATCH] [Theme] Add set type for testing. Allows a set of properties, f.e.: test: { "aap", "noot", "mies"} or tabs: { 1px, 10px, 1px, 3em } Issue: #1571 --- include/rofi-types.h | 2 ++ include/theme.h | 5 +++ lexer/theme-lexer.l | 77 ++++++++++++++++++++++++++------------------ lexer/theme-parser.y | 22 +++++++++++++ source/theme.c | 62 +++++++++++++++++++++++++++++++++++ 5 files changed, 136 insertions(+), 32 deletions(-) diff --git a/include/rofi-types.h b/include/rofi-types.h index 48de8f78..4e3462a3 100644 --- a/include/rofi-types.h +++ b/include/rofi-types.h @@ -32,6 +32,8 @@ typedef enum { P_HIGHLIGHT, /** List */ P_LIST, + /** Set */ + P_SET, /** Orientation */ P_ORIENTATION, /** Cursor */ diff --git a/include/theme.h b/include/theme.h index db41e16a..4bf7654d 100644 --- a/include/theme.h +++ b/include/theme.h @@ -467,4 +467,9 @@ void rofi_theme_free_parsed_files(void); */ void rofi_theme_print_parsed_files(int is_term); +/** + * Returns a list of allocated RofiDistance objects that should be + * freed. + */ +GList *rofi_theme_get_set_distance(const widget *widget, const char *property); #endif diff --git a/lexer/theme-lexer.l b/lexer/theme-lexer.l index 97e860f1..6404e07b 100644 --- a/lexer/theme-lexer.l +++ b/lexer/theme-lexer.l @@ -275,6 +275,9 @@ FORWARD_SLASH \/ LIST_OPEN \[ LIST_CLOSE \] +SET_OPEN \{ +SET_CLOSE \} + VAR_START "var" ENV_START "env" @@ -297,6 +300,7 @@ CONFIGURATION (?i:configuration) %x PROPERTIES_ENV_VAR %x PROPERTIES_VAR_DEFAULT %x PROPERTIES_LIST +%x PROPERTIES_SET %x NAMESTR %x SECTION %x DEFAULTS @@ -496,17 +500,17 @@ if ( queue == NULL ) { /* After Namestr/Classstr we want to go to state str, then to { */ {WHITESPACE}+ ; // ignore all whitespace -{WHITESPACE}+ ; // ignore all whitespace +{WHITESPACE}+ ; // ignore all whitespace
":" { g_queue_push_head ( queue, GINT_TO_POINTER (YY_START) ); BEGIN(PROPERTIES); return T_PSEP; } ";" { BEGIN(GPOINTER_TO_INT ( g_queue_pop_head ( queue ))); return T_PCLOSE;} -(true|false) { yylval->bval= g_strcmp0(yytext, "true") == 0; return T_BOOLEAN;} -{PNNUMBER}\.{NUMBER}+ { yylval->fval = g_ascii_strtod(yytext, NULL); return T_DOUBLE;} -{PNNUMBER} { yylval->ival = (int)g_ascii_strtoll(yytext, NULL, 10); return T_INT;} -{STRING} { yytext[yyleng-1] = '\0'; yylval->sval = g_strcompress(&yytext[1]); return T_STRING;} -{CHAR} { yytext[yyleng-1] = '\0'; yylval->cval = g_strcompress(&yytext[1])[0]; return T_CHAR;} +(true|false) { yylval->bval= g_strcmp0(yytext, "true") == 0; return T_BOOLEAN;} +{PNNUMBER}\.{NUMBER}+ { yylval->fval = g_ascii_strtod(yytext, NULL); return T_DOUBLE;} +{PNNUMBER} { yylval->ival = (int)g_ascii_strtoll(yytext, NULL, 10); return T_INT;} +{STRING} { yytext[yyleng-1] = '\0'; yylval->sval = g_strcompress(&yytext[1]); return T_STRING;} +{CHAR} { yytext[yyleng-1] = '\0'; yylval->cval = g_strcompress(&yytext[1])[0]; return T_CHAR;} -@{WORD} { +@{WORD} { yylval->sval = g_strdup(yytext+1); return T_LINK; } @@ -670,7 +674,7 @@ if ( queue == NULL ) { } {S_T_PARENT_LEFT} { return T_PARENT_LEFT; } {S_T_PARENT_RIGHT} { return T_PARENT_RIGHT; } -{COMMA} { return T_COMMA; } +{COMMA} { return T_COMMA; } {LIST_OPEN} { g_queue_push_head ( queue, GINT_TO_POINTER (YY_START) ); BEGIN(PROPERTIES_LIST); @@ -680,37 +684,46 @@ if ( queue == NULL ) { BEGIN(GPOINTER_TO_INT(g_queue_pop_head ( queue ))); return T_LIST_CLOSE; } -{FORWARD_SLASH} { return T_FORWARD_SLASH; } +{SET_OPEN} { + g_queue_push_head ( queue, GINT_TO_POINTER (YY_START) ); + BEGIN(PROPERTIES_SET); + return T_SET_OPEN; +} +{SET_CLOSE} { + BEGIN(GPOINTER_TO_INT(g_queue_pop_head ( queue ))); + return T_SET_CLOSE; +} +{FORWARD_SLASH} { return T_FORWARD_SLASH; } /* Position */ -{CENTER} { return T_POS_CENTER; } -{EAST} { return T_POS_EAST; } -{WEST} { return T_POS_WEST; } -{SOUTH} { return T_POS_SOUTH; } -{NORTH} { return T_POS_NORTH; } +{CENTER} { return T_POS_CENTER; } +{EAST} { return T_POS_EAST; } +{WEST} { return T_POS_WEST; } +{SOUTH} { return T_POS_SOUTH; } +{NORTH} { return T_POS_NORTH; } /* Highlight style */ -{NONE} { return T_NONE; } -{BOLD} { return T_BOLD; } -{ITALIC} { return T_ITALIC; } -{UNDERLINE} { return T_UNDERLINE; } -{STRIKETHROUGH} { return T_STRIKETHROUGH; } -{SMALLCAPS} { return T_SMALLCAPS; } +{NONE} { return T_NONE; } +{BOLD} { return T_BOLD; } +{ITALIC} { return T_ITALIC; } +{UNDERLINE} { return T_UNDERLINE; } +{STRIKETHROUGH} { return T_STRIKETHROUGH; } +{SMALLCAPS} { return T_SMALLCAPS; } -{ANGLE_DEG} { return T_ANGLE_DEG; } -{ANGLE_RAD} { return T_ANGLE_RAD; } -{ANGLE_GRAD} { return T_ANGLE_GRAD; } -{ANGLE_TURN} { return T_ANGLE_TURN; } +{ANGLE_DEG} { return T_ANGLE_DEG; } +{ANGLE_RAD} { return T_ANGLE_RAD; } +{ANGLE_GRAD} { return T_ANGLE_GRAD; } +{ANGLE_TURN} { return T_ANGLE_TURN; } -{ORIENTATION_HORI} { return ORIENTATION_HORI; } -{ORIENTATION_VERT} { return ORIENTATION_VERT; } +{ORIENTATION_HORI} { return ORIENTATION_HORI; } +{ORIENTATION_VERT} { return ORIENTATION_VERT; } -{CURSOR_DEF} { return CURSOR_DEF; } -{CURSOR_PTR} { return CURSOR_PTR; } -{CURSOR_TXT} { return CURSOR_TXT; } +{CURSOR_DEF} { return CURSOR_DEF; } +{CURSOR_PTR} { return CURSOR_PTR; } +{CURSOR_TXT} { return CURSOR_TXT; } -{COLOR_TRANSPARENT} { +{COLOR_TRANSPARENT} { return T_COLOR_TRANSPARENT; } -{COLOR_NAME} { +{COLOR_NAME} { for ( unsigned int iter = 0; iter < num_CSSColors; iter++) { if ( strcasecmp(yytext, CSSColors[iter].name )== 0 ) { yylval->colorval.alpha = 1.0; @@ -831,7 +844,7 @@ if ( queue == NULL ) { return T_ELEMENT; } -. { +. { yytext[yyleng-1] = '\0'; return T_ERROR_PROPERTY; } diff --git a/lexer/theme-parser.y b/lexer/theme-parser.y index 6deb38d0..1d109dcc 100644 --- a/lexer/theme-parser.y +++ b/lexer/theme-parser.y @@ -234,6 +234,9 @@ static ThemeColor hwb_to_rgb ( double h, double w, double b ) %token T_LIST_OPEN "List open ('[')" %token T_LIST_CLOSE "List close (']')" +%token T_SET_OPEN "Set open ('{')" +%token T_SET_CLOSE "Set close ('}')" + %token T_MODIFIER_ADD "Add ('+')" %token T_MODIFIER_SUBTRACT "Subtract ('-')" %token T_MODIFIER_MULTIPLY "Multiply ('*')" @@ -305,6 +308,8 @@ static ThemeColor hwb_to_rgb ( double h, double w, double b ) %type t_property_line_style %type t_property_element_list %type t_property_element_list_optional +%type t_property_element_set +%type t_property_element_set_optional %type t_property_orientation %type t_property_cursor %type t_name_prefix_optional @@ -580,6 +585,11 @@ t_property_element $$ = rofi_theme_property_create ( P_LIST ); $$->value.list = $2; } +| T_SET_OPEN t_property_element_set_optional T_SET_CLOSE { +printf("set create\n"); + $$ = rofi_theme_property_create ( P_SET ); + $$->value.list = $2; +} | t_property_orientation { $$ = rofi_theme_property_create ( P_ORIENTATION ); $$->value.i = $1; @@ -657,6 +667,18 @@ t_property_element_list $$ = g_list_append ( $1, $3 ); } ; +/** List of elements */ +t_property_element_set_optional +: %empty { $$ = NULL; } +| t_property_element_set { $$ = $1; } +; + +t_property_element_set +: t_property_element { $$ = g_list_append ( NULL, $1); } +| t_property_element_set T_COMMA t_property_element { + $$ = g_list_append ( $1, $3 ); +} +; /** * Position can be either center, diff --git a/source/theme.c b/source/theme.c index a565c19f..8ae5aa62 100644 --- a/source/theme.c +++ b/source/theme.c @@ -137,6 +137,10 @@ Property *rofi_theme_property_copy(const Property *p) { retv->value.list = g_list_copy_deep(p->value.list, rofi_g_list_strdup, NULL); break; + case P_SET: + retv->value.list = g_list_copy_deep( + p->value.list, (GCopyFunc)rofi_theme_property_copy, NULL); + break; case P_LINK: retv->value.link.name = g_strdup(p->value.link.name); retv->value.link.ref = NULL; @@ -206,6 +210,9 @@ void rofi_theme_property_free(Property *p) { } else if (p->type == P_LIST) { g_list_free_full(p->value.list, g_free); p->value.list = 0; + } else if (p->type == P_SET) { + g_list_free_full(p->value.list, (GDestroyNotify)rofi_theme_property_free); + p->value.list = 0; } else if (p->type == P_LINK) { g_free(p->value.link.name); if (p->value.link.def_value) { @@ -368,6 +375,16 @@ static void int_rofi_theme_print_property(Property *p) { } printf(" ]"); break; + case P_SET: + printf("{ "); + for (GList *iter = p->value.list; iter != NULL; iter = g_list_next(iter)) { + int_rofi_theme_print_property((Property *)iter->data); + if (iter->next != NULL) { + printf(","); + } + } + printf(" }"); + break; case P_ORIENTATION: printf("%s", (p->value.i == ROFI_ORIENTATION_HORIZONTAL) ? "horizontal" : "vertical"); @@ -1245,6 +1262,51 @@ GList *rofi_theme_get_list(const widget *widget, const char *property, return rofi_theme_get_list_inside(p, widget, property, defaults); } +static GList *rofi_theme_get_set_inside(Property *p, const widget *widget, + const char *property, + PropertyType child_type) { + if (p) { + if (p->type == P_INHERIT) { + if (widget->parent) { + ThemeWidget *parent = + rofi_theme_find_widget(widget->parent->name, widget->state, FALSE); + Property *pv = rofi_theme_find_property(parent, P_SET, property, FALSE); + return rofi_theme_get_set_inside(pv, widget->parent, property, + child_type); + } + } else if (p->type == P_SET) { + return p->value.list; + } + } + return NULL; +} +GList *rofi_theme_get_set_distance(const widget *widget, const char *property) { + ThemeWidget *wid2 = rofi_theme_find_widget(widget->name, widget->state, TRUE); + Property *p = rofi_theme_find_property(wid2, P_SET, property, TRUE); + GList *list = rofi_theme_get_set_inside(p, widget, property, P_PADDING); + GList *retv = NULL; + for (GList *iter = g_list_first(list); iter != NULL; + iter = g_list_next(iter)) { + Property *prop = (Property *)(iter->data); + if (prop->type == P_PADDING) { + RofiDistance *p = g_new0(RofiDistance, 1); + *p = prop->value.padding.left; + retv = g_list_append(retv, p); + } else if (prop->type == P_INTEGER) { + RofiDistance *p = g_new0(RofiDistance, 1); + RofiDistance d = + (RofiDistance){.base = {prop->value.i, ROFI_PU_PX, + ROFI_DISTANCE_MODIFIER_NONE, NULL, NULL}, + .style = ROFI_HL_SOLID}; + *p = d; + retv = g_list_append(retv, p); + } else { + g_warning("Invalid type detected in list."); + } + } + return retv; +} + static RofiHighlightColorStyle rofi_theme_get_highlight_inside(Property *p, widget *widget, const char *property,