diff options
author | Dave Davenport <qball@blame.services> | 2022-01-24 19:43:08 +0100 |
---|---|---|
committer | Dave Davenport <qball@blame.services> | 2022-01-24 19:43:08 +0100 |
commit | 55b043bcfaaadba44a7139fe8a9ab97db495eb46 (patch) | |
tree | 9f2830c3c78e1cec033e5e38abb4c7560930c9c2 | |
parent | 50b85ba95480976b972affeaa4522da133c9037d (diff) |
[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
-rw-r--r-- | include/rofi-types.h | 2 | ||||
-rw-r--r-- | include/theme.h | 5 | ||||
-rw-r--r-- | lexer/theme-lexer.l | 85 | ||||
-rw-r--r-- | lexer/theme-parser.y | 22 | ||||
-rw-r--r-- | source/theme.c | 62 |
5 files changed, 140 insertions, 36 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 { */ <INITIAL,SECTION>{WHITESPACE}+ ; // ignore all whitespace -<PROPERTIES,PROPERTIES_ENV,PROPERTIES_VAR_DEFAULT,PROPERTIES_LIST,PROPERTIES_ENV_VAR,PROPERTIES_VAR,MEDIA_CONTENT>{WHITESPACE}+ ; // ignore all whitespace +<PROPERTIES,PROPERTIES_ENV,PROPERTIES_VAR_DEFAULT,PROPERTIES_LIST,PROPERTIES_SET,PROPERTIES_ENV_VAR,PROPERTIES_VAR,MEDIA_CONTENT>{WHITESPACE}+ ; // ignore all whitespace <SECTION>":" { g_queue_push_head ( queue, GINT_TO_POINTER (YY_START) ); BEGIN(PROPERTIES); return T_PSEP; } <PROPERTIES>";" { BEGIN(GPOINTER_TO_INT ( g_queue_pop_head ( queue ))); return T_PCLOSE;} -<PROPERTIES,PROPERTIES_ENV,PROPERTIES_VAR_DEFAULT>(true|false) { yylval->bval= g_strcmp0(yytext, "true") == 0; return T_BOOLEAN;} -<PROPERTIES,PROPERTIES_ENV,PROPERTIES_VAR_DEFAULT,MEDIA_CONTENT>{PNNUMBER}\.{NUMBER}+ { yylval->fval = g_ascii_strtod(yytext, NULL); return T_DOUBLE;} -<PROPERTIES,PROPERTIES_ENV,PROPERTIES_VAR_DEFAULT,MEDIA_CONTENT>{PNNUMBER} { yylval->ival = (int)g_ascii_strtoll(yytext, NULL, 10); return T_INT;} -<PROPERTIES,PROPERTIES_ENV,PROPERTIES_VAR_DEFAULT>{STRING} { yytext[yyleng-1] = '\0'; yylval->sval = g_strcompress(&yytext[1]); return T_STRING;} -<PROPERTIES,PROPERTIES_ENV,PROPERTIES_VAR_DEFAULT>{CHAR} { yytext[yyleng-1] = '\0'; yylval->cval = g_strcompress(&yytext[1])[0]; return T_CHAR;} +<PROPERTIES,PROPERTIES_SET,PROPERTIES_ENV,PROPERTIES_VAR_DEFAULT>(true|false) { yylval->bval= g_strcmp0(yytext, "true") == 0; return T_BOOLEAN;} +<PROPERTIES,PROPERTIES_SET,PROPERTIES_ENV,PROPERTIES_VAR_DEFAULT,MEDIA_CONTENT>{PNNUMBER}\.{NUMBER}+ { yylval->fval = g_ascii_strtod(yytext, NULL); return T_DOUBLE;} +<PROPERTIES,PROPERTIES_SET,PROPERTIES_ENV,PROPERTIES_VAR_DEFAULT,MEDIA_CONTENT>{PNNUMBER} { yylval->ival = (int)g_ascii_strtoll(yytext, NULL, 10); return T_INT;} +<PROPERTIES,PROPERTIES_SET,PROPERTIES_ENV,PROPERTIES_VAR_DEFAULT>{STRING} { yytext[yyleng-1] = '\0'; yylval->sval = g_strcompress(&yytext[1]); return T_STRING;} +<PROPERTIES,PROPERTIES_SET,PROPERTIES_ENV,PROPERTIES_VAR_DEFAULT>{CHAR} { yytext[yyleng-1] = '\0'; yylval->cval = g_strcompress(&yytext[1])[0]; return T_CHAR;} -<PROPERTIES,PROPERTIES_ENV,PROPERTIES_VAR_DEFAULT>@{WORD} { +<PROPERTIES,PROPERTIES_SET,PROPERTIES_ENV,PROPERTIES_VAR_DEFAULT>@{WORD} { yylval->sval = g_strdup(yytext+1); return T_LINK; } @@ -670,7 +674,7 @@ if ( queue == NULL ) { } <PROPERTIES,PROPERTIES_ENV,PROPERTIES_VAR_DEFAULT>{S_T_PARENT_LEFT} { return T_PARENT_LEFT; } <PROPERTIES,PROPERTIES_ENV,PROPERTIES_VAR_DEFAULT>{S_T_PARENT_RIGHT} { return T_PARENT_RIGHT; } -<PROPERTIES,PROPERTIES_ENV,PROPERTIES_VAR_DEFAULT,PROPERTIES_LIST>{COMMA} { return T_COMMA; } +<PROPERTIES,PROPERTIES_SET,PROPERTIES_ENV,PROPERTIES_VAR_DEFAULT,PROPERTIES_LIST>{COMMA} { return T_COMMA; } <PROPERTIES,PROPERTIES_ENV,PROPERTIES_VAR_DEFAULT>{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; } -<PROPERTIES,PROPERTIES_ENV,PROPERTIES_VAR_DEFAULT>{FORWARD_SLASH} { return T_FORWARD_SLASH; } +<PROPERTIES,PROPERTIES_ENV,PROPERTIES_VAR_DEFAULT>{SET_OPEN} { + g_queue_push_head ( queue, GINT_TO_POINTER (YY_START) ); + BEGIN(PROPERTIES_SET); + return T_SET_OPEN; +} +<PROPERTIES_SET>{SET_CLOSE} { + BEGIN(GPOINTER_TO_INT(g_queue_pop_head ( queue ))); + return T_SET_CLOSE; +} +<PROPERTIES,PROPERTIES_SET,PROPERTIES_ENV,PROPERTIES_VAR_DEFAULT>{FORWARD_SLASH} { return T_FORWARD_SLASH; } /* Position */ -<PROPERTIES,PROPERTIES_ENV,PROPERTIES_VAR_DEFAULT>{CENTER} { return T_POS_CENTER; } -<PROPERTIES,PROPERTIES_ENV,PROPERTIES_VAR_DEFAULT>{EAST} { return T_POS_EAST; } -<PROPERTIES,PROPERTIES_ENV,PROPERTIES_VAR_DEFAULT>{WEST} { return T_POS_WEST; } -<PROPERTIES,PROPERTIES_ENV,PROPERTIES_VAR_DEFAULT>{SOUTH} { return T_POS_SOUTH; } -<PROPERTIES,PROPERTIES_ENV,PROPERTIES_VAR_DEFAULT>{NORTH} { return T_POS_NORTH; } +<PROPERTIES,PROPERTIES_SET,PROPERTIES_ENV,PROPERTIES_VAR_DEFAULT>{CENTER} { return T_POS_CENTER; } +<PROPERTIES,PROPERTIES_SET,PROPERTIES_ENV,PROPERTIES_VAR_DEFAULT>{EAST} { return T_POS_EAST; } +<PROPERTIES,PROPERTIES_SET,PROPERTIES_ENV,PROPERTIES_VAR_DEFAULT>{WEST} { return T_POS_WEST; } +<PROPERTIES,PROPERTIES_SET,PROPERTIES_ENV,PROPERTIES_VAR_DEFAULT>{SOUTH} { return T_POS_SOUTH; } +<PROPERTIES,PROPERTIES_SET,PROPERTIES_ENV,PROPERTIES_VAR_DEFAULT>{NORTH} { return T_POS_NORTH; } /* Highlight style */ -<PROPERTIES,PROPERTIES_ENV,PROPERTIES_VAR_DEFAULT>{NONE} { return T_NONE; } -<PROPERTIES,PROPERTIES_ENV,PROPERTIES_VAR_DEFAULT>{BOLD} { return T_BOLD; } -<PROPERTIES,PROPERTIES_ENV,PROPERTIES_VAR_DEFAULT>{ITALIC} { return T_ITALIC; } -<PROPERTIES,PROPERTIES_ENV,PROPERTIES_VAR_DEFAULT>{UNDERLINE} { return T_UNDERLINE; } -<PROPERTIES,PROPERTIES_ENV,PROPERTIES_VAR_DEFAULT>{STRIKETHROUGH} { return T_STRIKETHROUGH; } -<PROPERTIES,PROPERTIES_ENV,PROPERTIES_VAR_DEFAULT>{SMALLCAPS} { return T_SMALLCAPS; } - -<PROPERTIES,PROPERTIES_ENV,PROPERTIES_VAR_DEFAULT>{ANGLE_DEG} { return T_ANGLE_DEG; } -<PROPERTIES,PROPERTIES_ENV,PROPERTIES_VAR_DEFAULT>{ANGLE_RAD} { return T_ANGLE_RAD; } -<PROPERTIES,PROPERTIES_ENV,PROPERTIES_VAR_DEFAULT>{ANGLE_GRAD} { return T_ANGLE_GRAD; } -<PROPERTIES,PROPERTIES_ENV,PROPERTIES_VAR_DEFAULT>{ANGLE_TURN} { return T_ANGLE_TURN; } - -<PROPERTIES,PROPERTIES_ENV,PROPERTIES_VAR_DEFAULT>{ORIENTATION_HORI} { return ORIENTATION_HORI; } -<PROPERTIES,PROPERTIES_ENV,PROPERTIES_VAR_DEFAULT>{ORIENTATION_VERT} { return ORIENTATION_VERT; } - -<PROPERTIES,PROPERTIES_ENV,PROPERTIES_VAR_DEFAULT>{CURSOR_DEF} { return CURSOR_DEF; } -<PROPERTIES,PROPERTIES_ENV,PROPERTIES_VAR_DEFAULT>{CURSOR_PTR} { return CURSOR_PTR; } -<PROPERTIES,PROPERTIES_ENV,PROPERTIES_VAR_DEFAULT>{CURSOR_TXT} { return CURSOR_TXT; } - -<PROPERTIES,PROPERTIES_ENV,PROPERTIES_VAR_DEFAULT>{COLOR_TRANSPARENT} { +<PROPERTIES,PROPERTIES_SET,PROPERTIES_ENV,PROPERTIES_VAR_DEFAULT>{NONE} { return T_NONE; } +<PROPERTIES,PROPERTIES_SET,PROPERTIES_ENV,PROPERTIES_VAR_DEFAULT>{BOLD} { return T_BOLD; } +<PROPERTIES,PROPERTIES_SET,PROPERTIES_ENV,PROPERTIES_VAR_DEFAULT>{ITALIC} { return T_ITALIC; } +<PROPERTIES,PROPERTIES_SET,PROPERTIES_ENV,PROPERTIES_VAR_DEFAULT>{UNDERLINE} { return T_UNDERLINE; } +<PROPERTIES,PROPERTIES_SET,PROPERTIES_ENV,PROPERTIES_VAR_DEFAULT>{STRIKETHROUGH} { return T_STRIKETHROUGH; } +<PROPERTIES,PROPERTIES_SET,PROPERTIES_ENV,PROPERTIES_VAR_DEFAULT>{SMALLCAPS} { return T_SMALLCAPS; } + +<PROPERTIES,PROPERTIES_SET,PROPERTIES_ENV,PROPERTIES_VAR_DEFAULT>{ANGLE_DEG} { return T_ANGLE_DEG; } +<PROPERTIES,PROPERTIES_SET,PROPERTIES_ENV,PROPERTIES_VAR_DEFAULT>{ANGLE_RAD} { return T_ANGLE_RAD; } +<PROPERTIES,PROPERTIES_SET,PROPERTIES_ENV,PROPERTIES_VAR_DEFAULT>{ANGLE_GRAD} { return T_ANGLE_GRAD; } +<PROPERTIES,PROPERTIES_SET,PROPERTIES_ENV,PROPERTIES_VAR_DEFAULT>{ANGLE_TURN} { return T_ANGLE_TURN; } + +<PROPERTIES,PROPERTIES_SET,PROPERTIES_ENV,PROPERTIES_VAR_DEFAULT>{ORIENTATION_HORI} { return ORIENTATION_HORI; } +<PROPERTIES,PROPERTIES_SET,PROPERTIES_ENV,PROPERTIES_VAR_DEFAULT>{ORIENTATION_VERT} { return ORIENTATION_VERT; } + +<PROPERTIES,PROPERTIES_SET,PROPERTIES_ENV,PROPERTIES_VAR_DEFAULT>{CURSOR_DEF} { return CURSOR_DEF; } +<PROPERTIES,PROPERTIES_SET,PROPERTIES_ENV,PROPERTIES_VAR_DEFAULT>{CURSOR_PTR} { return CURSOR_PTR; } +<PROPERTIES,PROPERTIES_SET,PROPERTIES_ENV,PROPERTIES_VAR_DEFAULT>{CURSOR_TXT} { return CURSOR_TXT; } + +<PROPERTIES,PROPERTIES_SET,PROPERTIES_ENV,PROPERTIES_VAR_DEFAULT>{COLOR_TRANSPARENT} { return T_COLOR_TRANSPARENT; } -<PROPERTIES,PROPERTIES_ENV,PROPERTIES_VAR_DEFAULT>{COLOR_NAME} { +<PROPERTIES,PROPERTIES_SET,PROPERTIES_ENV,PROPERTIES_VAR_DEFAULT>{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; } -<PROPERTIES_ENV_VAR,PROPERTIES_VAR,PROPERTIES,PROPERTIES_ENV,PROPERTIES_VAR_DEFAULT,PROPERTIES_LIST>. { +<PROPERTIES_ENV_VAR,PROPERTIES_VAR,PROPERTIES_SET,PROPERTIES,PROPERTIES_ENV,PROPERTIES_VAR_DEFAULT,PROPERTIES_LIST>. { 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 <ival> t_property_line_style %type <list> t_property_element_list %type <list> t_property_element_list_optional +%type <list> t_property_element_set +%type <list> t_property_element_set_optional %type <ival> t_property_orientation %type <ival> t_property_cursor %type <ival> 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, |