Allow linking to top level properties.

This commit is contained in:
Dave Davenport 2017-01-05 18:22:34 +01:00
parent 50479057bc
commit 4cc21b93a5
4 changed files with 100 additions and 35 deletions

View File

@ -55,6 +55,8 @@ typedef enum {
P_COLOR,
/** Padding */
P_PADDING,
/** Link to global setting */
P_LINK,
} PropertyType;
/**
@ -76,14 +78,14 @@ typedef struct
* Padding
*/
typedef struct
{
{
Distance top;
Distance right;
Distance bottom;
Distance left;
} Padding;
typedef struct {
typedef struct Property {
char *name;
PropertyType type;
union {
@ -93,6 +95,10 @@ typedef struct {
int b;
ThemeColor color;
Padding padding;
struct {
char *name;
struct Property *ref;
} link;
} value;
} Property;
/**

View File

@ -109,6 +109,10 @@ if ( queue == NULL ){
<PROPERTIES>{NUMBER}+ { yylval->ival = (int)g_ascii_strtoll(yytext, NULL, 10); return T_INT;}
<PROPERTIES>{NUMBER}+\.{NUMBER}+ { yylval->fval = g_ascii_strtod(yytext, NULL); return T_DOUBLE;}
<PROPERTIES>\"{STRING}\" { yytext[yyleng-1] = '\0'; yylval->sval = g_strdup(&yytext[1]); return T_STRING;}
<PROPERTIES>@{WORD} {
yylval->sval = g_strdup(yytext);
return T_LINK;
}
<PROPERTIES>{REAL}{EM} {
yylval->distance.distance = (double)g_ascii_strtod(yytext, NULL);
@ -208,6 +212,11 @@ if ( queue == NULL ){
return T_COLOR;
}
<*>'\n' {
printf("newlines\n");
yylloc->last_column = 1;
yylloc->last_line ++;
};
<*>(\r\n) {
printf("newlines\n");
yylloc->last_column = 1;

View File

@ -42,6 +42,7 @@ int yylex (YYSTYPE *, YYLTYPE *);
%token <bval> T_BOOLEAN
%token <colorval> T_COLOR
%token <distance> T_PIXEL
%token <sval> T_LINK
%token <sval> FIRST_NAME
%token BOPEN "bracket open";
@ -146,6 +147,11 @@ property
$$->name = $1;
$$->value.s = $3;
}
| pvalue PSEP T_LINK PCLOSE {
$$ = rofi_theme_property_create ( P_LINK );
$$->name = $1;
$$->value.link.name = $3;
}
| pvalue PSEP T_BOOLEAN PCLOSE {
$$ = rofi_theme_property_create ( P_BOOLEAN );
$$->name = $1;

View File

@ -50,6 +50,8 @@ void rofi_theme_property_free ( Property *p )
g_free ( p->name );
if ( p->type == P_STRING ) {
g_free ( p->value.s );
} else if ( p->type == P_LINK ) {
g_free ( p->value.link.name );
}
g_free(p);
}
@ -92,45 +94,48 @@ static void rofi_theme_print_property_index ( int depth, Property *p )
switch ( p->type )
{
case P_STRING:
printf("\"%s\";", p->value.s);
break;
printf("\"%s\";", p->value.s);
break;
case P_INTEGER:
printf("%d;", p->value.i);
break;
printf("%d;", p->value.i);
break;
case P_DOUBLE:
printf("%.2f;", p->value.f);
break;
printf("%.2f;", p->value.f);
break;
case P_BOOLEAN:
printf("%s;", p->value.b?"true":"false");
break;
printf("%s;", p->value.b?"true":"false");
break;
case P_COLOR:
printf("#%02X%02X%02X%02X;",
(unsigned char)(p->value.color.alpha*255.0),
(unsigned char)(p->value.color.red*255.0),
(unsigned char)(p->value.color.green*255.0),
(unsigned char)(p->value.color.blue*255.0));
break;
printf("#%02X%02X%02X%02X;",
(unsigned char)(p->value.color.alpha*255.0),
(unsigned char)(p->value.color.red*255.0),
(unsigned char)(p->value.color.green*255.0),
(unsigned char)(p->value.color.blue*255.0));
break;
case P_PADDING:
if ( distance_compare ( p->value.padding.top, p->value.padding.bottom) &&
distance_compare ( p->value.padding.left, p->value.padding.right) &&
if ( distance_compare ( p->value.padding.top, p->value.padding.bottom) &&
distance_compare ( p->value.padding.left, p->value.padding.right) &&
distance_compare ( p->value.padding.left, p->value.padding.top) ) {
rofi_theme_print_distance ( p->value.padding.left );
} else if ( distance_compare ( p->value.padding.top, p->value.padding.bottom) &&
distance_compare ( p->value.padding.left, p->value.padding.right)){
rofi_theme_print_distance ( p->value.padding.top );
rofi_theme_print_distance ( p->value.padding.left );
} else if ( !distance_compare ( p->value.padding.top, p->value.padding.bottom) &&
distance_compare ( p->value.padding.left, p->value.padding.right)){
rofi_theme_print_distance ( p->value.padding.top );
rofi_theme_print_distance ( p->value.padding.left );
rofi_theme_print_distance ( p->value.padding.bottom);
} else {
rofi_theme_print_distance ( p->value.padding.top );
rofi_theme_print_distance ( p->value.padding.right );
rofi_theme_print_distance ( p->value.padding.bottom);
rofi_theme_print_distance ( p->value.padding.left );
}
printf(";\n");
rofi_theme_print_distance ( p->value.padding.left );
} else if ( distance_compare ( p->value.padding.top, p->value.padding.bottom) &&
distance_compare ( p->value.padding.left, p->value.padding.right)){
rofi_theme_print_distance ( p->value.padding.top );
rofi_theme_print_distance ( p->value.padding.left );
} else if ( !distance_compare ( p->value.padding.top, p->value.padding.bottom) &&
distance_compare ( p->value.padding.left, p->value.padding.right)){
rofi_theme_print_distance ( p->value.padding.top );
rofi_theme_print_distance ( p->value.padding.left );
rofi_theme_print_distance ( p->value.padding.bottom);
} else {
rofi_theme_print_distance ( p->value.padding.top );
rofi_theme_print_distance ( p->value.padding.right );
rofi_theme_print_distance ( p->value.padding.bottom);
rofi_theme_print_distance ( p->value.padding.left );
}
printf(";");
break;
case P_LINK:
printf("@%s;", p->value.link.name);
}
putchar ( '\n' );
}
@ -272,11 +277,50 @@ static ThemeWidget *rofi_theme_find ( ThemeWidget *widget , const char *name, co
}
}
static void rofi_theme_resolve_link_property ( Property *p, int depth )
{
// Set name, remove '@' prefix.
const char *name = p->value.link.name +1;
if ( depth > 20 ){
g_log ( LOG_DOMAIN, G_LOG_LEVEL_WARNING, "Found more then 20 redirects for property. Stopping.");
p->value.link.ref = p;
return;
}
if( g_hash_table_contains ( rofi_theme->properties, name ) ) {
Property *pr = g_hash_table_lookup ( rofi_theme->properties, name );
if ( pr->type == P_LINK ) {
if ( pr->value.link.ref == NULL ) {
rofi_theme_resolve_link_property ( pr, depth+1);
}
if ( pr->value.link.ref != pr ){
p->value.link.ref = pr->value.link.ref;
return;
}
} else {
p->value.link.ref = pr;
return;
}
}
// No found, set ref to self.
p->value.link.ref = p;
}
static Property *rofi_theme_find_property ( ThemeWidget *widget, PropertyType type, const char *property )
{
while ( widget ) {
if ( widget->properties && g_hash_table_contains ( widget->properties, property) ) {
Property *p = g_hash_table_lookup ( widget->properties, property);
if ( p->type == P_LINK ) {
if ( p->value.link.ref == NULL ) {
// Resolve link.
rofi_theme_resolve_link_property ( p, 0 );
}
if ( p->value.link.ref->type == type ){
return p->value.link.ref;
}
}
if ( p->type == type ){
return p;
}