Allow to set anchor position on normitor and anchor position on window.

This commit is contained in:
Dave Davenport 2017-01-06 19:04:25 +01:00
parent 8bc1831d17
commit 06c5f51e7d
7 changed files with 149 additions and 18 deletions

View File

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

View File

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

View File

@ -3,6 +3,7 @@
#include <glib.h>
#include <cairo.h>
#include <widgets/widget.h>
#include <settings.h>
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.

View File

@ -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;
}
<PROPERTIES>{CENTER} {
yylval->sval = WL_CENTER;
return T_POSITION;
}
<PROPERTIES>{EAST} {
yylval->sval = WL_EAST;
return T_POSITION;
}
<PROPERTIES>{WEST} {
yylval->sval = WL_WEST;
return T_POSITION;
}
<PROPERTIES>{SOUTH}{EAST} {
yylval->sval = WL_SOUTH_EAST;
return T_POSITION;
}
<PROPERTIES>{SOUTH}{WEST} {
yylval->sval = WL_SOUTH_WEST;
return T_POSITION;
}
<PROPERTIES>{SOUTH} {
yylval->sval = WL_SOUTH;
return T_POSITION;
}
<PROPERTIES>{NORTH}{EAST} {
yylval->sval = WL_NORTH_EAST;
return T_POSITION;
}
<PROPERTIES>{NORTH}{WEST} {
yylval->sval = WL_NORTH_WEST;
return T_POSITION;
}
<PROPERTIES>{NORTH} {
yylval->sval = WL_NORTH;
return T_POSITION;
}
<PROPERTIES>NORTH {
yylval->sval = WL_NORTH;
return T_POSITION;
}
<INITIAL><<EOF>> {
g_queue_free ( queue );
yyterminate();

View File

@ -38,6 +38,7 @@ int yylex (YYSTYPE *, YYLTYPE *);
%token <fval> T_DOUBLE
%token <sval> T_STRING
%token <sval> N_STRING
%token <sval> T_POSITION;
%token <sval> NAME_ELEMENT
%token <bval> T_BOOLEAN
%token <colorval> 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; }

View File

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

View File

@ -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, "*" );