From 7c331b130be01d6af3f566417c0a4881260f0c27 Mon Sep 17 00:00:00 2001 From: Dave Davenport Date: Mon, 14 Sep 2020 20:34:39 +0200 Subject: [PATCH] [Calc] Add min/max operator support to calc() Fixes: #1172 --- doc/rofi-theme.5.markdown | 12 +++++++----- include/rofi-types.h | 2 ++ lexer/theme-lexer.l | 4 ++++ lexer/theme-parser.y | 25 +++++++++++++++++++++++-- source/theme.c | 18 ++++++++++++++++++ 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 ){ {MODIFIER_ADD} { return T_MODIFIER_ADD; } {MODIFIER_SUBTRACT} { return T_MODIFIER_SUBTRACT; } {MODIFIER_MULTIPLY} { return T_MODIFIER_MULTIPLY; } +{MODIFIER_MIN} { return T_MODIFIER_MIN; } +{MODIFIER_MAX} { return T_MODIFIER_MAX; } {CALC} { return T_CALC; } {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 t_property_distance_zero %type t_property_distance_unit_math %type t_property_distance_unit_math2 +%type t_property_distance_unit_math3 %type t_property_distance_unit %type t_property_unit %type 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; }