Commit 2d01f778 authored by Benjamin Otte's avatar Benjamin Otte

css: Add selector change types

This allows querying selectors for which changes would change their
"matchingness".
parent 53317aed
...@@ -29,10 +29,11 @@ typedef struct _GtkCssSelectorClass GtkCssSelectorClass; ...@@ -29,10 +29,11 @@ typedef struct _GtkCssSelectorClass GtkCssSelectorClass;
struct _GtkCssSelectorClass { struct _GtkCssSelectorClass {
const char *name; const char *name;
void (* print) (const GtkCssSelector *selector, void (* print) (const GtkCssSelector *selector,
GString *string); GString *string);
gboolean (* match) (const GtkCssSelector *selector, gboolean (* match) (const GtkCssSelector *selector,
const GtkCssMatcher *matcher); const GtkCssMatcher *matcher);
GtkCssChange (* get_change) (const GtkCssSelector *selector);
guint increase_id_specificity :1; guint increase_id_specificity :1;
guint increase_class_specificity :1; guint increase_class_specificity :1;
...@@ -57,6 +58,15 @@ gtk_css_selector_match (const GtkCssSelector *selector, ...@@ -57,6 +58,15 @@ gtk_css_selector_match (const GtkCssSelector *selector,
return selector->class->match (selector, matcher); return selector->class->match (selector, matcher);
} }
static GtkCssChange
gtk_css_selector_get_change (const GtkCssSelector *selector)
{
if (selector == NULL)
return 0;
return selector->class->get_change (selector);
}
static const GtkCssSelector * static const GtkCssSelector *
gtk_css_selector_previous (const GtkCssSelector *selector) gtk_css_selector_previous (const GtkCssSelector *selector)
{ {
...@@ -91,10 +101,17 @@ gtk_css_selector_descendant_match (const GtkCssSelector *selector, ...@@ -91,10 +101,17 @@ gtk_css_selector_descendant_match (const GtkCssSelector *selector,
return FALSE; return FALSE;
} }
static GtkCssChange
gtk_css_selector_descendant_get_change (const GtkCssSelector *selector)
{
return _gtk_css_change_for_child (gtk_css_selector_get_change (gtk_css_selector_previous (selector)));
}
static const GtkCssSelectorClass GTK_CSS_SELECTOR_DESCENDANT = { static const GtkCssSelectorClass GTK_CSS_SELECTOR_DESCENDANT = {
"descendant", "descendant",
gtk_css_selector_descendant_print, gtk_css_selector_descendant_print,
gtk_css_selector_descendant_match, gtk_css_selector_descendant_match,
gtk_css_selector_descendant_get_change,
FALSE, FALSE, FALSE FALSE, FALSE, FALSE
}; };
...@@ -119,10 +136,17 @@ gtk_css_selector_child_match (const GtkCssSelector *selector, ...@@ -119,10 +136,17 @@ gtk_css_selector_child_match (const GtkCssSelector *selector,
return gtk_css_selector_match (gtk_css_selector_previous (selector), &parent); return gtk_css_selector_match (gtk_css_selector_previous (selector), &parent);
} }
static GtkCssChange
gtk_css_selector_child_get_change (const GtkCssSelector *selector)
{
return _gtk_css_change_for_child (gtk_css_selector_get_change (gtk_css_selector_previous (selector)));
}
static const GtkCssSelectorClass GTK_CSS_SELECTOR_CHILD = { static const GtkCssSelectorClass GTK_CSS_SELECTOR_CHILD = {
"child", "child",
gtk_css_selector_child_print, gtk_css_selector_child_print,
gtk_css_selector_child_match, gtk_css_selector_child_match,
gtk_css_selector_child_get_change,
FALSE, FALSE, FALSE FALSE, FALSE, FALSE
}; };
...@@ -152,10 +176,17 @@ gtk_css_selector_sibling_match (const GtkCssSelector *selector, ...@@ -152,10 +176,17 @@ gtk_css_selector_sibling_match (const GtkCssSelector *selector,
return FALSE; return FALSE;
} }
static GtkCssChange
gtk_css_selector_sibling_get_change (const GtkCssSelector *selector)
{
return _gtk_css_change_for_sibling (gtk_css_selector_get_change (gtk_css_selector_previous (selector)));
}
static const GtkCssSelectorClass GTK_CSS_SELECTOR_SIBLING = { static const GtkCssSelectorClass GTK_CSS_SELECTOR_SIBLING = {
"sibling", "sibling",
gtk_css_selector_sibling_print, gtk_css_selector_sibling_print,
gtk_css_selector_sibling_match, gtk_css_selector_sibling_match,
gtk_css_selector_sibling_get_change,
FALSE, FALSE, FALSE FALSE, FALSE, FALSE
}; };
...@@ -180,10 +211,17 @@ gtk_css_selector_adjacent_match (const GtkCssSelector *selector, ...@@ -180,10 +211,17 @@ gtk_css_selector_adjacent_match (const GtkCssSelector *selector,
return gtk_css_selector_match (gtk_css_selector_previous (selector), &previous); return gtk_css_selector_match (gtk_css_selector_previous (selector), &previous);
} }
static GtkCssChange
gtk_css_selector_adjacent_get_change (const GtkCssSelector *selector)
{
return _gtk_css_change_for_sibling (gtk_css_selector_get_change (gtk_css_selector_previous (selector)));
}
static const GtkCssSelectorClass GTK_CSS_SELECTOR_ADJACENT = { static const GtkCssSelectorClass GTK_CSS_SELECTOR_ADJACENT = {
"adjacent", "adjacent",
gtk_css_selector_adjacent_print, gtk_css_selector_adjacent_print,
gtk_css_selector_adjacent_match, gtk_css_selector_adjacent_match,
gtk_css_selector_adjacent_get_change,
FALSE, FALSE, FALSE FALSE, FALSE, FALSE
}; };
...@@ -213,10 +251,17 @@ gtk_css_selector_any_match (const GtkCssSelector *selector, ...@@ -213,10 +251,17 @@ gtk_css_selector_any_match (const GtkCssSelector *selector,
return gtk_css_selector_match (previous, matcher); return gtk_css_selector_match (previous, matcher);
} }
static GtkCssChange
gtk_css_selector_any_get_change (const GtkCssSelector *selector)
{
return gtk_css_selector_get_change (gtk_css_selector_previous (selector));
}
static const GtkCssSelectorClass GTK_CSS_SELECTOR_ANY = { static const GtkCssSelectorClass GTK_CSS_SELECTOR_ANY = {
"any", "any",
gtk_css_selector_any_print, gtk_css_selector_any_print,
gtk_css_selector_any_match, gtk_css_selector_any_match,
gtk_css_selector_any_get_change,
FALSE, FALSE, FALSE FALSE, FALSE, FALSE
}; };
...@@ -239,10 +284,17 @@ gtk_css_selector_name_match (const GtkCssSelector *selector, ...@@ -239,10 +284,17 @@ gtk_css_selector_name_match (const GtkCssSelector *selector,
return gtk_css_selector_match (gtk_css_selector_previous (selector), matcher); return gtk_css_selector_match (gtk_css_selector_previous (selector), matcher);
} }
static GtkCssChange
gtk_css_selector_name_get_change (const GtkCssSelector *selector)
{
return gtk_css_selector_get_change (gtk_css_selector_previous (selector)) | GTK_CSS_CHANGE_NAME;
}
static const GtkCssSelectorClass GTK_CSS_SELECTOR_NAME = { static const GtkCssSelectorClass GTK_CSS_SELECTOR_NAME = {
"name", "name",
gtk_css_selector_name_print, gtk_css_selector_name_print,
gtk_css_selector_name_match, gtk_css_selector_name_match,
gtk_css_selector_name_get_change,
FALSE, FALSE, TRUE FALSE, FALSE, TRUE
}; };
...@@ -272,10 +324,23 @@ gtk_css_selector_region_match (const GtkCssSelector *selector, ...@@ -272,10 +324,23 @@ gtk_css_selector_region_match (const GtkCssSelector *selector,
return gtk_css_selector_match (previous, matcher); return gtk_css_selector_match (previous, matcher);
} }
static GtkCssChange
gtk_css_selector_region_get_change (const GtkCssSelector *selector)
{
GtkCssChange change;
change = gtk_css_selector_get_change (gtk_css_selector_previous (selector));
change |= GTK_CSS_CHANGE_REGION;
change |= _gtk_css_change_for_child (change);
return change;
}
static const GtkCssSelectorClass GTK_CSS_SELECTOR_REGION = { static const GtkCssSelectorClass GTK_CSS_SELECTOR_REGION = {
"region", "region",
gtk_css_selector_region_print, gtk_css_selector_region_print,
gtk_css_selector_region_match, gtk_css_selector_region_match,
gtk_css_selector_region_get_change,
FALSE, FALSE, TRUE FALSE, FALSE, TRUE
}; };
...@@ -299,10 +364,17 @@ gtk_css_selector_class_match (const GtkCssSelector *selector, ...@@ -299,10 +364,17 @@ gtk_css_selector_class_match (const GtkCssSelector *selector,
return gtk_css_selector_match (gtk_css_selector_previous (selector), matcher); return gtk_css_selector_match (gtk_css_selector_previous (selector), matcher);
} }
static GtkCssChange
gtk_css_selector_class_get_change (const GtkCssSelector *selector)
{
return gtk_css_selector_get_change (gtk_css_selector_previous (selector)) | GTK_CSS_CHANGE_CLASS;
}
static const GtkCssSelectorClass GTK_CSS_SELECTOR_CLASS = { static const GtkCssSelectorClass GTK_CSS_SELECTOR_CLASS = {
"class", "class",
gtk_css_selector_class_print, gtk_css_selector_class_print,
gtk_css_selector_class_match, gtk_css_selector_class_match,
gtk_css_selector_class_get_change,
FALSE, TRUE, FALSE FALSE, TRUE, FALSE
}; };
...@@ -326,10 +398,17 @@ gtk_css_selector_id_match (const GtkCssSelector *selector, ...@@ -326,10 +398,17 @@ gtk_css_selector_id_match (const GtkCssSelector *selector,
return gtk_css_selector_match (gtk_css_selector_previous (selector), matcher); return gtk_css_selector_match (gtk_css_selector_previous (selector), matcher);
} }
static GtkCssChange
gtk_css_selector_id_get_change (const GtkCssSelector *selector)
{
return gtk_css_selector_get_change (gtk_css_selector_previous (selector)) | GTK_CSS_CHANGE_ID;
}
static const GtkCssSelectorClass GTK_CSS_SELECTOR_ID = { static const GtkCssSelectorClass GTK_CSS_SELECTOR_ID = {
"id", "id",
gtk_css_selector_id_print, gtk_css_selector_id_print,
gtk_css_selector_id_match, gtk_css_selector_id_match,
gtk_css_selector_id_get_change,
TRUE, FALSE, FALSE TRUE, FALSE, FALSE
}; };
...@@ -377,10 +456,17 @@ gtk_css_selector_pseudoclass_state_match (const GtkCssSelector *selector, ...@@ -377,10 +456,17 @@ gtk_css_selector_pseudoclass_state_match (const GtkCssSelector *selector,
return gtk_css_selector_match (gtk_css_selector_previous (selector), matcher); return gtk_css_selector_match (gtk_css_selector_previous (selector), matcher);
} }
static GtkCssChange
gtk_css_selector_pseudoclass_state_get_change (const GtkCssSelector *selector)
{
return gtk_css_selector_get_change (gtk_css_selector_previous (selector)) | GTK_CSS_CHANGE_STATE;
}
static const GtkCssSelectorClass GTK_CSS_SELECTOR_PSEUDOCLASS_STATE = { static const GtkCssSelectorClass GTK_CSS_SELECTOR_PSEUDOCLASS_STATE = {
"pseudoclass-state", "pseudoclass-state",
gtk_css_selector_pseudoclass_state_print, gtk_css_selector_pseudoclass_state_print,
gtk_css_selector_pseudoclass_state_match, gtk_css_selector_pseudoclass_state_match,
gtk_css_selector_pseudoclass_state_get_change,
FALSE, TRUE, FALSE FALSE, TRUE, FALSE
}; };
...@@ -487,10 +573,17 @@ gtk_css_selector_pseudoclass_region_match (const GtkCssSelector *selector, ...@@ -487,10 +573,17 @@ gtk_css_selector_pseudoclass_region_match (const GtkCssSelector *selector,
return gtk_css_selector_match (previous, matcher); return gtk_css_selector_match (previous, matcher);
} }
static GtkCssChange
gtk_css_selector_pseudoclass_region_get_change (const GtkCssSelector *selector)
{
return gtk_css_selector_get_change (gtk_css_selector_previous (selector)) | GTK_CSS_CHANGE_POSITION;
}
static const GtkCssSelectorClass GTK_CSS_SELECTOR_PSEUDOCLASS_REGION = { static const GtkCssSelectorClass GTK_CSS_SELECTOR_PSEUDOCLASS_REGION = {
"pseudoclass-region", "pseudoclass-region",
gtk_css_selector_pseudoclass_region_print, gtk_css_selector_pseudoclass_region_print,
gtk_css_selector_pseudoclass_region_match, gtk_css_selector_pseudoclass_region_match,
gtk_css_selector_pseudoclass_region_get_change,
FALSE, TRUE, FALSE FALSE, TRUE, FALSE
}; };
...@@ -815,6 +908,14 @@ _gtk_css_selector_to_string (const GtkCssSelector *selector) ...@@ -815,6 +908,14 @@ _gtk_css_selector_to_string (const GtkCssSelector *selector)
return g_string_free (string, FALSE); return g_string_free (string, FALSE);
} }
GtkCssChange
_gtk_css_selector_get_change (const GtkCssSelector *selector)
{
g_return_val_if_fail (selector != NULL, 0);
return gtk_css_selector_get_change (selector);
}
/** /**
* _gtk_css_selector_matches: * _gtk_css_selector_matches:
* @selector: the selector * @selector: the selector
......
...@@ -18,8 +18,6 @@ ...@@ -18,8 +18,6 @@
#ifndef __GTK_CSS_SELECTOR_PRIVATE_H__ #ifndef __GTK_CSS_SELECTOR_PRIVATE_H__
#define __GTK_CSS_SELECTOR_PRIVATE_H__ #define __GTK_CSS_SELECTOR_PRIVATE_H__
#include <gtk/gtkenums.h>
#include <gtk/gtktypes.h>
#include "gtk/gtkcssmatcherprivate.h" #include "gtk/gtkcssmatcherprivate.h"
#include "gtk/gtkcssparserprivate.h" #include "gtk/gtkcssparserprivate.h"
...@@ -36,6 +34,7 @@ void _gtk_css_selector_print (const GtkCssSelector *sel ...@@ -36,6 +34,7 @@ void _gtk_css_selector_print (const GtkCssSelector *sel
GtkStateFlags _gtk_css_selector_get_state_flags (const GtkCssSelector *selector); GtkStateFlags _gtk_css_selector_get_state_flags (const GtkCssSelector *selector);
GtkCssChange _gtk_css_selector_get_change (const GtkCssSelector *selector);
gboolean _gtk_css_selector_matches (const GtkCssSelector *selector, gboolean _gtk_css_selector_matches (const GtkCssSelector *selector,
const GtkCssMatcher *matcher); const GtkCssMatcher *matcher);
int _gtk_css_selector_compare (const GtkCssSelector *a, int _gtk_css_selector_compare (const GtkCssSelector *a,
......
...@@ -36,6 +36,62 @@ DEFINE_BOXED_TYPE_WITH_COPY_FUNC (GtkCssBorderCornerRadius, _gtk_css_border_corn ...@@ -36,6 +36,62 @@ DEFINE_BOXED_TYPE_WITH_COPY_FUNC (GtkCssBorderCornerRadius, _gtk_css_border_corn
DEFINE_BOXED_TYPE_WITH_COPY_FUNC (GtkCssBorderImageRepeat, _gtk_css_border_image_repeat) DEFINE_BOXED_TYPE_WITH_COPY_FUNC (GtkCssBorderImageRepeat, _gtk_css_border_image_repeat)
DEFINE_BOXED_TYPE_WITH_COPY_FUNC (GtkCssNumber, _gtk_css_number) DEFINE_BOXED_TYPE_WITH_COPY_FUNC (GtkCssNumber, _gtk_css_number)
typedef struct _GtkCssChangeTranslation GtkCssChangeTranslation;
struct _GtkCssChangeTranslation {
GtkCssChange from;
GtkCssChange to;
};
static GtkCssChange
gtk_css_change_translate (GtkCssChange match,
const GtkCssChangeTranslation *translations,
guint n_translations)
{
GtkCssChange result = match;
guint i;
for (i = 0; i < n_translations; i++)
{
if (match & translations[i].from)
{
result &= ~translations[i].from;
result |= translations[i].to;
}
}
return result;
}
GtkCssChange
_gtk_css_change_for_sibling (GtkCssChange match)
{
static const GtkCssChangeTranslation table[] = {
{ GTK_CSS_CHANGE_CLASS, GTK_CSS_CHANGE_SIBLING_CLASS },
{ GTK_CSS_CHANGE_NAME, GTK_CSS_CHANGE_SIBLING_NAME },
{ GTK_CSS_CHANGE_POSITION, GTK_CSS_CHANGE_SIBLING_POSITION },
{ GTK_CSS_CHANGE_STATE, GTK_CSS_CHANGE_SIBLING_STATE },
};
return gtk_css_change_translate (match, table, G_N_ELEMENTS (table));
}
GtkCssChange
_gtk_css_change_for_child (GtkCssChange match)
{
static const GtkCssChangeTranslation table[] = {
{ GTK_CSS_CHANGE_CLASS, GTK_CSS_CHANGE_PARENT_CLASS },
{ GTK_CSS_CHANGE_NAME, GTK_CSS_CHANGE_PARENT_NAME },
{ GTK_CSS_CHANGE_POSITION, GTK_CSS_CHANGE_PARENT_POSITION },
{ GTK_CSS_CHANGE_STATE, GTK_CSS_CHANGE_PARENT_STATE },
{ GTK_CSS_CHANGE_SIBLING_CLASS, GTK_CSS_CHANGE_PARENT_SIBLING_CLASS },
{ GTK_CSS_CHANGE_SIBLING_NAME, GTK_CSS_CHANGE_PARENT_SIBLING_NAME },
{ GTK_CSS_CHANGE_SIBLING_POSITION, GTK_CSS_CHANGE_PARENT_SIBLING_POSITION },
{ GTK_CSS_CHANGE_SIBLING_STATE, GTK_CSS_CHANGE_PARENT_SIBLING_STATE }
};
return gtk_css_change_translate (match, table, G_N_ELEMENTS (table));
}
void void
_gtk_css_number_init (GtkCssNumber *number, _gtk_css_number_init (GtkCssNumber *number,
double value, double value,
......
...@@ -23,6 +23,37 @@ ...@@ -23,6 +23,37 @@
G_BEGIN_DECLS G_BEGIN_DECLS
typedef enum { /*< skip >*/
GTK_CSS_CHANGE_CLASS = (1 << 0),
GTK_CSS_CHANGE_NAME = (1 << 1),
GTK_CSS_CHANGE_ID = GTK_CSS_CHANGE_NAME,
GTK_CSS_CHANGE_REGION = GTK_CSS_CHANGE_NAME,
GTK_CSS_CHANGE_POSITION = (1 << 2),
GTK_CSS_CHANGE_STATE = (1 << 3),
GTK_CSS_CHANGE_SIBLING_CLASS = (1 << 4),
GTK_CSS_CHANGE_SIBLING_NAME = (1 << 5),
GTK_CSS_CHANGE_SIBLING_POSITION = (1 << 6),
GTK_CSS_CHANGE_SIBLING_STATE = (1 << 7),
GTK_CSS_CHANGE_PARENT_CLASS = (1 << 8),
GTK_CSS_CHANGE_PARENT_NAME = (1 << 9),
GTK_CSS_CHANGE_PARENT_POSITION = (1 << 10),
GTK_CSS_CHANGE_PARENT_STATE = (1 << 11),
GTK_CSS_CHANGE_PARENT_SIBLING_CLASS = (1 << 12),
GTK_CSS_CHANGE_PARENT_SIBLING_NAME = (1 << 13),
GTK_CSS_CHANGE_PARENT_SIBLING_POSITION = (1 << 14),
GTK_CSS_CHANGE_PARENT_SIBLING_STATE = (1 << 15),
/* add more */
} GtkCssChange;
#define GTK_CSS_CHANGE_ANY ((1 << 16) - 1)
#define GTK_CSS_CHANGE_ANY_SELF (GTK_CSS_CHANGE_CLASS | GTK_CSS_CHANGE_NAME | GTK_CSS_CHANGE_POSITION | GTK_CSS_CHANGE_STATE)
#define GTK_CSS_CHANGE_ANY_SIBLING (GTK_CSS_CHANGE_SIBLING_CLASS | GTK_CSS_CHANGE_SIBLING_NAME | \
GTK_CSS_CHANGE_SIBLING_POSITION | GTK_CSS_CHANGE_SIBLING_STATE)
#define GTK_CSS_CHANGE_ANY_PARENT (GTK_CSS_CHANGE_PARENT_CLASS | GTK_CSS_CHANGE_PARENT_SIBLING_CLASS | \
GTK_CSS_CHANGE_PARENT_NAME | GTK_CSS_CHANGE_PARENT_SIBLING_NAME | \
GTK_CSS_CHANGE_PARENT_POSITION | GTK_CSS_CHANGE_PARENT_SIBLING_POSITION | \
GTK_CSS_CHANGE_PARENT_STATE | GTK_CSS_CHANGE_PARENT_SIBLING_STATE)
typedef enum { typedef enum {
GTK_CSS_INHERIT, GTK_CSS_INHERIT,
GTK_CSS_INITIAL GTK_CSS_INITIAL
...@@ -142,6 +173,9 @@ GType _gtk_css_border_corner_radius_get_type (void); ...@@ -142,6 +173,9 @@ GType _gtk_css_border_corner_radius_get_type (void);
GType _gtk_css_border_image_repeat_get_type (void); GType _gtk_css_border_image_repeat_get_type (void);
GType _gtk_css_number_get_type (void); GType _gtk_css_number_get_type (void);
GtkCssChange _gtk_css_change_for_sibling (GtkCssChange match);
GtkCssChange _gtk_css_change_for_child (GtkCssChange match);
#define GTK_CSS_NUMBER_INIT(_value,_unit) { (_value), (_unit) } #define GTK_CSS_NUMBER_INIT(_value,_unit) { (_value), (_unit) }
void _gtk_css_number_init (GtkCssNumber *number, void _gtk_css_number_init (GtkCssNumber *number,
double value, double value,
......
Markdown is supported
0% or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment