summaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorDave Davenport <qball@gmpclient.org>2020-04-23 20:04:41 +0200
committerDave Davenport <qball@gmpclient.org>2020-04-23 20:04:41 +0200
commit1cf9fd4b5e63d05bdbcda7b2ff7db1934dcfa8c2 (patch)
tree7b8c7e785a1478d71f81e430334331bc44c4de9c
parentf90ad971d9d334b26280fbf14dda700877f75d67 (diff)
Initial test to allow math in distances.
Support + and - Needs spaces around + and -.
-rw-r--r--include/rofi-types.h22
-rw-r--r--include/theme.h1
-rw-r--r--lexer/theme-lexer.l5
-rw-r--r--lexer/theme-parser.y79
-rw-r--r--source/theme.c120
-rw-r--r--source/widgets/scrollbar.c2
-rw-r--r--source/widgets/widget.c10
7 files changed, 200 insertions, 39 deletions
diff --git a/include/rofi-types.h b/include/rofi-types.h
index bb294dad..c546f6e6 100644
--- a/include/rofi-types.h
+++ b/include/rofi-types.h
@@ -89,12 +89,32 @@ typedef enum
/**
* Structure representing a distance.
*/
-typedef struct
+typedef enum
+{
+ ROFI_DISTANCE_MODIFIER_NONE,
+ ROFI_DISTANCE_MODIFIER_ADD,
+ ROFI_DISTANCE_MODIFIER_SUBTRACT,
+} RofiDistanceModifier;
+
+typedef struct RofiDistanceUnit
{
/** Distance */
double distance;
/** Unit type of the distance */
RofiPixelUnit type;
+
+ /** Type */
+ RofiDistanceModifier modtype;
+
+ /** Modifier */
+ struct RofiDistanceUnit *modifier;
+
+} RofiDistanceUnit;
+
+typedef struct
+{
+ /** Base */
+ RofiDistanceUnit base;
/** Style of the line (optional)*/
RofiLineStyle style;
} RofiDistance;
diff --git a/include/theme.h b/include/theme.h
index 0ed71460..055bea71 100644
--- a/include/theme.h
+++ b/include/theme.h
@@ -387,4 +387,5 @@ void rofi_theme_parse_merge_widgets ( ThemeWidget *parent, ThemeWidget *child );
* Returns the media type described by type.
*/
ThemeMediaType rofi_theme_parse_media_type ( const char *type );
+RofiDistance rofi_theme_property_copy_distance ( RofiDistance const distance );
#endif
diff --git a/lexer/theme-lexer.l b/lexer/theme-lexer.l
index 50a2c4e7..f0b68048 100644
--- a/lexer/theme-lexer.l
+++ b/lexer/theme-lexer.l
@@ -183,6 +183,9 @@ ASTERIX \*
ENV $\{[[:alnum:]]*\}
+MODIFIER_ADD \+
+MODIFIER_SUBTRACT -
+
/* Position */
CENTER (?i:center)
NORTH (?i:north)
@@ -450,6 +453,8 @@ if ( queue == NULL ){
<PROPERTIES,PROPERTIES_ENV,PROPERTIES_VAR_DEFAULT>{LS_DASH} { return T_DASH; }
<PROPERTIES,PROPERTIES_ENV,PROPERTIES_VAR_DEFAULT>{INHERIT} { return T_INHERIT; }
+<PROPERTIES,PROPERTIES_ENV,PROPERTIES_VAR_DEFAULT>{MODIFIER_ADD} { return T_MODIFIER_ADD; }
+<PROPERTIES,PROPERTIES_ENV,PROPERTIES_VAR_DEFAULT>{MODIFIER_SUBTRACT} { return T_MODIFIER_SUBTRACT; }
<PROPERTIES,PROPERTIES_ENV,PROPERTIES_VAR_DEFAULT>{ENV} {
yytext[yyleng-1] = '\0';
diff --git a/lexer/theme-parser.y b/lexer/theme-parser.y
index c85a5bbe..50819098 100644
--- a/lexer/theme-parser.y
+++ b/lexer/theme-parser.y
@@ -146,6 +146,7 @@ static ThemeColor hwb_to_rgb ( double h, double w, double b)
Property *property;
GHashTable *property_list;
RofiDistance distance;
+ RofiDistanceUnit *distance_unit;
}
%token <ival> T_END 0 "end of file"
@@ -210,6 +211,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_MODIFIER_ADD "Add ('+')"
+%token T_MODIFIER_SUBTRACT "Subtract ('-')"
+
%token T_BOPEN "bracket open ('{')"
%token T_BCLOSE "bracket close ('}')"
%token T_PSEP "property separator (':')"
@@ -251,6 +255,8 @@ static ThemeColor hwb_to_rgb ( double h, double w, double b)
%type <sval> t_property_name
%type <distance> t_property_distance
%type <distance> t_property_distance_zero
+%type <distance_unit> t_property_distance_unit
+%type <ival> t_property_distance_modifier_type
%type <ival> t_property_unit
%type <wloc> t_property_position
%type <wloc> t_property_position_ew
@@ -503,15 +509,15 @@ t_property_element
}
| t_property_distance {
$$ = rofi_theme_property_create ( P_PADDING );
- $$->value.padding = (RofiPadding){ $1, $1, $1, $1 };
+ $$->value.padding = (RofiPadding){ $1, rofi_theme_property_copy_distance($1), rofi_theme_property_copy_distance($1), rofi_theme_property_copy_distance($1) };
}
| t_property_distance_zero t_property_distance_zero {
$$ = rofi_theme_property_create ( P_PADDING );
- $$->value.padding = (RofiPadding){ $1, $2, $1, $2 };
+ $$->value.padding = (RofiPadding){ $1, $2, rofi_theme_property_copy_distance($1), rofi_theme_property_copy_distance($2) };
}
| t_property_distance_zero t_property_distance_zero t_property_distance_zero {
$$ = rofi_theme_property_create ( P_PADDING );
- $$->value.padding = (RofiPadding){ $1, $2, $3, $2 };
+ $$->value.padding = (RofiPadding){ $1, $2, $3, rofi_theme_property_copy_distance($2) };
}
| t_property_distance_zero t_property_distance_zero t_property_distance_zero t_property_distance_zero {
$$ = rofi_theme_property_create ( P_PADDING );
@@ -599,25 +605,80 @@ t_property_highlight_style
t_property_distance_zero
: T_INT t_property_line_style {
- $$.distance = (double) $1;
- $$.type = ROFI_PU_PX;
+ $$.base.distance = (double) $1;
+ $$.base.type = ROFI_PU_PX;
+ $$.base.modifier = NULL;
$$.style = $2;
}
| t_property_distance { $$ = $1;}
;
+
+t_property_distance_modifier_type
+: T_MODIFIER_ADD { $$ = ROFI_DISTANCE_MODIFIER_ADD; }
+| T_MODIFIER_SUBTRACT { $$ = ROFI_DISTANCE_MODIFIER_SUBTRACT; };
+
+
/** Distance. */
+t_property_distance_unit
+: t_property_distance_modifier_type T_INT t_property_unit {
+ $$ = g_malloc0(sizeof(RofiDistanceUnit));
+ $$->distance = (double)$2;
+ $$->type = $3;
+ $$->modifier = NULL;
+ $$->modtype = $1;
+}
+| t_property_distance_modifier_type T_DOUBLE t_property_unit {
+ $$ = g_malloc0(sizeof(RofiDistanceUnit));
+ $$->distance = (double)$2;
+ $$->type = $3;
+ $$->modifier = NULL;
+ $$->modtype = $1;
+}
+| t_property_distance_modifier_type T_INT t_property_unit t_property_distance_unit {
+ $$ = g_malloc0(sizeof(RofiDistanceUnit));
+ $$->distance = (double)$2;
+ $$->type = $3;
+ $$->modifier = $4;
+ $$->modtype = $1;
+}
+| t_property_distance_modifier_type T_DOUBLE t_property_unit t_property_distance_unit {
+ $$ = g_malloc0(sizeof(RofiDistanceUnit));
+ $$->distance = (double)$2;
+ $$->type = $3;
+ $$->modifier = $4;
+ $$->modtype = $1;
+};
+
t_property_distance
/** Integer unit and line style */
: T_INT t_property_unit t_property_line_style {
- $$.distance = (double)$1;
- $$.type = $2;
+ $$.base.distance = (double)$1;
+ $$.base.type = $2;
+ $$.base.modifier = NULL;
+ $$.base.modtype = ROFI_DISTANCE_MODIFIER_NONE;
$$.style = $3;
}
/** Double unit and line style */
| T_DOUBLE t_property_unit t_property_line_style {
- $$.distance = (double)$1;
- $$.type = $2;
+ $$.base.distance = (double)$1;
+ $$.base.type = $2;
+ $$.base.modtype = ROFI_DISTANCE_MODIFIER_NONE;
+ $$.base.modifier = NULL;
$$.style = $3;
+}
+| T_INT t_property_unit t_property_distance_unit t_property_line_style {
+ $$.base.distance = (double)$1;
+ $$.base.type = $2;
+ $$.base.modifier = $3;
+ $$.base.modtype = ROFI_DISTANCE_MODIFIER_NONE;
+ $$.style = $4;
+}
+| T_DOUBLE t_property_unit t_property_distance_unit t_property_line_style {
+ $$.base.distance = (double)$1;
+ $$.base.type = $2;
+ $$.base.modifier = $3;
+ $$.base.modtype = ROFI_DISTANCE_MODIFIER_NONE;
+ $$.style = $4;
};
/** distance unit. px, em, % */
diff --git a/source/theme.c b/source/theme.c
index 069b9ef3..c7489292 100644
--- a/source/theme.c
+++ b/source/theme.c
@@ -47,7 +47,8 @@
void yyerror ( YYLTYPE *yylloc, const char *, const char * );
static gboolean distance_compare ( RofiDistance d, RofiDistance e )
{
- return d.type == e.type && d.distance == e.distance && d.style == e.style;
+ // TODO UPDATE
+ return d.base.type == e.base.type && d.base.distance == e.base.distance && d.style == e.style;
}
static gpointer rofi_g_list_strdup ( gconstpointer data, G_GNUC_UNUSED gpointer user_data )
@@ -80,6 +81,26 @@ Property *rofi_theme_property_create ( PropertyType type )
retv->type = type;
return retv;
}
+
+static RofiDistanceUnit *rofi_theme_property_copy_distance_unit ( RofiDistanceUnit *unit )
+{
+ RofiDistanceUnit *retv = g_malloc0( sizeof(RofiDistanceUnit) );
+ *retv = *unit;
+ if ( unit->modifier ) {
+ retv->modifier = rofi_theme_property_copy_distance_unit ( unit->modifier );
+ }
+ return retv;
+}
+RofiDistance rofi_theme_property_copy_distance ( RofiDistance const distance )
+{
+ RofiDistance retv = distance;
+ if ( distance.base.modifier )
+ {
+ retv.base.modifier = rofi_theme_property_copy_distance_unit ( distance.base.modifier );
+ }
+ return retv;
+}
+
Property* rofi_theme_property_copy ( Property *p )
{
Property *retv = rofi_theme_property_create ( p->type );
@@ -100,12 +121,37 @@ Property* rofi_theme_property_copy ( Property *p )
retv->value.link.def_value = rofi_theme_property_copy ( p->value.link.def_value );
}
break;
+ case P_PADDING:
+ {
+ retv->value = p->value;
+ retv->value.padding.top = rofi_theme_property_copy_distance ( p->value.padding.top);
+ retv->value.padding.left = rofi_theme_property_copy_distance ( p->value.padding.left);
+ retv->value.padding.bottom = rofi_theme_property_copy_distance ( p->value.padding.bottom);
+ retv->value.padding.right = rofi_theme_property_copy_distance ( p->value.padding.right);
+ break;
+ }
default:
retv->value = p->value;
}
return retv;
}
+static void rofi_theme_distance_unit_property_free ( RofiDistanceUnit *unit )
+{
+ if ( unit->modifier ) {
+ rofi_theme_distance_unit_property_free ( unit->modifier );
+ unit->modifier = NULL;
+ }
+ g_free (unit);
+}
+static void rofi_theme_distance_property_free ( RofiDistance *distance )
+{
+ if ( distance->base.modifier ) {
+ rofi_theme_distance_unit_property_free ( distance->base.modifier );
+ distance->base.modifier = NULL;
+ }
+}
+
void rofi_theme_property_free ( Property *p )
{
if ( p == NULL ) {
@@ -121,6 +167,12 @@ void rofi_theme_property_free ( Property *p )
rofi_theme_property_free ( p->value.link.def_value );
}
}
+ if ( p->type == P_PADDING) {
+ rofi_theme_distance_property_free( &(p->value.padding.top));
+ rofi_theme_distance_property_free( &(p->value.padding.right));
+ rofi_theme_distance_property_free( &(p->value.padding.bottom));
+ rofi_theme_distance_property_free( &(p->value.padding.left));
+ }
g_slice_free ( Property, p );
}
@@ -149,7 +201,7 @@ static void rofi_theme_insert_listview_backwards_fix ( void )
rofi_theme_widget_add_properties ( tt, table );
- RofiDistance dsize = (RofiDistance){ 1.2, ROFI_PU_CH, ROFI_HL_SOLID };
+ RofiDistance dsize = (RofiDistance){ .base = {1.2, ROFI_PU_CH, ROFI_DISTANCE_MODIFIER_NONE, NULL}, .style = ROFI_HL_SOLID };
Property *pts = rofi_theme_property_create ( P_PADDING );
pts->value.padding.top = pts->value.padding.right = pts->value.padding.bottom = pts->value.padding.left = dsize;
pts->name = g_strdup ( "size" );
@@ -162,7 +214,7 @@ static void rofi_theme_insert_listview_backwards_fix ( void )
table = g_hash_table_new_full ( g_str_hash, g_str_equal, NULL, (GDestroyNotify) rofi_theme_property_free );
Property *psp = rofi_theme_property_create ( P_PADDING );
psp->name = g_strdup ( "spacing" );
- RofiDistance d = (RofiDistance){ 5, ROFI_PU_PX, ROFI_HL_SOLID };
+ RofiDistance d = (RofiDistance){ .base = {5, ROFI_PU_PX, ROFI_DISTANCE_MODIFIER_NONE, NULL}, .style = ROFI_HL_SOLID };
psp->value.padding = (RofiPadding){ d, d, d, d };
g_hash_table_replace ( table, psp->name, psp );
rofi_theme_widget_add_properties ( t, table );
@@ -206,19 +258,19 @@ inline static void printf_double ( double d )
}
static void rofi_theme_print_distance ( RofiDistance d )
{
- if ( d.type == ROFI_PU_PX ) {
- printf ( "%upx ", (unsigned int) d.distance );
+ if ( d.base.type == ROFI_PU_PX ) {
+ printf ( "%upx ", (unsigned int) d.base.distance );
}
- else if ( d.type == ROFI_PU_PERCENT ) {
- printf_double ( d.distance );
+ else if ( d.base.type == ROFI_PU_PERCENT ) {
+ printf_double ( d.base.distance );
fputs ( "%% ", stdout );
}
- else if ( d.type == ROFI_PU_CH ) {
- printf_double ( d.distance );
+ else if ( d.base.type == ROFI_PU_CH ) {
+ printf_double ( d.base.distance );
fputs ( "ch ", stdout );
}
else {
- printf_double ( d.distance );
+ printf_double ( d.base.distance );
fputs ( "em ", stdout );
}
if ( d.style == ROFI_HL_DASH ) {
@@ -636,17 +688,17 @@ RofiDistance rofi_theme_get_distance ( const widget *widget, const char *propert
if ( widget->parent ) {
return rofi_theme_get_distance ( widget->parent, property, def );
}
- return (RofiDistance){ def, ROFI_PU_PX, ROFI_HL_SOLID };
+ return (RofiDistance){ .base = {def, ROFI_PU_PX, ROFI_DISTANCE_MODIFIER_NONE, NULL}, .style = ROFI_HL_SOLID };
}
if ( p->type == P_INTEGER ) {
- return (RofiDistance){ p->value.i, ROFI_PU_PX, ROFI_HL_SOLID };
+ return (RofiDistance){ .base = { p->value.i, ROFI_PU_PX, ROFI_DISTANCE_MODIFIER_NONE, NULL}, .style = ROFI_HL_SOLID };
}
else {
return p->value.padding.left;
}
}
g_debug ( "Theme entry: #%s %s property %s unset.", widget->name, widget->state ? widget->state : "", property );
- return (RofiDistance){ def, ROFI_PU_PX, ROFI_HL_SOLID };
+ return (RofiDistance){ .base = {def, ROFI_PU_PX, ROFI_DISTANCE_MODIFIER_NONE, NULL}, .style = ROFI_HL_SOLID };
}
int rofi_theme_get_boolean ( const widget *widget, const char *property, int def )
@@ -762,7 +814,7 @@ RofiPadding rofi_theme_get_padding ( const widget *widget, const char *property,
pad = p->value.padding;
}
else {
- RofiDistance d = (RofiDistance){ p->value.i, ROFI_PU_PX, ROFI_HL_SOLID };
+ RofiDistance d = (RofiDistance){ .base = {p->value.i, ROFI_PU_PX, ROFI_DISTANCE_MODIFIER_NONE, NULL}, .style = ROFI_HL_SOLID };
return (RofiPadding){ d, d, d, d };
}
}
@@ -813,27 +865,49 @@ RofiHighlightColorStyle rofi_theme_get_highlight ( widget *widget, const char *p
return th;
}
-int distance_get_pixel ( RofiDistance d, RofiOrientation ori )
+
+static int distance_unit_get_pixel ( RofiDistanceUnit *unit, RofiOrientation ori )
{
- if ( d.type == ROFI_PU_EM ) {
- return d.distance * textbox_get_estimated_char_height ();
+ int val = unit->distance;
+
+
+ if ( unit->type == ROFI_PU_EM ) {
+ val = unit->distance * textbox_get_estimated_char_height ();
}
- else if ( d.type == ROFI_PU_CH ) {
- return d.distance * textbox_get_estimated_ch ();
+ else if ( unit->type == ROFI_PU_CH ) {
+ val = unit->distance * textbox_get_estimated_ch ();
}
- else if ( d.type == ROFI_PU_PERCENT ) {
+ else if ( unit->type == ROFI_PU_PERCENT ) {
if ( ori == ROFI_ORIENTATION_VERTICAL ) {
int height = 0;
rofi_view_get_current_monitor ( NULL, &height );
- return ( d.distance * height ) / ( 100.0 );
+ val = ( unit->distance * height ) / ( 100.0 );
}
else {
int width = 0;
rofi_view_get_current_monitor ( &width, NULL );
- return ( d.distance * width ) / ( 100.0 );
+ val = ( unit->distance * width ) / ( 100.0 );
+ }
+ }
+ if ( unit->modifier ) {
+ switch ( unit->modifier->modtype)
+ {
+ case ROFI_DISTANCE_MODIFIER_ADD:
+ val += distance_unit_get_pixel ( unit->modifier, ori);
+ break;
+ case ROFI_DISTANCE_MODIFIER_SUBTRACT:
+ val -= distance_unit_get_pixel ( unit->modifier, ori);
+ break;
+ default:
+ break;
}
}
- return d.distance;
+ return val;
+}
+
+int distance_get_pixel ( RofiDistance d, RofiOrientation ori )
+{
+ return distance_unit_get_pixel ( &(d.base), ori);
}
void distance_get_linestyle ( RofiDistance d, cairo_t *draw )
diff --git a/source/widgets/scrollbar.c b/source/widgets/scrollbar.c
index dd057591..699ab07e 100644
--- a/source/widgets/scrollbar.c
+++ b/source/widgets/scrollbar.c
@@ -51,7 +51,7 @@ static int scrollbar_get_desired_height ( widget *wid )
// This should behave more like a real scrollbar.
guint scrollbar_scroll_get_line ( const scrollbar *sb, int y )
{
- y -= sb->widget.border.top.distance;
+ y -= sb->widget.border.top.base.distance;
if ( y < 0 ) {
return 0;
}
diff --git a/source/widgets/widget.c b/source/widgets/widget.c
index 5dfd9437..d90ec297 100644
--- a/source/widgets/widget.c
+++ b/source/widgets/widget.c
@@ -40,11 +40,11 @@ void widget_init ( widget *wid, widget *parent, WidgetType type, const char *nam
wid->parent = parent;
wid->name = g_strdup ( name );
wid->def_padding =
- (RofiPadding){ { WIDGET_DEFAULT_PADDING, ROFI_PU_PX, ROFI_HL_SOLID }, { WIDGET_DEFAULT_PADDING, ROFI_PU_PX, ROFI_HL_SOLID }, { WIDGET_DEFAULT_PADDING, ROFI_PU_PX, ROFI_HL_SOLID },
- { WIDGET_DEFAULT_PADDING, ROFI_PU_PX, ROFI_HL_SOLID } };
- wid->def_border = (RofiPadding){ { 0, ROFI_PU_PX, ROFI_HL_SOLID }, { 0, ROFI_PU_PX, ROFI_HL_SOLID }, { 0, ROFI_PU_PX, ROFI_HL_SOLID }, { 0, ROFI_PU_PX, ROFI_HL_SOLID } };
- wid->def_border_radius = (RofiPadding){ { 0, ROFI_PU_PX, ROFI_HL_SOLID }, { 0, ROFI_PU_PX, ROFI_HL_SOLID }, { 0, ROFI_PU_PX, ROFI_HL_SOLID }, { 0, ROFI_PU_PX, ROFI_HL_SOLID } };
- wid->def_margin = (RofiPadding){ { 0, ROFI_PU_PX, ROFI_HL_SOLID }, { 0, ROFI_PU_PX, ROFI_HL_SOLID }, { 0, ROFI_PU_PX, ROFI_HL_SOLID }, { 0, ROFI_PU_PX, ROFI_HL_SOLID } };
+ (RofiPadding){ { {WIDGET_DEFAULT_PADDING, ROFI_PU_PX, ROFI_DISTANCE_MODIFIER_NONE, NULL}, ROFI_HL_SOLID }, { {WIDGET_DEFAULT_PADDING, ROFI_PU_PX,ROFI_DISTANCE_MODIFIER_NONE, NULL}, ROFI_HL_SOLID }, { {WIDGET_DEFAULT_PADDING, ROFI_PU_PX,ROFI_DISTANCE_MODIFIER_NONE, NULL}, ROFI_HL_SOLID },
+ { {WIDGET_DEFAULT_PADDING, ROFI_PU_PX,ROFI_DISTANCE_MODIFIER_NONE, NULL}, ROFI_HL_SOLID } };
+ wid->def_border = (RofiPadding){ { {0, ROFI_PU_PX, ROFI_DISTANCE_MODIFIER_NONE, NULL} , ROFI_HL_SOLID }, { {0, ROFI_PU_PX, ROFI_DISTANCE_MODIFIER_NONE, NULL}, ROFI_HL_SOLID }, { {0, ROFI_PU_PX, ROFI_DISTANCE_MODIFIER_NONE, NULL}, ROFI_HL_SOLID }, { {0, ROFI_PU_PX, ROFI_DISTANCE_MODIFIER_NONE, NULL}, ROFI_HL_SOLID } };
+ wid->def_border_radius = (RofiPadding){ { {0, ROFI_PU_PX, ROFI_DISTANCE_MODIFIER_NONE, NULL} , ROFI_HL_SOLID }, { {0, ROFI_PU_PX, ROFI_DISTANCE_MODIFIER_NONE, NULL}, ROFI_HL_SOLID }, { {0, ROFI_PU_PX, ROFI_DISTANCE_MODIFIER_NONE, NULL}, ROFI_HL_SOLID }, { {0, ROFI_PU_PX, ROFI_DISTANCE_MODIFIER_NONE, NULL}, ROFI_HL_SOLID } };
+ wid->def_margin = (RofiPadding){ { {0, ROFI_PU_PX, ROFI_DISTANCE_MODIFIER_NONE, NULL} , ROFI_HL_SOLID }, { {0, ROFI_PU_PX, ROFI_DISTANCE_MODIFIER_NONE, NULL}, ROFI_HL_SOLID }, { {0, ROFI_PU_PX, ROFI_DISTANCE_MODIFIER_NONE, NULL}, ROFI_HL_SOLID }, { {0, ROFI_PU_PX, ROFI_DISTANCE_MODIFIER_NONE, NULL}, ROFI_HL_SOLID } };
wid->padding = rofi_theme_get_padding ( wid, "padding", wid->def_padding );
wid->border = rofi_theme_get_padding ( wid, "border", wid->def_border );