summaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorDave Davenport <qball@gmpclient.org>2020-09-14 20:34:39 +0200
committerDave Davenport <qball@gmpclient.org>2020-09-14 20:34:39 +0200
commit7c331b130be01d6af3f566417c0a4881260f0c27 (patch)
treeb5a0225bb06d9c82990b4f503899e9a8f19006e9
parent798379551f3043a59d69bd371c38d36894f68ce7 (diff)
[Calc] Add min/max operator support to calc()
Fixes: #1172
-rw-r--r--doc/rofi-theme.5.markdown12
-rw-r--r--include/rofi-types.h2
-rw-r--r--lexer/theme-lexer.l4
-rw-r--r--lexer/theme-parser.y25
-rw-r--r--source/theme.c18
5 files changed, 54 insertions, 7 deletions
diff --git a/doc/rofi-theme.5.markdown b/doc/rofi-theme.5.markdown
index adeccbb0..7c23dbf8 100644
--- a/doc/rofi-theme.5.markdown
+++ b/doc/rofi-theme.5.markdown
@@ -364,11 +364,13 @@ width: calc( 100% - 37px );
It supports the following operations:
-* `+`: Add
-* `-`: Subtract
-* `/`: Divide
-* `*`: Multiply
-* `%`: Multiply
+* `+` : Add
+* `-` : Subtract
+* `/` : Divide
+* `*` : Multiply
+* `%` : Multiply
+* `min` : Minimum of l or rvalue;
+* `max` : Maximum of l or rvalue;
It uses the C precedence ordering.
diff --git a/include/rofi-types.h b/include/rofi-types.h
index f9370295..bdda445f 100644
--- a/include/rofi-types.h
+++ b/include/rofi-types.h
@@ -102,6 +102,8 @@ typedef enum
ROFI_DISTANCE_MODIFIER_MULTIPLY,
ROFI_DISTANCE_MODIFIER_MODULO,
ROFI_DISTANCE_MODIFIER_GROUP,
+ ROFI_DISTANCE_MODIFIER_MIN,
+ ROFI_DISTANCE_MODIFIER_MAX,
} RofiDistanceModifier;
typedef struct RofiDistanceUnit
diff --git a/lexer/theme-lexer.l b/lexer/theme-lexer.l
index 8fb5840c..077c3797 100644
--- a/lexer/theme-lexer.l
+++ b/lexer/theme-lexer.l
@@ -189,6 +189,8 @@ ENV $\{[[:alnum:]]*\}
MODIFIER_ADD \+
MODIFIER_SUBTRACT -
MODIFIER_MULTIPLY \*
+MODIFIER_MIN (min)
+MODIFIER_MAX (max)
/* Position */
CENTER (?i:center)
@@ -463,6 +465,8 @@ if ( queue == NULL ){
<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>{MODIFIER_MULTIPLY} { return T_MODIFIER_MULTIPLY; }
+<PROPERTIES,PROPERTIES_ENV,PROPERTIES_VAR_DEFAULT>{MODIFIER_MIN} { return T_MODIFIER_MIN; }
+<PROPERTIES,PROPERTIES_ENV,PROPERTIES_VAR_DEFAULT>{MODIFIER_MAX} { return T_MODIFIER_MAX; }
<PROPERTIES,PROPERTIES_ENV,PROPERTIES_VAR_DEFAULT>{CALC} { return T_CALC; }
<PROPERTIES,PROPERTIES_ENV,PROPERTIES_VAR_DEFAULT>{ENV} {
diff --git a/lexer/theme-parser.y b/lexer/theme-parser.y
index 619a9873..bb1496db 100644
--- a/lexer/theme-parser.y
+++ b/lexer/theme-parser.y
@@ -218,6 +218,9 @@ static ThemeColor hwb_to_rgb ( double h, double w, double b)
%token T_MODIFIER_SUBTRACT "Subtract ('-')"
%token T_MODIFIER_MULTIPLY "Multiply ('*')"
+%token T_MODIFIER_MAX "Max ('max')"
+%token T_MODIFIER_MIN "Min ('min')"
+
%token T_CALC "calc"
%token T_BOPEN "bracket open ('{')"
@@ -261,6 +264,7 @@ static ThemeColor hwb_to_rgb ( double h, double w, double b)
%type <distance> t_property_distance_zero
%type <distance_unit> t_property_distance_unit_math
%type <distance_unit> t_property_distance_unit_math2
+%type <distance_unit> t_property_distance_unit_math3
%type <distance_unit> t_property_distance_unit
%type <ival> t_property_unit
%type <wloc> t_property_position
@@ -601,7 +605,7 @@ t_property_distance_unit
$$->right = NULL;
$$->modtype = ROFI_DISTANCE_MODIFIER_NONE;
}
-| T_PARENT_LEFT t_property_distance_unit_math2 T_PARENT_RIGHT {
+| T_PARENT_LEFT t_property_distance_unit_math3 T_PARENT_RIGHT {
$$ = g_slice_new0(RofiDistanceUnit);
$$->distance = 0;
$$->type = ROFI_PU_PX;
@@ -655,6 +659,23 @@ t_property_distance_unit_math2
| t_property_distance_unit_math {
$$ = $1;
};
+/** Level 3 (min max)*/
+t_property_distance_unit_math3
+: t_property_distance_unit_math3 T_MODIFIER_MIN t_property_distance_unit_math2 {
+ $$ = g_slice_new0(RofiDistanceUnit);
+ $$->left = $1;
+ $$->right = $3;
+ $$->modtype = ROFI_DISTANCE_MODIFIER_MIN;
+}
+| t_property_distance_unit_math3 T_MODIFIER_MAX t_property_distance_unit_math2 {
+ $$ = g_slice_new0(RofiDistanceUnit);
+ $$->left = $1;
+ $$->right = $3;
+ $$->modtype = ROFI_DISTANCE_MODIFIER_MAX;
+}
+| t_property_distance_unit_math2 {
+ $$ = $1;
+};
t_property_distance
@@ -676,7 +697,7 @@ t_property_distance
$$.base.right = NULL;
$$.style = $3;
}
-| T_CALC T_PARENT_LEFT t_property_distance_unit_math2 T_PARENT_RIGHT t_property_line_style {
+| T_CALC T_PARENT_LEFT t_property_distance_unit_math3 T_PARENT_RIGHT t_property_line_style {
$$.base.distance = 0;
$$.base.type = ROFI_PU_PX;
$$.base.left = $3;
diff --git a/source/theme.c b/source/theme.c
index 44cf3d9f..035c7b6b 100644
--- a/source/theme.c
+++ b/source/theme.c
@@ -297,6 +297,12 @@ static void rofi_theme_print_distance_unit ( RofiDistanceUnit *unit )
else if ( unit->modtype == ROFI_DISTANCE_MODIFIER_MODULO ) {
fputs ( " % ", stdout );
}
+ else if ( unit->modtype == ROFI_DISTANCE_MODIFIER_MIN ) {
+ fputs ( " min ", stdout );
+ }
+ else if ( unit->modtype == ROFI_DISTANCE_MODIFIER_MAX ) {
+ fputs ( " max ", stdout );
+ }
if ( unit->right ) {
rofi_theme_print_distance_unit ( unit->right );
}
@@ -998,6 +1004,18 @@ static int distance_unit_get_pixel ( RofiDistanceUnit *unit, RofiOrientation ori
}
return 0;
}
+ case ROFI_DISTANCE_MODIFIER_MIN:
+ {
+ int a = distance_unit_get_pixel ( unit->left, ori );
+ int b = distance_unit_get_pixel ( unit->right, ori );
+ return MIN(a,b);
+ }
+ case ROFI_DISTANCE_MODIFIER_MAX:
+ {
+ int a = distance_unit_get_pixel ( unit->left, ori );
+ int b = distance_unit_get_pixel ( unit->right, ori );
+ return MAX(a,b);
+ }
default:
break;
}