From 06c5f51e7dbaeee8723c3c2c8c753df37b860f85 Mon Sep 17 00:00:00 2001 From: Dave Davenport Date: Fri, 6 Jan 2017 19:04:25 +0100 Subject: [PATCH] Allow to set anchor position on normitor and anchor position on window. --- doc/themer.md | 5 +++ include/settings.h | 2 +- include/theme.h | 15 +++++++++ lexer/theme-lexer.l | 47 +++++++++++++++++++++++++++ lexer/theme-parser.y | 6 ++++ source/theme.c | 17 +++++++++- source/view.c | 75 ++++++++++++++++++++++++++++++++++---------- 7 files changed, 149 insertions(+), 18 deletions(-) diff --git a/doc/themer.md b/doc/themer.md index 9526dc70..58cb3c24 100644 --- a/doc/themer.md +++ b/doc/themer.md @@ -116,6 +116,7 @@ Value supports the following formats: * unit can be px,em,%. for px `{size}` is an integer number, for %,em it is a positive real. * {line-style} can be `dash` or `solid` and is optional. * padding: `({distance}){1,4}` + * position: (center|north|south|east|west|northeast|northwest|southwest|southeast) Each property is closed by a semi-colon `;`; @@ -136,6 +137,10 @@ The following properties are currently supports: - background - screenshot - Path to png file + * position: position + The place of the anchor on the monitor. + * anchor: anchor + The anchor position on the window. * scrollbar * foreground: color diff --git a/include/settings.h b/include/settings.h index 76f053cf..344208e2 100644 --- a/include/settings.h +++ b/include/settings.h @@ -38,7 +38,7 @@ typedef enum /** Middle right */ WL_EAST = 4, /** Bottom right */ - WL_EAST_SOUTH = 5, + WL_SOUTH_EAST = 5, /** Bottom middle */ WL_SOUTH = 6, /** Bottom left */ diff --git a/include/theme.h b/include/theme.h index ee5acb6f..fd318760 100644 --- a/include/theme.h +++ b/include/theme.h @@ -3,6 +3,7 @@ #include #include #include +#include typedef enum { SOLID, @@ -57,6 +58,8 @@ typedef enum { P_PADDING, /** Link to global setting */ P_LINK, + /** Position */ + P_POSITION, } PropertyType; /** @@ -202,6 +205,18 @@ Distance rofi_theme_get_distance ( const widget *widget, const char *property, i * @returns The integer value of this property for this widget. */ int rofi_theme_get_integer ( const widget *widget, const char *property, int def ); + +/** + * @param widget The widget to query + * @param property The property to query. + * @param def The default value. + * + * Obtain the position of the widget. + * + * @returns The position value of this property for this widget. + */ +int rofi_theme_get_position ( const widget *widget, const char *property, int def ); + /** * @param widget The widget to query * @param property The property to query. diff --git a/lexer/theme-lexer.l b/lexer/theme-lexer.l index 5ace2d2a..e5995e25 100644 --- a/lexer/theme-lexer.l +++ b/lexer/theme-lexer.l @@ -31,6 +31,12 @@ PX (px) EM (em) PERCENT (\%) +CENTER "center" +NORTH "north" +SOUTH "south" +EAST "east" +WEST "west" + LS_DASH "dash" LS_SOLID "solid" @@ -213,6 +219,47 @@ if ( queue == NULL ){ yylval->colorval.alpha = 1.0; return T_COLOR; } + +{CENTER} { + yylval->sval = WL_CENTER; + return T_POSITION; +} +{EAST} { + yylval->sval = WL_EAST; + return T_POSITION; +} +{WEST} { + yylval->sval = WL_WEST; + return T_POSITION; +} +{SOUTH}{EAST} { + yylval->sval = WL_SOUTH_EAST; + return T_POSITION; +} +{SOUTH}{WEST} { + yylval->sval = WL_SOUTH_WEST; + return T_POSITION; +} +{SOUTH} { + yylval->sval = WL_SOUTH; + return T_POSITION; +} +{NORTH}{EAST} { + yylval->sval = WL_NORTH_EAST; + return T_POSITION; +} +{NORTH}{WEST} { + yylval->sval = WL_NORTH_WEST; + return T_POSITION; +} +{NORTH} { + yylval->sval = WL_NORTH; + return T_POSITION; +} +NORTH { + yylval->sval = WL_NORTH; + return T_POSITION; +} <> { g_queue_free ( queue ); yyterminate(); diff --git a/lexer/theme-parser.y b/lexer/theme-parser.y index d520c299..81add24e 100644 --- a/lexer/theme-parser.y +++ b/lexer/theme-parser.y @@ -38,6 +38,7 @@ int yylex (YYSTYPE *, YYLTYPE *); %token T_DOUBLE %token T_STRING %token N_STRING +%token T_POSITION; %token NAME_ELEMENT %token T_BOOLEAN %token T_COLOR @@ -177,6 +178,11 @@ property $$->name = $1; $$->value.padding = (Padding){ $3, $4, $5, $6 }; } +| pvalue PSEP T_POSITION PCLOSE{ + $$ = rofi_theme_property_create ( P_POSITION ); + $$->name = $1; + $$->value.i = $3; +} ; pvalue: N_STRING { $$ = $1; } diff --git a/source/theme.c b/source/theme.c index 2b106848..2680a504 100644 --- a/source/theme.c +++ b/source/theme.c @@ -93,6 +93,10 @@ static void rofi_theme_print_property_index ( int depth, Property *p ) printf("%*s%s: ", depth, "", p->name ); switch ( p->type ) { + case P_POSITION: + // TODO Name + printf("%d;", p->value.i); + break; case P_STRING: printf("\"%s\";", p->value.s); break; @@ -346,6 +350,17 @@ static ThemeWidget *rofi_theme_find_widget ( const char *name, const char *state return widget; } +int rofi_theme_get_position ( const widget *widget, const char *property, int def ) +{ + ThemeWidget *wid = rofi_theme_find_widget ( widget->name, widget->state, FALSE ); + Property *p = rofi_theme_find_property ( wid, P_POSITION, property, FALSE ); + if ( p ){ + return p->value.i; + } + g_log ( LOG_DOMAIN, G_LOG_LEVEL_DEBUG, "Theme entry: #%s %s property %s unset.", widget->name, widget->state?widget->state:"", property ); + return def; +} + int rofi_theme_get_integer ( const widget *widget, const char *property, int def ) { ThemeWidget *wid = rofi_theme_find_widget ( widget->name, widget->state, FALSE ); @@ -553,7 +568,7 @@ void rofi_theme_convert_old_theme ( void ) LineStyle style = (g_strcmp0(config.separator_style,"dash") == 0)?DASH:SOLID; - int place_end = ( config.location == WL_EAST_SOUTH || config.location == WL_SOUTH || config.location == WL_SOUTH_WEST ); + int place_end = ( config.location == WL_SOUTH_EAST || config.location == WL_SOUTH || config.location == WL_SOUTH_WEST ); p = rofi_theme_property_create ( P_PADDING ); p->name = g_strdup("border"); Distance d = (Distance){config.menu_bw, PW_PX, style}; diff --git a/source/view.c b/source/view.c index 46c17637..e2f71513 100644 --- a/source/view.c +++ b/source/view.c @@ -253,22 +253,29 @@ static void rofi_view_update_prompt ( RofiViewState *state ) */ static void rofi_view_calculate_window_position ( RofiViewState *state ) { + int location = rofi_theme_get_position ( WIDGET ( state->main_window ), "location", config.location ); + int anchor = location; + if ( !config.fixed_num_lines ) { + anchor = location; + if ( location == WL_CENTER ) { + anchor = WL_NORTH; + } else if ( location == WL_EAST ) { + anchor = WL_NORTH_EAST; + } else if (location == WL_WEST ) { + anchor = WL_NORTH_WEST; + } + } + anchor = rofi_theme_get_position ( WIDGET ( state->main_window ), "anchor", anchor ); + if ( config.fullscreen ) { state->x = CacheState.mon.x; state->y = CacheState.mon.y; return; } - - if ( !config.fixed_num_lines && ( config.location == WL_CENTER || config.location == WL_EAST || config.location == WL_WEST ) ) { - state->y = CacheState.mon.y + CacheState.mon.h / 2 - widget_get_height ( WIDGET ( state->input_bar ) ); - } - else { - // Default location is center. - state->y = CacheState.mon.y + ( CacheState.mon.h - state->height ) / 2; - } - state->x = CacheState.mon.x + ( CacheState.mon.w - state->width ) / 2; + state->y = CacheState.mon.y + ( CacheState.mon.h ) / 2; + state->x = CacheState.mon.x + ( CacheState.mon.w ) / 2; // Determine window location - switch ( config.location ) + switch ( location ) { case WL_NORTH_WEST: state->x = CacheState.mon.x; @@ -278,15 +285,15 @@ static void rofi_view_calculate_window_position ( RofiViewState *state ) case WL_NORTH_EAST: state->y = CacheState.mon.y; case WL_EAST: - state->x = CacheState.mon.x + CacheState.mon.w - state->width; + state->x = CacheState.mon.x + CacheState.mon.w; break; - case WL_EAST_SOUTH: - state->x = CacheState.mon.x + CacheState.mon.w - state->width; + case WL_SOUTH_EAST: + state->x = CacheState.mon.x + CacheState.mon.w; case WL_SOUTH: - state->y = CacheState.mon.y + CacheState.mon.h - state->height; + state->y = CacheState.mon.y + CacheState.mon.h; break; case WL_SOUTH_WEST: - state->y = CacheState.mon.y + CacheState.mon.h - state->height; + state->y = CacheState.mon.y + CacheState.mon.h; case WL_WEST: state->x = CacheState.mon.x; break; @@ -294,6 +301,41 @@ static void rofi_view_calculate_window_position ( RofiViewState *state ) default: break; } + switch ( anchor ) + { + case WL_SOUTH_WEST: + state->y -= state->height; + break; + case WL_SOUTH: + state->x -= state->width/2; + state->y -= state->height; + break; + case WL_SOUTH_EAST: + state->x -= state->width; + state->y -= state->height; + break; + case WL_NORTH_EAST: + state->x -= state->width; + break; + case WL_NORTH_WEST: + break; + case WL_NORTH: + state->x -= state->width/2; + break; + case WL_EAST: + state->x -= state->width; + state->y -= state->height/2; + break; + case WL_WEST: + state->y -= state->height/2; + break; + case WL_CENTER: + state->y -= state->height/2; + state->x -= state->width/2; + break; + default: + break; + } // Apply offset. state->x += config.x_offset; state->y += config.y_offset; @@ -1469,7 +1511,8 @@ RofiViewState *rofi_view_create ( Mode *sw, } } - int end = ( config.location == WL_EAST_SOUTH || config.location == WL_SOUTH || config.location == WL_SOUTH_WEST ); + int location = rofi_theme_get_position ( WIDGET ( state->main_window ), "location", config.location ); + int end = ( location == WL_SOUTH_EAST || location == WL_SOUTH || location == WL_SOUTH_WEST ); box_add ( state->main_box, WIDGET ( state->input_bar ), FALSE, end?9:0 ); state->case_indicator = textbox_create ( "window.mainbox.inputbar.case-indicator", TB_AUTOWIDTH|TB_AUTOHEIGHT, NORMAL, "*" );