diff --git a/include/theme.h b/include/theme.h index af6a2f9b..8733df2a 100644 --- a/include/theme.h +++ b/include/theme.h @@ -11,6 +11,8 @@ typedef enum { PW_PX, /** PixelWidth in EM. */ PW_EM, + /** PixelWidget in percentage */ + PW_PERCENT, } PixelWidth; /** @@ -23,6 +25,13 @@ typedef struct { PixelWidth type; } Distance; +/** + * Type of orientation. + */ +typedef enum { + ORIENTATION_VERTICAL, + ORIENTATION_HORIZONTAL +} Orientation; /** * Type of property */ @@ -251,11 +260,12 @@ Padding rofi_theme_get_padding ( const char *wclass, const char *name, const ch /** * @param d The distance handle. + * @param ori The orientation. * * Convert Distance into pixels. * @returns the number of pixels this distance represents. */ -int distance_get_pixel ( Distance d ); +int distance_get_pixel ( Distance d, Orientation ori ); #ifdef THEME_CONVERTER /** diff --git a/include/view.h b/include/view.h index c6322af0..3a482310 100644 --- a/include/view.h +++ b/include/view.h @@ -248,5 +248,12 @@ void rofi_view_workers_initialize ( void ); * Stop all threads and free the resources used by the threadpool */ void rofi_view_workers_finalize ( void ); + +/** + * Return the current monitor workarea. + * + * @returns the current monitor workarea + */ +void rofi_view_get_current_monitor ( int *width, int *height ); /**@}*/ #endif diff --git a/lexer/theme-lexer.l b/lexer/theme-lexer.l index 08aab7aa..d0d2e01d 100644 --- a/lexer/theme-lexer.l +++ b/lexer/theme-lexer.l @@ -27,6 +27,7 @@ NUMBER [[:digit:]] REAL [[:digit:]]+(\.[[:digit:]]+)? PX (px) EM (em) +PERCENT (\%) NEWLINES (\r|\n)+ %x PROPERTIES @@ -117,6 +118,11 @@ if ( queue == NULL ){ yylval->distance.type = PW_PX; return T_PIXEL; } +{REAL}{PERCENT} { + yylval->distance.distance = (double)g_ascii_strtod(yytext, NULL); + yylval->distance.type = PW_PERCENT; + return T_PIXEL; +} #{HEX}{8} { union { unsigned int val; struct { unsigned char b,g,r,a;};} val; val.val = (unsigned int)strtoull ( &yytext[1], NULL, 16); diff --git a/source/theme.c b/source/theme.c index 870a0a1f..5098f51b 100644 --- a/source/theme.c +++ b/source/theme.c @@ -7,6 +7,7 @@ #include "helper.h" #include "settings.h" #include "widgets/textbox.h" +#include "view.h" void yyerror ( YYLTYPE *ylloc, const char *); @@ -369,10 +370,21 @@ Padding rofi_theme_get_padding ( const char *wclass, const char *name, const ch } return pad; } -int distance_get_pixel ( Distance d ) +int distance_get_pixel ( Distance d, Orientation ori ) { if ( d.type == PW_EM ){ return d.distance*textbox_get_estimated_char_height(); + } else if ( d.type == PW_PERCENT ) { + if ( ori == ORIENTATION_VERTICAL ){ + int height = 0; + rofi_view_get_current_monitor ( NULL, &height ); + return (d.distance*height)/(100.0); + } else { + int width = 0; + rofi_view_get_current_monitor ( &width, NULL ); + return (d.distance*width)/(100.0); + + } } return d.distance; } diff --git a/source/view.c b/source/view.c index 855bbb48..4b46242e 100644 --- a/source/view.c +++ b/source/view.c @@ -124,6 +124,15 @@ struct .repaint_source = 0, }; +void rofi_view_get_current_monitor ( int *width, int *height) +{ + if (width ){ + *width = CacheState.mon.w; + } + if (height){ + *height = CacheState.mon.h; + } +} static char * get_matching_state ( void ) { if ( config.case_sensitive ) { diff --git a/source/widgets/box.c b/source/widgets/box.c index 3a1c1d9d..e485c5e4 100644 --- a/source/widgets/box.c +++ b/source/widgets/box.c @@ -55,7 +55,7 @@ static void box_update ( widget *wid ); static int box_get_desired_height ( widget *wid ) { box *b = (box *)wid; - int spacing = distance_get_pixel ( b->spacing ); + int spacing = distance_get_pixel ( b->spacing, b->type == BOX_VERTICAL? ORIENTATION_VERTICAL:ORIENTATION_HORIZONTAL ); int active_widgets = 0; int height = 0; if ( b->type == BOX_VERTICAL ){ @@ -90,7 +90,7 @@ static int box_get_desired_height ( widget *wid ) static void vert_calculate_size ( box *b ) { - int spacing = distance_get_pixel ( b->spacing ); + int spacing = distance_get_pixel ( b->spacing, ORIENTATION_VERTICAL ); int expanding_widgets = 0; int active_widgets = 0; int rem_width = widget_padding_get_remaining_width ( WIDGET (b) ); @@ -169,7 +169,7 @@ static void vert_calculate_size ( box *b ) } static void hori_calculate_size ( box *b ) { - int spacing = distance_get_pixel ( b->spacing ); + int spacing = distance_get_pixel ( b->spacing, ORIENTATION_HORIZONTAL ); int expanding_widgets = 0; int active_widgets = 0; int rem_width = widget_padding_get_remaining_width ( WIDGET (b) ); diff --git a/source/widgets/listview.c b/source/widgets/listview.c index e2030b11..a7f4f644 100644 --- a/source/widgets/listview.c +++ b/source/widgets/listview.c @@ -164,21 +164,22 @@ static void listview_draw ( widget *wid, cairo_t *draw ) scrollbar_set_handle_length ( lv->scrollbar, lv->cur_columns * lv->max_rows ); scrollbar_set_handle ( lv->scrollbar, lv->selected ); lv->last_offset = offset; - int spacing = distance_get_pixel ( lv->spacing ); + int spacing_vert = distance_get_pixel ( lv->spacing, ORIENTATION_VERTICAL ); + int spacing_hori = distance_get_pixel ( lv->spacing, ORIENTATION_HORIZONTAL ); if ( lv->cur_elements > 0 && lv->max_rows > 0 ) { // Set new x/y possition. unsigned int max = MIN ( lv->cur_elements, lv->req_elements - offset ); if ( lv->rchanged ) { - unsigned int width = lv->widget.w - spacing * ( lv->cur_columns - 1 ); + unsigned int width = lv->widget.w - spacing_hori * ( lv->cur_columns - 1 ); width -= widget_padding_get_padding_width ( wid ); if ( widget_enabled ( WIDGET ( lv->scrollbar ) ) ) { - width -= spacing; + width -= spacing_hori; width -= widget_get_width ( WIDGET ( lv->scrollbar ) ); } unsigned int element_width = ( width ) / lv->cur_columns; for ( unsigned int i = 0; i < max; i++ ) { - unsigned int ex = widget_padding_get_left ( wid ) + ( ( i ) / lv->max_rows ) * ( element_width + spacing ); - unsigned int ey = widget_padding_get_top ( wid ) + ( ( i ) % lv->max_rows ) * ( lv->element_height + spacing ); + unsigned int ex = widget_padding_get_left ( wid ) + ( ( i ) / lv->max_rows ) * ( element_width + spacing_hori ); + unsigned int ey = widget_padding_get_top ( wid ) + ( ( i ) % lv->max_rows ) * ( lv->element_height + spacing_vert ); textbox_moveresize ( lv->boxes[i], ex, ey, element_width, lv->element_height ); update_element ( lv, i, i + offset, TRUE ); @@ -256,8 +257,8 @@ static void listview_resize ( widget *wid, short w, short h ) lv->widget.w = MAX ( 0, w ); lv->widget.h = MAX ( 0, h ); int height = lv->widget.h - widget_padding_get_padding_height ( WIDGET (lv) ); - int spacing = distance_get_pixel ( lv->spacing ); - lv->max_rows = ( spacing + height ) / ( lv->element_height + spacing ); + int spacing_vert = distance_get_pixel ( lv->spacing, ORIENTATION_VERTICAL ); + lv->max_rows = ( spacing_vert + height ) / ( lv->element_height + spacing_vert ); lv->max_elements = lv->max_rows * lv->menu_columns; widget_move ( WIDGET ( lv->scrollbar ), @@ -464,7 +465,7 @@ void listview_nav_page_next ( listview *lv ) static int listview_get_desired_height ( widget *wid ) { listview *lv = (listview *)wid; - int spacing = distance_get_pixel ( lv->spacing ); + int spacing = distance_get_pixel ( lv->spacing, ORIENTATION_VERTICAL ); if ( lv == NULL || lv->widget.enabled == FALSE ) { return 0; } diff --git a/source/widgets/widget.c b/source/widgets/widget.c index 23ddddae..5c8342c3 100644 --- a/source/widgets/widget.c +++ b/source/widgets/widget.c @@ -98,10 +98,10 @@ void widget_draw ( widget *widget, cairo_t *d ) // Set new x/y possition. cairo_translate ( d, widget->x, widget->y ); - int left = distance_get_pixel ( widget->border.left ); - int top = distance_get_pixel ( widget->border.top ); - int right = distance_get_pixel ( widget->border.right ); - int bottom = distance_get_pixel ( widget->border.bottom ); + int left = distance_get_pixel ( widget->border.left, ORIENTATION_HORIZONTAL ); + int top = distance_get_pixel ( widget->border.top, ORIENTATION_HORIZONTAL ); + int right = distance_get_pixel ( widget->border.right, ORIENTATION_VERTICAL ); + int bottom = distance_get_pixel ( widget->border.bottom, ORIENTATION_VERTICAL ); rofi_theme_get_color ( widget->class_name, widget->name, widget->state, "foreground", d ); if ( left > 0 ) { cairo_set_line_width ( d, left ); @@ -250,26 +250,26 @@ void widget_set_name ( widget *wid, const char *name ) int widget_padding_get_left ( const widget *wid ) { - int distance = distance_get_pixel ( wid->padding.left ); - distance += distance_get_pixel ( wid->border.left ); + int distance = distance_get_pixel ( wid->padding.left, ORIENTATION_HORIZONTAL ); + distance += distance_get_pixel ( wid->border.left, ORIENTATION_HORIZONTAL ); return distance; } int widget_padding_get_right ( const widget *wid ) { - int distance = distance_get_pixel ( wid->padding.right ); - distance += distance_get_pixel ( wid->border.right ); + int distance = distance_get_pixel ( wid->padding.right, ORIENTATION_HORIZONTAL ); + distance += distance_get_pixel ( wid->border.right, ORIENTATION_HORIZONTAL ); return distance; } int widget_padding_get_top ( const widget *wid ) { - int distance = distance_get_pixel ( wid->padding.top ); - distance += distance_get_pixel ( wid->border.top ); + int distance = distance_get_pixel ( wid->padding.top, ORIENTATION_VERTICAL ); + distance += distance_get_pixel ( wid->border.top, ORIENTATION_VERTICAL ); return distance; } int widget_padding_get_bottom ( const widget *wid ) { - int distance = distance_get_pixel ( wid->padding.bottom ); - distance += distance_get_pixel ( wid->border.bottom ); + int distance = distance_get_pixel ( wid->padding.bottom, ORIENTATION_VERTICAL ); + distance += distance_get_pixel ( wid->border.bottom, ORIENTATION_VERTICAL ); return distance; }