Flatten hierarchy, don't inherit by default.

* add keyword inherit to language parser and theme structure.
This commit is contained in:
Dave Davenport 2017-09-06 10:03:44 +02:00
parent 9b0a430fd4
commit 50998b8f04
6 changed files with 44 additions and 35 deletions

View File

@ -30,6 +30,8 @@ typedef enum
P_LIST,
/** Orientation */
P_ORIENTATION,
/** Inherit */
P_INHERIT,
/** Number of types. */
P_NUM_TYPES,
} PropertyType;

View File

@ -173,6 +173,8 @@ EM (em)
CH (ch)
PERCENT (\%)
INHERIT (inherit)
ASTERIX \*
/* Position */
@ -415,8 +417,10 @@ if ( queue == NULL ){
<PROPERTIES>{CH} { return T_UNIT_CH; }
<PROPERTIES>{PX} { return T_UNIT_PX; }
<PROPERTIES>{PERCENT} { return T_PERCENT; }
<PROPERTIES>{LS_SOLID} { return T_SOLID; }
<PROPERTIES>{LS_DASH} { return T_DASH; }
<PROPERTIES>{LS_SOLID} { return T_SOLID; }
<PROPERTIES>{LS_DASH} { return T_DASH; }
<PROPERTIES>{INHERIT} { return T_INHERIT; }
/**
* Color parsing. It is easier to do this at lexer level.

View File

@ -219,6 +219,8 @@ static ThemeColor hwb_to_rgb ( double h, double w, double b)
%token T_COLOR_TRANSPARENT "Transparent"
%token T_INHERIT "Inherit"
%type <sval> t_entry
%type <theme> t_entry_list
%type <list> t_entry_name_path
@ -322,7 +324,11 @@ t_property_list:
;
t_property
: t_property_name T_PSEP T_INT T_PCLOSE {
: t_property_name T_PSEP T_INHERIT T_PCLOSE {
$$ = rofi_theme_property_create ( P_INHERIT );
$$->name = $1;
}
| t_property_name T_PSEP T_INT T_PCLOSE {
$$ = rofi_theme_property_create ( P_INTEGER );
$$->name = $1;
$$->value.i = $3;

View File

@ -429,6 +429,9 @@ Property *rofi_theme_find_property ( ThemeWidget *widget, PropertyType type, con
while ( widget ) {
if ( widget->properties && g_hash_table_contains ( widget->properties, property ) ) {
Property *p = g_hash_table_lookup ( widget->properties, property );
if ( p ->type == P_INHERIT ) {
return p;
}
if ( p->type == P_LINK ) {
if ( p->value.link.ref == NULL ) {
// Resolve link.
@ -454,14 +457,15 @@ Property *rofi_theme_find_property ( ThemeWidget *widget, PropertyType type, con
if ( exact ) {
return NULL;
}
widget = widget->parent;
// Fall back to defaults.
widget = widget == rofi_theme?NULL:rofi_theme;
}
return NULL;
}
ThemeWidget *rofi_theme_find_widget ( const char *name, const char *state, gboolean exact )
{
// First find exact match based on name.
ThemeWidget *widget = rofi_theme_find ( rofi_theme, name, exact );
ThemeWidget *widget = rofi_theme_find ( rofi_theme, name, FALSE );
widget = rofi_theme_find ( widget, state, exact );
return widget;
@ -472,6 +476,9 @@ int rofi_theme_get_position ( const widget *widget, const char *property, int de
ThemeWidget *wid = rofi_theme_find_widget ( widget->name, widget->state, FALSE );
Property *p = rofi_theme_find_property ( wid, P_POSITION, property, FALSE );
if ( p ) {
if ( p->type == P_INHERIT ) {
return rofi_theme_get_position ( widget->parent, property, def );
}
return p->value.i;
}
g_debug ( "Theme entry: #%s %s property %s unset.", widget->name, widget->state ? widget->state : "", property );

View File

@ -735,7 +735,7 @@ void __create_window ( MenuFlags menu_flags )
}
// Setup font.
// Dummy widget.
box *win = box_create ( "window.box_window", ROFI_ORIENTATION_HORIZONTAL );
box *win = box_create ( "window", ROFI_ORIENTATION_HORIZONTAL );
const char *font = rofi_theme_get_string ( WIDGET ( win ), "font", config.menu_font );
if ( font ) {
PangoFontDescription *pfd = pango_font_description_from_string ( font );
@ -1520,14 +1520,12 @@ static void rofi_view_add_widget ( RofiViewState *state, widget *parent_widget,
{
char *defaults = NULL;
widget *wid = NULL;
char *str = g_strjoin ( ".", parent, name, NULL );
char *strbox = g_strjoin ( ".", str, "box", NULL );
/**
* MAINBOX
*/
if ( strcmp ( name, "mainbox" ) == 0 ) {
wid = (widget *) box_create ( strbox, ROFI_ORIENTATION_VERTICAL );
wid = (widget *) box_create ( name, ROFI_ORIENTATION_VERTICAL );
box_add ( (box *) parent_widget, WIDGET ( wid ), TRUE );
defaults = "inputbar,message,listview,sidebar";
}
@ -1535,7 +1533,7 @@ static void rofi_view_add_widget ( RofiViewState *state, widget *parent_widget,
* INPUTBAR
*/
else if ( strcmp ( name, "inputbar" ) == 0 ) {
wid = (widget *) box_create ( strbox, ROFI_ORIENTATION_HORIZONTAL );
wid = (widget *) box_create ( name, ROFI_ORIENTATION_HORIZONTAL );
defaults = "prompt,entry,case-indicator";
box_add ( (box *) parent_widget, WIDGET ( wid ), FALSE );
}
@ -1548,7 +1546,7 @@ static void rofi_view_add_widget ( RofiViewState *state, widget *parent_widget,
return;
}
// Prompt box.
state->prompt = textbox_create ( WIDGET_TYPE_TEXTBOX_TEXT, str, TB_AUTOWIDTH | TB_AUTOHEIGHT, NORMAL, "", 0, 0 );
state->prompt = textbox_create ( WIDGET_TYPE_TEXTBOX_TEXT, name, TB_AUTOWIDTH | TB_AUTOHEIGHT, NORMAL, "", 0, 0 );
rofi_view_update_prompt ( state );
box_add ( (box *) parent_widget, WIDGET ( state->prompt ), FALSE );
defaults = NULL;
@ -1561,7 +1559,7 @@ static void rofi_view_add_widget ( RofiViewState *state, widget *parent_widget,
g_error ( "Case indicator widget can only be added once to the layout." );
return;
}
state->case_indicator = textbox_create ( WIDGET_TYPE_TEXTBOX_TEXT, str, TB_AUTOWIDTH | TB_AUTOHEIGHT, NORMAL, "*", 0, 0 );
state->case_indicator = textbox_create ( WIDGET_TYPE_TEXTBOX_TEXT, name, TB_AUTOWIDTH | TB_AUTOHEIGHT, NORMAL, "*", 0, 0 );
// Add small separator between case indicator and text box.
box_add ( (box *) parent_widget, WIDGET ( state->case_indicator ), FALSE );
textbox_text ( state->case_indicator, get_matching_state () );
@ -1577,7 +1575,7 @@ static void rofi_view_add_widget ( RofiViewState *state, widget *parent_widget,
// Entry box
TextboxFlags tfl = TB_EDITABLE;
tfl |= ( ( state->menu_flags & MENU_PASSWORD ) == MENU_PASSWORD ) ? TB_PASSWORD : 0;
state->text = textbox_create ( WIDGET_TYPE_EDITBOX, str, tfl | TB_AUTOHEIGHT, NORMAL, NULL, 0, 0 );
state->text = textbox_create ( WIDGET_TYPE_EDITBOX, name, tfl | TB_AUTOHEIGHT, NORMAL, NULL, 0, 0 );
box_add ( (box *) parent_widget, WIDGET ( state->text ), TRUE );
}
/**
@ -1588,13 +1586,11 @@ static void rofi_view_add_widget ( RofiViewState *state, widget *parent_widget,
g_error ( "Message widget can only be added once to the layout." );
return;
}
char *strmsg = g_strjoin ( ".", str, "textbox", NULL );
state->mesg_box = container_create ( strbox );
state->mesg_tb = textbox_create ( WIDGET_TYPE_TEXTBOX_TEXT, strmsg, TB_AUTOHEIGHT | TB_MARKUP | TB_WRAP, NORMAL, NULL, 0, 0 );
state->mesg_box = container_create ( name );
state->mesg_tb = textbox_create ( WIDGET_TYPE_TEXTBOX_TEXT, "textbox", TB_AUTOHEIGHT | TB_MARKUP | TB_WRAP, NORMAL, NULL, 0, 0 );
container_add ( state->mesg_box, WIDGET ( state->mesg_tb ) );
rofi_view_reload_message_bar ( state );
box_add ( (box *) parent_widget, WIDGET ( state->mesg_box ), FALSE );
g_free ( strmsg );
}
/**
* LISTVIEW
@ -1604,7 +1600,7 @@ static void rofi_view_add_widget ( RofiViewState *state, widget *parent_widget,
g_error ( "Listview widget can only be added once to the layout." );
return;
}
state->list_view = listview_create ( str, update_callback, state, config.element_height, 0 );
state->list_view = listview_create ( name, update_callback, state, config.element_height, 0 );
box_add ( (box *) parent_widget, WIDGET ( state->list_view ), TRUE );
// Set configuration
listview_set_multi_select ( state->list_view, ( state->menu_flags & MENU_INDICATOR ) == MENU_INDICATOR );
@ -1624,39 +1620,35 @@ static void rofi_view_add_widget ( RofiViewState *state, widget *parent_widget,
return;
}
if ( config.sidebar_mode ) {
state->sidebar_bar = box_create ( strbox, ROFI_ORIENTATION_HORIZONTAL );
state->sidebar_bar = box_create ( name,ROFI_ORIENTATION_HORIZONTAL );
box_add ( (box *) parent_widget, WIDGET ( state->sidebar_bar ), FALSE );
state->num_modi = rofi_get_num_enabled_modi ();
state->modi = g_malloc0 ( state->num_modi * sizeof ( textbox * ) );
char *strbutton = g_strjoin ( ".", str, "button", NULL );
for ( unsigned int j = 0; j < state->num_modi; j++ ) {
const Mode * mode = rofi_get_mode ( j );
state->modi[j] = textbox_create ( WIDGET_TYPE_SIDEBAR_MODI, strbutton, TB_AUTOHEIGHT, ( mode == state->sw ) ? HIGHLIGHT : NORMAL,
state->modi[j] = textbox_create ( WIDGET_TYPE_SIDEBAR_MODI, "button", TB_AUTOHEIGHT, ( mode == state->sw ) ? HIGHLIGHT : NORMAL,
mode_get_display_name ( mode ), 0.5, 0.5 );
box_add ( state->sidebar_bar, WIDGET ( state->modi[j] ), TRUE );
widget_set_trigger_action_handler ( WIDGET ( state->modi[j] ), textbox_sidebar_modi_trigger_action, state );
}
g_free ( strbutton );
}
}
else if ( g_ascii_strncasecmp ( name, "textbox", 7 ) == 0 ) {
textbox *t = textbox_create ( WIDGET_TYPE_TEXTBOX_TEXT, str, TB_WRAP, NORMAL, "", 0, 0 );
textbox *t = textbox_create ( WIDGET_TYPE_TEXTBOX_TEXT, name, TB_WRAP, NORMAL, "", 0, 0 );
box_add ( (box *) parent_widget, WIDGET ( t ), TRUE );
}
else {
wid = (widget *) box_create ( strbox, ROFI_ORIENTATION_VERTICAL );
wid = (widget *) box_create ( name, ROFI_ORIENTATION_VERTICAL );
box_add ( (box *) parent_widget, WIDGET ( wid ), TRUE );
//g_error("The widget %s does not exists. Invalid layout.", name);
}
if ( wid ) {
GList *list = rofi_theme_get_list ( wid, "children", defaults );
for ( const GList *iter = list; iter != NULL; iter = g_list_next ( iter ) ) {
rofi_view_add_widget ( state, wid, str, (const char *) iter->data );
rofi_view_add_widget ( state, wid, "", (const char *) iter->data );
}
g_list_free_full ( list, g_free );
}
g_free ( strbox );
g_free ( str );
}
RofiViewState *rofi_view_create ( Mode *sw,
@ -1686,7 +1678,7 @@ RofiViewState *rofi_view_create ( Mode *sw,
// Get active monitor size.
TICK_N ( "Get active monitor" );
state->main_window = box_create ( "window.box", ROFI_ORIENTATION_VERTICAL );
state->main_window = box_create ( "window", ROFI_ORIENTATION_VERTICAL );
// Get children.
GList *list = rofi_theme_get_list ( WIDGET ( state->main_window ), "children", "mainbox" );
for ( const GList *iter = list; iter != NULL; iter = g_list_next ( iter ) ) {
@ -1699,7 +1691,7 @@ RofiViewState *rofi_view_create ( Mode *sw,
textbox_cursor_end ( state->text );
}
state->overlay = textbox_create ( WIDGET_TYPE_TEXTBOX_TEXT, "window.overlay", TB_AUTOWIDTH | TB_AUTOHEIGHT, URGENT, "blaat", 0.5, 0 );
state->overlay = textbox_create ( WIDGET_TYPE_TEXTBOX_TEXT, "overlay", TB_AUTOWIDTH | TB_AUTOHEIGHT, URGENT, "blaat", 0.5, 0 );
state->overlay->widget.parent = WIDGET ( state->main_window );
widget_disable ( WIDGET ( state->overlay ) );
@ -1737,10 +1729,10 @@ int rofi_view_error_dialog ( const char *msg, int markup )
state->menu_flags = MENU_ERROR_DIALOG;
state->finalize = process_result;
state->main_window = box_create ( "window.box", ROFI_ORIENTATION_VERTICAL );
box *box = box_create ( "window.mainbox.message.box", ROFI_ORIENTATION_VERTICAL );
state->main_window = box_create ( "window", ROFI_ORIENTATION_VERTICAL );
box *box = box_create ( "message", ROFI_ORIENTATION_VERTICAL );
box_add ( state->main_window, WIDGET ( box ), TRUE );
state->text = textbox_create ( WIDGET_TYPE_TEXTBOX_TEXT, "window.mainbox.message.textbox", ( TB_AUTOHEIGHT | TB_WRAP ) + ( ( markup ) ? TB_MARKUP : 0 ),
state->text = textbox_create ( WIDGET_TYPE_TEXTBOX_TEXT, "textbox", ( TB_AUTOHEIGHT | TB_WRAP ) + ( ( markup ) ? TB_MARKUP : 0 ),
NORMAL, ( msg != NULL ) ? msg : "", 0, 0 );
box_add ( box, WIDGET ( state->text ), TRUE );

View File

@ -368,14 +368,12 @@ static void listview_recompute_elements ( listview *lv )
}
lv->boxes = g_realloc ( lv->boxes, newne * sizeof ( textbox* ) );
if ( newne > 0 ) {
char *name = g_strjoin ( ".", lv->listview_name, "element", NULL );
for ( unsigned int i = lv->cur_elements; i < newne; i++ ) {
TextboxFlags flags = ( lv->multi_select ) ? TB_INDICATOR : 0;
flags |= ( ( config.show_icons ) ? TB_ICON : 0 );
lv->boxes[i] = textbox_create ( WIDGET_TYPE_LISTVIEW_ELEMENT, name, flags, NORMAL, "", 0, 0 );
lv->boxes[i] = textbox_create ( WIDGET_TYPE_LISTVIEW_ELEMENT, "element", flags, NORMAL, "", 0, 0 );
widget_set_trigger_action_handler ( WIDGET ( lv->boxes[i] ), listview_element_trigger_action, lv );
}
g_free ( name );
}
lv->rchanged = TRUE;
lv->cur_elements = newne;