[StWidget] add list-like methods for style_class and pseudo_class
Since style_class and pseudo_class are space-separated lists of names, add new methods to add and remove individual names rather than just re-setting the entire name. Update existing code to use the new pseudo-class methods where appropriate. In some cases, this may result in actors having multiple pseudoclasses where previously they only had one at a time, but there don't seem to be any visible differences. (There are some places that could usefully use the new style_class methods as well, but this patch doesn't change them.) Also, update test-theme.c to test the new methods. https://bugzilla.gnome.org/show_bug.cgi?id=604943
This commit is contained in:
parent
7c37e94eda
commit
909b5ec43c
@ -797,12 +797,12 @@ AppIconMenu.prototype = {
|
|||||||
|
|
||||||
_updateHighlight: function (item) {
|
_updateHighlight: function (item) {
|
||||||
if (this._highlightedItem) {
|
if (this._highlightedItem) {
|
||||||
this._highlightedItem.set_style_pseudo_class(null);
|
this._highlightedItem.remove_style_pseudo_class('hover');
|
||||||
this.emit('highlight-window', null);
|
this.emit('highlight-window', null);
|
||||||
}
|
}
|
||||||
this._highlightedItem = item;
|
this._highlightedItem = item;
|
||||||
if (this._highlightedItem) {
|
if (this._highlightedItem) {
|
||||||
item.set_style_pseudo_class('hover');
|
item.add_style_pseudo_class('hover');
|
||||||
let window = this._highlightedItem._window;
|
let window = this._highlightedItem._window;
|
||||||
if (window)
|
if (window)
|
||||||
this.emit('highlight-window', window);
|
this.emit('highlight-window', window);
|
||||||
|
@ -359,7 +359,10 @@ SearchResult.prototype = {
|
|||||||
},
|
},
|
||||||
|
|
||||||
setSelected: function(selected) {
|
setSelected: function(selected) {
|
||||||
this._content.set_style_pseudo_class(selected ? 'selected' : null);
|
if (selected)
|
||||||
|
this._content.add_style_pseudo_class('selected');
|
||||||
|
else
|
||||||
|
this._content.remove_style_pseudo_class('selected');
|
||||||
},
|
},
|
||||||
|
|
||||||
activate: function() {
|
activate: function() {
|
||||||
@ -630,10 +633,10 @@ MoreLink.prototype = {
|
|||||||
setPane: function (pane) {
|
setPane: function (pane) {
|
||||||
this._pane = pane;
|
this._pane = pane;
|
||||||
this._pane.connect('open-state-changed', Lang.bind(this, function(pane, isOpen) {
|
this._pane.connect('open-state-changed', Lang.bind(this, function(pane, isOpen) {
|
||||||
if (!isOpen)
|
if (isOpen)
|
||||||
this._expander.style_class = 'more-link-expander';
|
this._expander.add_style_class_name('open');
|
||||||
else
|
else
|
||||||
this._expander.style_class = 'more-link-expander open';
|
this._expander.remove_style_class_name('open');
|
||||||
}));
|
}));
|
||||||
}
|
}
|
||||||
};
|
};
|
||||||
|
@ -105,7 +105,10 @@ GenericDisplayItem.prototype = {
|
|||||||
// Highlights the item by setting a different background color than the default
|
// Highlights the item by setting a different background color than the default
|
||||||
// if isSelected is true, removes the highlighting otherwise.
|
// if isSelected is true, removes the highlighting otherwise.
|
||||||
markSelected: function(isSelected) {
|
markSelected: function(isSelected) {
|
||||||
this.actor.set_style_pseudo_class(isSelected ? "selected" : null);
|
if (iSelected)
|
||||||
|
this.actor.add_style_pseudo_class('selected');
|
||||||
|
else
|
||||||
|
this.actor.remove_style_pseudo_class('selected');
|
||||||
},
|
},
|
||||||
|
|
||||||
/*
|
/*
|
||||||
|
@ -84,7 +84,7 @@ Notebook.prototype = {
|
|||||||
if (this._selectedIndex < 0)
|
if (this._selectedIndex < 0)
|
||||||
return;
|
return;
|
||||||
let tabData = this._tabs[this._selectedIndex];
|
let tabData = this._tabs[this._selectedIndex];
|
||||||
tabData.labelBox.set_style_pseudo_class(null);
|
tabData.labelBox.remove_style_pseudo_class('selected');
|
||||||
tabData.scrollView.hide();
|
tabData.scrollView.hide();
|
||||||
this._selectedIndex = -1;
|
this._selectedIndex = -1;
|
||||||
},
|
},
|
||||||
@ -98,7 +98,7 @@ Notebook.prototype = {
|
|||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
let tabData = this._tabs[index];
|
let tabData = this._tabs[index];
|
||||||
tabData.labelBox.set_style_pseudo_class('selected');
|
tabData.labelBox.add_style_pseudo_class('selected');
|
||||||
tabData.scrollView.show();
|
tabData.scrollView.show();
|
||||||
this._selectedIndex = index;
|
this._selectedIndex = index;
|
||||||
this.emit('selection', tabData.child);
|
this.emit('selection', tabData.child);
|
||||||
|
@ -484,7 +484,10 @@ NewWorkspaceArea.prototype = {
|
|||||||
},
|
},
|
||||||
|
|
||||||
setStyle: function(isHover) {
|
setStyle: function(isHover) {
|
||||||
this._child1.set_style_pseudo_class(isHover ? 'hover' : null);
|
if (isHover)
|
||||||
|
this._child1.add_style_pseudo_class('hover');
|
||||||
|
else
|
||||||
|
this._child1.remove_style_pseudo_class('hover');
|
||||||
}
|
}
|
||||||
};
|
};
|
||||||
|
|
||||||
|
@ -161,6 +161,6 @@ libst_1_0_la_LDFLAGS = $(LDADD)
|
|||||||
noinst_PROGRAMS += test-theme
|
noinst_PROGRAMS += test-theme
|
||||||
|
|
||||||
test_theme_CPPFLAGS = $(st_cflags)
|
test_theme_CPPFLAGS = $(st_cflags)
|
||||||
test_theme_LDADD = libst-1.0.la
|
test_theme_LDADD = libst-1.0.la libbig-1.0.la
|
||||||
|
|
||||||
test_theme_SOURCES = st/test-theme.c
|
test_theme_SOURCES = st/test-theme.c
|
||||||
|
@ -133,21 +133,13 @@ st_button_style_changed (StWidget *widget)
|
|||||||
static void
|
static void
|
||||||
st_button_real_pressed (StButton *button)
|
st_button_real_pressed (StButton *button)
|
||||||
{
|
{
|
||||||
st_widget_set_style_pseudo_class ((StWidget*) button, "active");
|
st_widget_add_style_pseudo_class ((StWidget*) button, "active");
|
||||||
}
|
}
|
||||||
|
|
||||||
static void
|
static void
|
||||||
st_button_real_released (StButton *button)
|
st_button_real_released (StButton *button)
|
||||||
{
|
{
|
||||||
StButtonPrivate *priv = button->priv;
|
st_widget_remove_style_pseudo_class ((StWidget*) button, "active");
|
||||||
|
|
||||||
if (priv->is_checked)
|
|
||||||
st_widget_set_style_pseudo_class ((StWidget*) button, "checked");
|
|
||||||
else if (!priv->is_hover)
|
|
||||||
st_widget_set_style_pseudo_class ((StWidget*) button, NULL);
|
|
||||||
else
|
|
||||||
st_widget_set_style_pseudo_class ((StWidget*) button, "hover");
|
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|
||||||
static gboolean
|
static gboolean
|
||||||
@ -212,8 +204,7 @@ st_button_enter (ClutterActor *actor,
|
|||||||
{
|
{
|
||||||
StButton *button = ST_BUTTON (actor);
|
StButton *button = ST_BUTTON (actor);
|
||||||
|
|
||||||
if (!button->priv->is_checked)
|
st_widget_add_style_pseudo_class ((StWidget*) button, "hover");
|
||||||
st_widget_set_style_pseudo_class ((StWidget*) button, "hover");
|
|
||||||
|
|
||||||
button->priv->is_hover = 1;
|
button->priv->is_hover = 1;
|
||||||
|
|
||||||
@ -240,10 +231,7 @@ st_button_leave (ClutterActor *actor,
|
|||||||
klass->released (button);
|
klass->released (button);
|
||||||
}
|
}
|
||||||
|
|
||||||
if (button->priv->is_checked)
|
st_widget_remove_style_pseudo_class ((StWidget*) button, "hover");
|
||||||
st_widget_set_style_pseudo_class ((StWidget*) button, "checked");
|
|
||||||
else
|
|
||||||
st_widget_set_style_pseudo_class ((StWidget*) button, NULL);
|
|
||||||
|
|
||||||
return CLUTTER_ACTOR_CLASS (st_button_parent_class)->leave_event (actor, event);
|
return CLUTTER_ACTOR_CLASS (st_button_parent_class)->leave_event (actor, event);
|
||||||
}
|
}
|
||||||
@ -558,12 +546,9 @@ st_button_set_checked (StButton *button,
|
|||||||
button->priv->is_checked = checked;
|
button->priv->is_checked = checked;
|
||||||
|
|
||||||
if (checked)
|
if (checked)
|
||||||
st_widget_set_style_pseudo_class ((StWidget*) button, "checked");
|
st_widget_add_style_pseudo_class ((StWidget*) button, "checked");
|
||||||
else
|
else
|
||||||
if (button->priv->is_hover)
|
st_widget_remove_style_pseudo_class ((StWidget*) button, "checked");
|
||||||
st_widget_set_style_pseudo_class ((StWidget*) button, "hover");
|
|
||||||
else
|
|
||||||
st_widget_set_style_pseudo_class ((StWidget*) button, NULL);
|
|
||||||
}
|
}
|
||||||
|
|
||||||
g_object_notify (G_OBJECT (button), "checked");
|
g_object_notify (G_OBJECT (button), "checked");
|
||||||
|
@ -42,9 +42,15 @@ static guint st_clickable_signals [LAST_SIGNAL] = { 0 };
|
|||||||
static void
|
static void
|
||||||
sync_pseudo_class (StClickable *self)
|
sync_pseudo_class (StClickable *self)
|
||||||
{
|
{
|
||||||
st_widget_set_style_pseudo_class (ST_WIDGET (self),
|
if (self->priv->pressed || self->priv->active)
|
||||||
(self->priv->pressed || self->priv->active) ? "pressed" :
|
st_widget_add_style_pseudo_class (ST_WIDGET (self), "pressed");
|
||||||
(self->priv->hover ? "hover" : NULL));
|
else
|
||||||
|
st_widget_remove_style_pseudo_class (ST_WIDGET (self), "pressed");
|
||||||
|
|
||||||
|
if (self->priv->hover)
|
||||||
|
st_widget_add_style_pseudo_class (ST_WIDGET (self), "hover");
|
||||||
|
else
|
||||||
|
st_widget_remove_style_pseudo_class (ST_WIDGET (self), "hover");
|
||||||
}
|
}
|
||||||
|
|
||||||
static void
|
static void
|
||||||
|
@ -391,7 +391,8 @@ clutter_text_focus_in_cb (ClutterText *text,
|
|||||||
|
|
||||||
clutter_text_set_text (text, "");
|
clutter_text_set_text (text, "");
|
||||||
}
|
}
|
||||||
st_widget_set_style_pseudo_class (ST_WIDGET (actor), "focus");
|
st_widget_remove_style_pseudo_class (ST_WIDGET (actor), "indeterminate");
|
||||||
|
st_widget_add_style_pseudo_class (ST_WIDGET (actor), "focus");
|
||||||
clutter_text_set_cursor_visible (text, TRUE);
|
clutter_text_set_cursor_visible (text, TRUE);
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -401,17 +402,15 @@ clutter_text_focus_out_cb (ClutterText *text,
|
|||||||
{
|
{
|
||||||
StEntryPrivate *priv = ST_ENTRY_PRIV (actor);
|
StEntryPrivate *priv = ST_ENTRY_PRIV (actor);
|
||||||
|
|
||||||
|
st_widget_remove_style_pseudo_class (ST_WIDGET (actor), "focus");
|
||||||
|
|
||||||
/* add a hint if the entry is empty */
|
/* add a hint if the entry is empty */
|
||||||
if (priv->hint && !strcmp (clutter_text_get_text (text), ""))
|
if (priv->hint && !strcmp (clutter_text_get_text (text), ""))
|
||||||
{
|
{
|
||||||
priv->hint_visible = TRUE;
|
priv->hint_visible = TRUE;
|
||||||
|
|
||||||
clutter_text_set_text (text, priv->hint);
|
clutter_text_set_text (text, priv->hint);
|
||||||
st_widget_set_style_pseudo_class (ST_WIDGET (actor), "indeterminate");
|
st_widget_add_style_pseudo_class (ST_WIDGET (actor), "indeterminate");
|
||||||
}
|
|
||||||
else
|
|
||||||
{
|
|
||||||
st_widget_set_style_pseudo_class (ST_WIDGET (actor), NULL);
|
|
||||||
}
|
}
|
||||||
clutter_text_set_cursor_visible (text, FALSE);
|
clutter_text_set_cursor_visible (text, FALSE);
|
||||||
}
|
}
|
||||||
@ -586,7 +585,7 @@ st_entry_enter_event (ClutterActor *actor,
|
|||||||
|
|
||||||
if (priv->hint && priv->hint_visible)
|
if (priv->hint && priv->hint_visible)
|
||||||
{
|
{
|
||||||
st_widget_set_style_pseudo_class (ST_WIDGET (actor), "hover");
|
st_widget_add_style_pseudo_class (ST_WIDGET (actor), "hover");
|
||||||
}
|
}
|
||||||
|
|
||||||
return CLUTTER_ACTOR_CLASS (st_entry_parent_class)->enter_event (actor, event);
|
return CLUTTER_ACTOR_CLASS (st_entry_parent_class)->enter_event (actor, event);
|
||||||
@ -596,16 +595,7 @@ static gboolean
|
|||||||
st_entry_leave_event (ClutterActor *actor,
|
st_entry_leave_event (ClutterActor *actor,
|
||||||
ClutterCrossingEvent *event)
|
ClutterCrossingEvent *event)
|
||||||
{
|
{
|
||||||
StEntryPrivate *priv = ST_ENTRY_PRIV (actor);
|
st_widget_remove_style_pseudo_class (ST_WIDGET (actor), "hover");
|
||||||
|
|
||||||
if (priv->hint && priv->hint_visible)
|
|
||||||
{
|
|
||||||
st_widget_set_style_pseudo_class (ST_WIDGET (actor), "indeterminate");
|
|
||||||
}
|
|
||||||
else
|
|
||||||
{
|
|
||||||
st_widget_set_style_pseudo_class (ST_WIDGET (actor), "focus");
|
|
||||||
}
|
|
||||||
|
|
||||||
return CLUTTER_ACTOR_CLASS (st_entry_parent_class)->leave_event (actor, event);
|
return CLUTTER_ACTOR_CLASS (st_entry_parent_class)->leave_event (actor, event);
|
||||||
}
|
}
|
||||||
@ -782,14 +772,11 @@ st_entry_set_text (StEntry *entry,
|
|||||||
{
|
{
|
||||||
text = priv->hint;
|
text = priv->hint;
|
||||||
priv->hint_visible = TRUE;
|
priv->hint_visible = TRUE;
|
||||||
st_widget_set_style_pseudo_class (ST_WIDGET (entry), "indeterminate");
|
st_widget_add_style_pseudo_class (ST_WIDGET (entry), "indeterminate");
|
||||||
}
|
}
|
||||||
else
|
else
|
||||||
{
|
{
|
||||||
if (HAS_FOCUS (priv->entry))
|
st_widget_remove_style_pseudo_class (ST_WIDGET (entry), "indeterminate");
|
||||||
st_widget_set_style_pseudo_class (ST_WIDGET (entry), "focus");
|
|
||||||
else
|
|
||||||
st_widget_set_style_pseudo_class (ST_WIDGET (entry), NULL);
|
|
||||||
|
|
||||||
priv->hint_visible = FALSE;
|
priv->hint_visible = FALSE;
|
||||||
}
|
}
|
||||||
@ -845,7 +832,7 @@ st_entry_set_hint_text (StEntry *entry,
|
|||||||
priv->hint_visible = TRUE;
|
priv->hint_visible = TRUE;
|
||||||
|
|
||||||
clutter_text_set_text (CLUTTER_TEXT (priv->entry), priv->hint);
|
clutter_text_set_text (CLUTTER_TEXT (priv->entry), priv->hint);
|
||||||
st_widget_set_style_pseudo_class (ST_WIDGET (entry), "indeterminate");
|
st_widget_add_style_pseudo_class (ST_WIDGET (entry), "indeterminate");
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -723,7 +723,7 @@ handle_capture_event_cb (ClutterActor *trough,
|
|||||||
((ClutterButtonEvent*) event)->y);
|
((ClutterButtonEvent*) event)->y);
|
||||||
if (target != bar->priv->handle)
|
if (target != bar->priv->handle)
|
||||||
{
|
{
|
||||||
st_widget_set_style_pseudo_class ((StWidget*) bar->priv->handle, NULL);
|
st_widget_remove_style_pseudo_class ((StWidget*) bar->priv->handle, "hover");
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
|
@ -1354,34 +1354,165 @@ st_widget_get_theme (StWidget *actor)
|
|||||||
return actor->priv->theme;
|
return actor->priv->theme;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
static const gchar *
|
||||||
|
find_class_name (const gchar *class_list,
|
||||||
|
const gchar *class_name)
|
||||||
|
{
|
||||||
|
gint len = strlen (class_name);
|
||||||
|
const gchar *match;
|
||||||
|
|
||||||
|
if (!class_list)
|
||||||
|
return NULL;
|
||||||
|
|
||||||
|
for (match = strstr (class_list, class_name); match; match = strstr (match + 1, class_name))
|
||||||
|
{
|
||||||
|
if ((match == class_list || g_ascii_isspace (match[-1])) &&
|
||||||
|
(match[len] == '\0' || g_ascii_isspace (match[len])))
|
||||||
|
return match;
|
||||||
|
}
|
||||||
|
|
||||||
|
return NULL;
|
||||||
|
}
|
||||||
|
|
||||||
|
static gboolean
|
||||||
|
set_class_list (gchar **class_list,
|
||||||
|
const gchar *new_class_list)
|
||||||
|
{
|
||||||
|
if (g_strcmp0 (*class_list, new_class_list) != 0)
|
||||||
|
{
|
||||||
|
g_free (*class_list);
|
||||||
|
*class_list = g_strdup (new_class_list);
|
||||||
|
return TRUE;
|
||||||
|
}
|
||||||
|
else
|
||||||
|
return FALSE;
|
||||||
|
}
|
||||||
|
|
||||||
|
static gboolean
|
||||||
|
add_class_name (gchar **class_list,
|
||||||
|
const gchar *class_name)
|
||||||
|
{
|
||||||
|
gchar *new_class_list;
|
||||||
|
|
||||||
|
if (*class_list)
|
||||||
|
{
|
||||||
|
if (find_class_name (*class_list, class_name))
|
||||||
|
return FALSE;
|
||||||
|
|
||||||
|
new_class_list = g_strdup_printf ("%s %s", *class_list, class_name);
|
||||||
|
g_free (*class_list);
|
||||||
|
*class_list = new_class_list;
|
||||||
|
}
|
||||||
|
else
|
||||||
|
*class_list = g_strdup (class_name);
|
||||||
|
|
||||||
|
return TRUE;
|
||||||
|
}
|
||||||
|
|
||||||
|
static gboolean
|
||||||
|
remove_class_name (gchar **class_list,
|
||||||
|
const gchar *class_name)
|
||||||
|
{
|
||||||
|
const gchar *match, *end;
|
||||||
|
gchar *new_class_list;
|
||||||
|
|
||||||
|
if (!*class_list)
|
||||||
|
return FALSE;
|
||||||
|
|
||||||
|
if (strcmp (*class_list, class_name) == 0)
|
||||||
|
{
|
||||||
|
g_free (*class_list);
|
||||||
|
*class_list = NULL;
|
||||||
|
return TRUE;
|
||||||
|
}
|
||||||
|
|
||||||
|
match = find_class_name (*class_list, class_name);
|
||||||
|
if (!match)
|
||||||
|
return FALSE;
|
||||||
|
end = match + strlen (class_name);
|
||||||
|
|
||||||
|
/* Adjust either match or end to include a space as well.
|
||||||
|
* (One or the other must be possible at this point.)
|
||||||
|
*/
|
||||||
|
if (match != *class_list)
|
||||||
|
match--;
|
||||||
|
else
|
||||||
|
end++;
|
||||||
|
|
||||||
|
new_class_list = g_strdup_printf ("%.*s%s", match - *class_list,
|
||||||
|
*class_list, end);
|
||||||
|
g_free (*class_list);
|
||||||
|
*class_list = new_class_list;
|
||||||
|
|
||||||
|
return TRUE;
|
||||||
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* st_widget_set_style_class_name:
|
* st_widget_set_style_class_name:
|
||||||
* @actor: a #StWidget
|
* @actor: a #StWidget
|
||||||
* @style_class: a new style class string
|
* @style_class_list: (allow-none): a new style class list string
|
||||||
*
|
*
|
||||||
* Set the style class name
|
* Set the style class name list. @style_class_list can either be
|
||||||
|
* %NULL, for no classes, or a space-separated list of style class
|
||||||
|
* names. See also st_widget_add_style_class_name() and
|
||||||
|
* st_widget_remove_style_class_name().
|
||||||
*/
|
*/
|
||||||
void
|
void
|
||||||
st_widget_set_style_class_name (StWidget *actor,
|
st_widget_set_style_class_name (StWidget *actor,
|
||||||
const gchar *style_class)
|
const gchar *style_class_list)
|
||||||
{
|
{
|
||||||
StWidgetPrivate *priv = actor->priv;
|
|
||||||
|
|
||||||
g_return_if_fail (ST_IS_WIDGET (actor));
|
g_return_if_fail (ST_IS_WIDGET (actor));
|
||||||
|
|
||||||
priv = actor->priv;
|
if (set_class_list (&actor->priv->style_class, style_class_list))
|
||||||
|
|
||||||
if (g_strcmp0 (style_class, priv->style_class))
|
|
||||||
{
|
{
|
||||||
g_free (priv->style_class);
|
|
||||||
priv->style_class = g_strdup (style_class);
|
|
||||||
|
|
||||||
st_widget_style_changed (actor);
|
st_widget_style_changed (actor);
|
||||||
|
|
||||||
g_object_notify (G_OBJECT (actor), "style-class");
|
g_object_notify (G_OBJECT (actor), "style-class");
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* st_widget_add_style_class_name:
|
||||||
|
* @actor: a #StWidget
|
||||||
|
* @style_class: a style class name string
|
||||||
|
*
|
||||||
|
* Adds @style_class to @actor's style class name list, if it is not
|
||||||
|
* already present.
|
||||||
|
*/
|
||||||
|
void
|
||||||
|
st_widget_add_style_class_name (StWidget *actor,
|
||||||
|
const gchar *style_class)
|
||||||
|
{
|
||||||
|
g_return_if_fail (ST_IS_WIDGET (actor));
|
||||||
|
g_return_if_fail (style_class != NULL);
|
||||||
|
|
||||||
|
if (add_class_name (&actor->priv->style_class, style_class))
|
||||||
|
{
|
||||||
|
st_widget_style_changed (actor);
|
||||||
|
g_object_notify (G_OBJECT (actor), "style-class");
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* st_widget_remove_style_class_name:
|
||||||
|
* @actor: a #StWidget
|
||||||
|
* @style_class: a style class name string
|
||||||
|
*
|
||||||
|
* Removes @style_class from @actor's style class name, if it is
|
||||||
|
* present.
|
||||||
|
*/
|
||||||
|
void
|
||||||
|
st_widget_remove_style_class_name (StWidget *actor,
|
||||||
|
const gchar *style_class)
|
||||||
|
{
|
||||||
|
g_return_if_fail (ST_IS_WIDGET (actor));
|
||||||
|
g_return_if_fail (style_class != NULL);
|
||||||
|
|
||||||
|
if (remove_class_name (&actor->priv->style_class, style_class))
|
||||||
|
{
|
||||||
|
st_widget_style_changed (actor);
|
||||||
|
g_object_notify (G_OBJECT (actor), "style-class");
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* st_widget_get_style_class_name:
|
* st_widget_get_style_class_name:
|
||||||
@ -1400,14 +1531,37 @@ st_widget_get_style_class_name (StWidget *actor)
|
|||||||
return actor->priv->style_class;
|
return actor->priv->style_class;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* st_widget_has_style_class_name:
|
||||||
|
* @actor: a #StWidget
|
||||||
|
* @style_class: a style class string
|
||||||
|
*
|
||||||
|
* Tests if @actor's style class list includes @style_class.
|
||||||
|
*
|
||||||
|
* Returns: whether or not @actor's style class list includes
|
||||||
|
* @style_class.
|
||||||
|
*/
|
||||||
|
gboolean
|
||||||
|
st_widget_has_style_class_name (StWidget *actor,
|
||||||
|
const gchar *style_class)
|
||||||
|
{
|
||||||
|
g_return_val_if_fail (ST_IS_WIDGET (actor), FALSE);
|
||||||
|
|
||||||
|
return find_class_name (actor->priv->style_class, style_class) != NULL;
|
||||||
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* st_widget_get_style_pseudo_class:
|
* st_widget_get_style_pseudo_class:
|
||||||
* @actor: a #StWidget
|
* @actor: a #StWidget
|
||||||
*
|
*
|
||||||
* Get the current style pseudo class
|
* Get the current style pseudo class list.
|
||||||
*
|
*
|
||||||
* Returns: the pseudo class string. The string is owned by the #StWidget and
|
* Note that an actor can have multiple pseudo classes; if you just
|
||||||
* should not be modified or freed.
|
* want to test for the presence of a specific pseudo class, use
|
||||||
|
* st_widget_has_style_pseudo_class().
|
||||||
|
*
|
||||||
|
* Returns: the pseudo class list string. The string is owned by the
|
||||||
|
* #StWidget and should not be modified or freed.
|
||||||
*/
|
*/
|
||||||
const gchar*
|
const gchar*
|
||||||
st_widget_get_style_pseudo_class (StWidget *actor)
|
st_widget_get_style_pseudo_class (StWidget *actor)
|
||||||
@ -1417,30 +1571,87 @@ st_widget_get_style_pseudo_class (StWidget *actor)
|
|||||||
return actor->priv->pseudo_class;
|
return actor->priv->pseudo_class;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* st_widget_has_style_pseudo_class:
|
||||||
|
* @actor: a #StWidget
|
||||||
|
* @pseudo_class: a pseudo class string
|
||||||
|
*
|
||||||
|
* Tests if @actor's pseudo class list includes @pseudo_class.
|
||||||
|
*
|
||||||
|
* Returns: whether or not @actor's pseudo class list includes
|
||||||
|
* @pseudo_class.
|
||||||
|
*/
|
||||||
|
gboolean
|
||||||
|
st_widget_has_style_pseudo_class (StWidget *actor,
|
||||||
|
const gchar *pseudo_class)
|
||||||
|
{
|
||||||
|
g_return_val_if_fail (ST_IS_WIDGET (actor), FALSE);
|
||||||
|
|
||||||
|
return find_class_name (actor->priv->pseudo_class, pseudo_class) != NULL;
|
||||||
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* st_widget_set_style_pseudo_class:
|
* st_widget_set_style_pseudo_class:
|
||||||
* @actor: a #StWidget
|
* @actor: a #StWidget
|
||||||
* @pseudo_class: (allow-none): a new pseudo class string
|
* @pseudo_class_list: (allow-none): a new pseudo class list string
|
||||||
*
|
*
|
||||||
* Set the style pseudo class
|
* Set the style pseudo class list. @pseudo_class_list can either be
|
||||||
|
* %NULL, for no classes, or a space-separated list of pseudo class
|
||||||
|
* names. See also st_widget_add_style_pseudo_class() and
|
||||||
|
* st_widget_remove_style_pseudo_class().
|
||||||
*/
|
*/
|
||||||
void
|
void
|
||||||
st_widget_set_style_pseudo_class (StWidget *actor,
|
st_widget_set_style_pseudo_class (StWidget *actor,
|
||||||
const gchar *pseudo_class)
|
const gchar *pseudo_class_list)
|
||||||
{
|
{
|
||||||
StWidgetPrivate *priv;
|
|
||||||
|
|
||||||
g_return_if_fail (ST_IS_WIDGET (actor));
|
g_return_if_fail (ST_IS_WIDGET (actor));
|
||||||
|
|
||||||
priv = actor->priv;
|
if (set_class_list (&actor->priv->pseudo_class, pseudo_class_list))
|
||||||
|
|
||||||
if (g_strcmp0 (pseudo_class, priv->pseudo_class))
|
|
||||||
{
|
{
|
||||||
g_free (priv->pseudo_class);
|
|
||||||
priv->pseudo_class = g_strdup (pseudo_class);
|
|
||||||
|
|
||||||
st_widget_style_changed (actor);
|
st_widget_style_changed (actor);
|
||||||
|
g_object_notify (G_OBJECT (actor), "pseudo-class");
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* st_widget_add_style_pseudo_class:
|
||||||
|
* @actor: a #StWidget
|
||||||
|
* @pseudo_class: a pseudo class string
|
||||||
|
*
|
||||||
|
* Adds @pseudo_class to @actor's pseudo class list, if it is not
|
||||||
|
* already present.
|
||||||
|
*/
|
||||||
|
void
|
||||||
|
st_widget_add_style_pseudo_class (StWidget *actor,
|
||||||
|
const gchar *pseudo_class)
|
||||||
|
{
|
||||||
|
g_return_if_fail (ST_IS_WIDGET (actor));
|
||||||
|
g_return_if_fail (pseudo_class != NULL);
|
||||||
|
|
||||||
|
if (add_class_name (&actor->priv->pseudo_class, pseudo_class))
|
||||||
|
{
|
||||||
|
st_widget_style_changed (actor);
|
||||||
|
g_object_notify (G_OBJECT (actor), "pseudo-class");
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* st_widget_remove_style_pseudo_class:
|
||||||
|
* @actor: a #StWidget
|
||||||
|
* @pseudo_class: a pseudo class string
|
||||||
|
*
|
||||||
|
* Removes @pseudo_class from @actor's pseudo class, if it is present.
|
||||||
|
*/
|
||||||
|
void
|
||||||
|
st_widget_remove_style_pseudo_class (StWidget *actor,
|
||||||
|
const gchar *pseudo_class)
|
||||||
|
{
|
||||||
|
g_return_if_fail (ST_IS_WIDGET (actor));
|
||||||
|
g_return_if_fail (pseudo_class != NULL);
|
||||||
|
|
||||||
|
if (remove_class_name (&actor->priv->pseudo_class, pseudo_class))
|
||||||
|
{
|
||||||
|
st_widget_style_changed (actor);
|
||||||
g_object_notify (G_OBJECT (actor), "pseudo-class");
|
g_object_notify (G_OBJECT (actor), "pseudo-class");
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@ -84,11 +84,25 @@ struct _StWidgetClass
|
|||||||
GType st_widget_get_type (void) G_GNUC_CONST;
|
GType st_widget_get_type (void) G_GNUC_CONST;
|
||||||
|
|
||||||
void st_widget_set_style_pseudo_class (StWidget *actor,
|
void st_widget_set_style_pseudo_class (StWidget *actor,
|
||||||
|
const gchar *pseudo_class_list);
|
||||||
|
void st_widget_add_style_pseudo_class (StWidget *actor,
|
||||||
|
const gchar *pseudo_class);
|
||||||
|
void st_widget_remove_style_pseudo_class (StWidget *actor,
|
||||||
const gchar *pseudo_class);
|
const gchar *pseudo_class);
|
||||||
G_CONST_RETURN gchar *st_widget_get_style_pseudo_class (StWidget *actor);
|
G_CONST_RETURN gchar *st_widget_get_style_pseudo_class (StWidget *actor);
|
||||||
|
gboolean st_widget_has_style_pseudo_class (StWidget *actor,
|
||||||
|
const gchar *pseudo_class);
|
||||||
|
|
||||||
void st_widget_set_style_class_name (StWidget *actor,
|
void st_widget_set_style_class_name (StWidget *actor,
|
||||||
|
const gchar *style_class_list);
|
||||||
|
void st_widget_add_style_class_name (StWidget *actor,
|
||||||
|
const gchar *style_class);
|
||||||
|
void st_widget_remove_style_class_name (StWidget *actor,
|
||||||
const gchar *style_class);
|
const gchar *style_class);
|
||||||
G_CONST_RETURN gchar *st_widget_get_style_class_name (StWidget *actor);
|
G_CONST_RETURN gchar *st_widget_get_style_class_name (StWidget *actor);
|
||||||
|
gboolean st_widget_has_style_class_name (StWidget *actor,
|
||||||
|
const gchar *style_class);
|
||||||
|
|
||||||
void st_widget_set_style (StWidget *actor,
|
void st_widget_set_style (StWidget *actor,
|
||||||
const gchar *style);
|
const gchar *style);
|
||||||
G_CONST_RETURN gchar *st_widget_get_style (StWidget *actor);
|
G_CONST_RETURN gchar *st_widget_get_style (StWidget *actor);
|
||||||
|
@ -3,9 +3,11 @@
|
|||||||
#include <clutter/clutter.h>
|
#include <clutter/clutter.h>
|
||||||
#include "st-theme.h"
|
#include "st-theme.h"
|
||||||
#include "st-theme-context.h"
|
#include "st-theme-context.h"
|
||||||
|
#include "st-label.h"
|
||||||
#include <math.h>
|
#include <math.h>
|
||||||
#include <string.h>
|
#include <string.h>
|
||||||
|
|
||||||
|
static ClutterActor *stage;
|
||||||
static StThemeNode *root;
|
static StThemeNode *root;
|
||||||
static StThemeNode *group1;
|
static StThemeNode *group1;
|
||||||
static StThemeNode *text1;
|
static StThemeNode *text1;
|
||||||
@ -322,12 +324,72 @@ test_font (void)
|
|||||||
static void
|
static void
|
||||||
test_pseudo_class (void)
|
test_pseudo_class (void)
|
||||||
{
|
{
|
||||||
|
StWidget *label;
|
||||||
|
StThemeNode *labelNode;
|
||||||
|
|
||||||
test = "pseudo_class";
|
test = "pseudo_class";
|
||||||
/* text4 has :visited and :hover pseudo-classes, so should pick up both of these */
|
/* text4 has :visited and :hover pseudo-classes, so should pick up both of these */
|
||||||
assert_foreground_color (text4, "text4", 0x888888ff);
|
assert_foreground_color (text4, "text4", 0x888888ff);
|
||||||
assert_text_decoration (text4, "text4", ST_TEXT_DECORATION_UNDERLINE);
|
assert_text_decoration (text4, "text4", ST_TEXT_DECORATION_UNDERLINE);
|
||||||
/* :hover pseudo-class matches, but class doesn't match */
|
/* :hover pseudo-class matches, but class doesn't match */
|
||||||
assert_text_decoration (group3, "group3", 0);
|
assert_text_decoration (group3, "group3", 0);
|
||||||
|
|
||||||
|
/* Test the StWidget add/remove pseudo_class interfaces */
|
||||||
|
label = st_label_new ("foo");
|
||||||
|
clutter_container_add_actor (CLUTTER_CONTAINER (stage), CLUTTER_ACTOR (label));
|
||||||
|
|
||||||
|
labelNode = st_widget_get_theme_node (label);
|
||||||
|
assert_foreground_color (labelNode, "label", 0x000000ff);
|
||||||
|
assert_text_decoration (labelNode, "label", 0);
|
||||||
|
assert_length ("label", "border-width", 0.,
|
||||||
|
st_theme_node_get_border_width (labelNode, ST_SIDE_TOP));
|
||||||
|
|
||||||
|
st_widget_add_style_pseudo_class (label, "visited");
|
||||||
|
g_assert (st_widget_has_style_pseudo_class (label, "visited"));
|
||||||
|
labelNode = st_widget_get_theme_node (label);
|
||||||
|
assert_foreground_color (labelNode, "label", 0x888888ff);
|
||||||
|
assert_text_decoration (labelNode, "label", 0);
|
||||||
|
assert_length ("label", "border-width", 0.,
|
||||||
|
st_theme_node_get_border_width (labelNode, ST_SIDE_TOP));
|
||||||
|
|
||||||
|
st_widget_add_style_pseudo_class (label, "hover");
|
||||||
|
g_assert (st_widget_has_style_pseudo_class (label, "hover"));
|
||||||
|
labelNode = st_widget_get_theme_node (label);
|
||||||
|
assert_foreground_color (labelNode, "label", 0x888888ff);
|
||||||
|
assert_text_decoration (labelNode, "label", ST_TEXT_DECORATION_UNDERLINE);
|
||||||
|
assert_length ("label", "border-width", 0.,
|
||||||
|
st_theme_node_get_border_width (labelNode, ST_SIDE_TOP));
|
||||||
|
|
||||||
|
st_widget_remove_style_pseudo_class (label, "visited");
|
||||||
|
g_assert (!st_widget_has_style_pseudo_class (label, "visited"));
|
||||||
|
g_assert (st_widget_has_style_pseudo_class (label, "hover"));
|
||||||
|
labelNode = st_widget_get_theme_node (label);
|
||||||
|
assert_foreground_color (labelNode, "label", 0x000000ff);
|
||||||
|
assert_text_decoration (labelNode, "label", ST_TEXT_DECORATION_UNDERLINE);
|
||||||
|
assert_length ("label", "border-width", 0.,
|
||||||
|
st_theme_node_get_border_width (labelNode, ST_SIDE_TOP));
|
||||||
|
|
||||||
|
st_widget_add_style_pseudo_class (label, "boxed");
|
||||||
|
labelNode = st_widget_get_theme_node (label);
|
||||||
|
assert_foreground_color (labelNode, "label", 0x000000ff);
|
||||||
|
assert_text_decoration (labelNode, "label", ST_TEXT_DECORATION_UNDERLINE);
|
||||||
|
assert_length ("label", "border-width", 1.,
|
||||||
|
st_theme_node_get_border_width (labelNode, ST_SIDE_TOP));
|
||||||
|
|
||||||
|
st_widget_remove_style_pseudo_class (label, "hover");
|
||||||
|
labelNode = st_widget_get_theme_node (label);
|
||||||
|
assert_foreground_color (labelNode, "label", 0x000000ff);
|
||||||
|
assert_text_decoration (labelNode, "label", 0);
|
||||||
|
assert_length ("label", "border-width", 1.,
|
||||||
|
st_theme_node_get_border_width (labelNode, ST_SIDE_TOP));
|
||||||
|
|
||||||
|
st_widget_remove_style_pseudo_class (label, "boxed");
|
||||||
|
g_assert (st_widget_get_style_pseudo_class (label) == NULL);
|
||||||
|
labelNode = st_widget_get_theme_node (label);
|
||||||
|
assert_foreground_color (labelNode, "label", 0x000000ff);
|
||||||
|
assert_text_decoration (labelNode, "label", 0);
|
||||||
|
assert_length ("label", "border-width", 0.,
|
||||||
|
st_theme_node_get_border_width (labelNode, ST_SIDE_TOP));
|
||||||
}
|
}
|
||||||
|
|
||||||
static void
|
static void
|
||||||
@ -351,7 +413,8 @@ main (int argc, char **argv)
|
|||||||
theme = st_theme_new ("st/test-theme.css",
|
theme = st_theme_new ("st/test-theme.css",
|
||||||
NULL, NULL);
|
NULL, NULL);
|
||||||
|
|
||||||
context = st_theme_context_new ();
|
stage = clutter_stage_get_default ();
|
||||||
|
context = st_theme_context_get_for_stage (CLUTTER_STAGE (stage));
|
||||||
st_theme_context_set_theme (context, theme);
|
st_theme_context_set_theme (context, theme);
|
||||||
st_theme_context_set_resolution (context, 96.);
|
st_theme_context_set_resolution (context, 96.);
|
||||||
st_theme_context_set_font (context,
|
st_theme_context_set_font (context,
|
||||||
|
@ -64,10 +64,14 @@ stage > #text2 {
|
|||||||
border-radius: 10px 10px 0px 0px;
|
border-radius: 10px 10px 0px 0px;
|
||||||
}
|
}
|
||||||
|
|
||||||
ClutterText:hover {
|
ClutterText:hover, StLabel:hover {
|
||||||
text-decoration: underline;
|
text-decoration: underline;
|
||||||
}
|
}
|
||||||
|
|
||||||
ClutterText:visited {
|
ClutterText:visited, StLabel:visited {
|
||||||
color: #888888;
|
color: #888888;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
StLabel:boxed {
|
||||||
|
border: 1px;
|
||||||
|
}
|
||||||
|
Loading…
Reference in New Issue
Block a user