[Calc] Add min/max operator support to calc()

Fixes: #1172
This commit is contained in:
Dave Davenport 2020-09-14 20:34:39 +02:00
parent 798379551f
commit 7c331b130b
5 changed files with 54 additions and 7 deletions

View File

@ -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.

View File

@ -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

View File

@ -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} {

View File

@ -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;

View File

@ -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;
}