diff --git a/configure.ac b/configure.ac index ad6b87a2a..30b26a3f7 100644 --- a/configure.ac +++ b/configure.ac @@ -57,7 +57,7 @@ PKG_CHECK_MODULES(MUTTER_PLUGIN, gio-unix-2.0 gtk+-2.0 dbus-glib-1 mutter-plugin gnome-desktop-2.0 >= 2.26 libstartup-notification-1.0 gobject-introspection-1.0 >= 0.6.5) PKG_CHECK_MODULES(TIDY, clutter-1.0) -PKG_CHECK_MODULES(NBTK, clutter-1.0 gtk+-2.0 libccss-1 >= 0.3.1 clutter-imcontext-0.1) +PKG_CHECK_MODULES(NBTK, clutter-1.0 gtk+-2.0 clutter-imcontext-0.1) PKG_CHECK_MODULES(BIG, clutter-1.0 gtk+-2.0 librsvg-2.0) PKG_CHECK_MODULES(GDMUSER, dbus-glib-1 gtk+-2.0) PKG_CHECK_MODULES(TOOLKIT, clutter-1.0 libcroco-0.6) diff --git a/data/theme/gnome-shell.css b/data/theme/gnome-shell.css index 5c8f52340..d89d6f573 100644 --- a/data/theme/gnome-shell.css +++ b/data/theme/gnome-shell.css @@ -25,38 +25,38 @@ NbtkScrollBar NbtkScrollView { - scrollbar-width: 16; - scrollbar-height: 16; + scrollbar-width: 16px; + scrollbar-height: 16px; } NbtkButton#up-stepper { - border-image: url("file://scroll-button-up.png") 5; + -shell-background-image: url("scroll-button-up.png") 5px; } NbtkButton#up-stepper:hover, NbtkButton#up-stepper:active { - border-image: url("file://scroll-button-up-hover.png") 5; + -shell-background-image: url("scroll-button-up-hover.png") 5px; } NbtkButton#down-stepper { - border-image: url("file://scroll-button-down.png") 5; + -shell-background-image: url("scroll-button-down.png") 5px; } NbtkButton#down-stepper:hover, NbtkButton#down-stepper:active { - border-image: url("file://scroll-button-down-hover.png") 5; + -shell-background-image: url("scroll-button-down-hover.png") 5px; } NbtkScrollBar NbtkButton#vhandle { - border-image: url("file://scroll-vhandle.png") 5; + -shell-background-image: url("scroll-vhandle.png") 5px; } NbtkScrollBar NbtkButton#vhandle:hover { - border-image: url("file://scroll-vhandle.png") 5; + -shell-background-image: url("scroll-vhandle.png") 5px; } diff --git a/js/ui/main.js b/js/ui/main.js index 56dfeff4c..c39e3c325 100644 --- a/js/ui/main.js +++ b/js/ui/main.js @@ -67,9 +67,10 @@ function start() { for (let i = 0; i < children.length; i++) children[i].destroy(); - let style = Nbtk.Style.get_default(); + let themeContext = Shell.ThemeContext.get_for_stage (global.stage); let stylesheetPath = global.datadir + "/theme/gnome-shell.css"; - style.load_from_file(stylesheetPath); + let theme = new Shell.Theme ({ application_stylesheet: stylesheetPath }); + themeContext.set_theme (theme); global.connect('panel-run-dialog', function(panel) { // Make sure not more than one run dialog is shown. diff --git a/src/Makefile-nbtk.am b/src/Makefile-nbtk.am index b690cf75b..685473d8d 100644 --- a/src/Makefile-nbtk.am +++ b/src/Makefile-nbtk.am @@ -76,8 +76,6 @@ nbtk_source_h = \ nbtk/nbtk-scrollable.h \ nbtk/nbtk-scroll-bar.h \ nbtk/nbtk-scroll-view.h \ - nbtk/nbtk-stylable.h \ - nbtk/nbtk-style.h \ nbtk/nbtk-subtexture.h \ nbtk/nbtk-texture-cache.h \ nbtk/nbtk-texture-frame.h \ @@ -101,8 +99,6 @@ nbtk_source_c = \ nbtk/nbtk-scrollable.c \ nbtk/nbtk-scroll-bar.c \ nbtk/nbtk-scroll-view.c \ - nbtk/nbtk-stylable.c \ - nbtk/nbtk-style.c \ nbtk/nbtk-subtexture.c \ nbtk/nbtk-texture-cache.c \ nbtk/nbtk-texture-frame.c \ diff --git a/src/Makefile.am b/src/Makefile.am index dfa827c5d..6ec7d4d38 100644 --- a/src/Makefile.am +++ b/src/Makefile.am @@ -212,12 +212,35 @@ Big-1.0.typelib: libbig-1.0.la Big-1.0.gir $(AM_V_GEN) $(G_IR_COMPILER) Big-1.0.gir -o $@ CLEANFILES += Big-1.0.typelib +toolkit_gir_sources = \ + $(filter-out $(non_gir_toolkit_sources), $(toolkit_sources)) + +# Since the Shell namepace includes both the code in toolkit/ that our fork of +# NBTK depends upon and the code in this directory that depends on NBTK, We have a +# circular dependency when generating the girs and typelibs. We work around this +# by generating a Toolkit gir, using it to build the Nbtk gir then sed'ing the +# reference out of the generated gir. +Toolkit-0.1.gir: $(mutter) $(G_IR_SCANNER) libgnome-shell.la libshell-toolkit.la Makefile + $(AM_V_GEN) $(G_IR_SCANNER) \ + --namespace=Shell \ + --nsversion=0.1 \ + --include=Clutter-1.0 \ + --libtool="$(LIBTOOL)" \ + --program=mutter \ + --program-arg=--mutter-plugins=$$(pwd)/libgnome-shell.la \ + $(addprefix $(srcdir)/,$(toolkit_gir_sources)) \ + $(TOOLKIT_CFLAGS) \ + -o $@ +CLEANFILES += Toolkit-1.0.gir + Nbtk-1.0.gir: $(mutter) $(G_IR_SCANNER) Toolkit-0.1.gir libgnome-shell.la libnbtk-1.0.la Makefile $(AM_V_GEN) $(G_IR_SCANNER) \ --namespace=Nbtk \ --nsversion=1.0 \ --include=Clutter-1.0 \ + --include=Gtk-2.0 \ --add-include-path=$(builddir) \ + --include=Toolkit-0.1 \ --libtool="$(LIBTOOL)" \ --program=mutter \ --program-arg=--mutter-plugins=$$(pwd)/libgnome-shell.la \ @@ -226,11 +249,14 @@ Nbtk-1.0.gir: $(mutter) $(G_IR_SCANNER) Toolkit-0.1.gir libgnome-shell.la libnbt $(addprefix $(srcdir)/,$(nbtk_source_c)) \ $(srcdir)/nbtk-enum-types.h \ $(NBTK_CFLAGS) \ - -o $@ + -o $@.tmp && \ + sed -e '/"Toolkit"/d' < $@.tmp > $@ CLEANFILES += Nbtk-1.0.gir Nbtk-1.0.typelib: Nbtk-1.0.gir $(AM_V_GEN) $(G_IR_COMPILER) \ + --includedir=. \ + --includedir=$(MUTTER_LIB_DIR)/mutter/ \ $< -o $@ CLEANFILES += Nbtk-1.0.typelib diff --git a/src/nbtk/nbtk-bin.c b/src/nbtk/nbtk-bin.c index 03ad68cad..c0bde1c1d 100644 --- a/src/nbtk/nbtk-bin.c +++ b/src/nbtk/nbtk-bin.c @@ -39,7 +39,6 @@ #include "nbtk-bin.h" #include "nbtk-enum-types.h" #include "nbtk-private.h" -#include "nbtk-stylable.h" #define NBTK_BIN_GET_PRIVATE(obj) (G_TYPE_INSTANCE_GET_PRIVATE ((obj), NBTK_TYPE_BIN, NbtkBinPrivate)) diff --git a/src/nbtk/nbtk-button.c b/src/nbtk/nbtk-button.c index 558852dfd..812377ddc 100644 --- a/src/nbtk/nbtk-button.c +++ b/src/nbtk/nbtk-button.c @@ -1,8 +1,6 @@ -/* - * nbtk-button.c: Plain button actor - * +/*-button.c: Plain button actor * Copyright 2007 OpenedHand - * Copyright 2008, 2009 Intel Corporation. + * Copyright , 2009 Intel Corporation. * * This program is free software; you can redistribute it and/or modify it * under the terms and conditions of the GNU Lesser General Public License, @@ -34,6 +32,7 @@ #include "config.h" #endif +#include #include #include @@ -44,8 +43,6 @@ #include "nbtk-button.h" #include "nbtk-marshal.h" -#include "nbtk-stylable.h" -#include "nbtk-style.h" #include "nbtk-texture-frame.h" #include "nbtk-texture-cache.h" #include "nbtk-private.h" @@ -93,51 +90,16 @@ struct _NbtkButtonPrivate static guint button_signals[LAST_SIGNAL] = { 0, }; -static void nbtk_stylable_iface_init (NbtkStylableIface *iface); - -G_DEFINE_TYPE_WITH_CODE (NbtkButton, nbtk_button, NBTK_TYPE_BIN, - G_IMPLEMENT_INTERFACE (NBTK_TYPE_STYLABLE, - nbtk_stylable_iface_init)); - -static void -nbtk_stylable_iface_init (NbtkStylableIface *iface) -{ - static gboolean is_initialized = FALSE; - - if (G_UNLIKELY (!is_initialized)) - { - ClutterColor bg_color = { 0xcc, 0xcc, 0xcc, 0x00 }; - GParamSpec *pspec; - - is_initialized = TRUE; - - pspec = g_param_spec_int ("border-spacing", - "Border Spacing", - "Spacing between internal elements", - 0, G_MAXINT, 6, - G_PARAM_READWRITE); - nbtk_stylable_iface_install_property (iface, NBTK_TYPE_BUTTON, pspec); - - - is_initialized = TRUE; - - pspec = clutter_param_spec_color ("background-color", - "Background Color", - "The background color of an actor", - &bg_color, - G_PARAM_READWRITE); - nbtk_stylable_iface_install_property (iface, NBTK_TYPE_BUTTON, pspec); - } -} +G_DEFINE_TYPE (NbtkButton, nbtk_button, NBTK_TYPE_BIN); static void nbtk_button_update_label_style (NbtkButton *button) { - ClutterColor *real_color = NULL; - gchar *font_string = NULL; - gchar *font_name = NULL; - gint font_size = 0; ClutterActor *label; + ShellThemeNode *theme_node; + ClutterColor color; + const PangoFontDescription *font; + gchar *font_string = NULL; label = nbtk_bin_get_child ((NbtkBin*) button); @@ -145,37 +107,15 @@ nbtk_button_update_label_style (NbtkButton *button) if (!CLUTTER_IS_TEXT (label)) return; - nbtk_stylable_get (NBTK_STYLABLE (button), - "color", &real_color, - "font-family", &font_name, - "font-size", &font_size, - NULL); + theme_node = nbtk_widget_get_theme_node (NBTK_WIDGET (button)); - if (font_name || font_size) - { - if (font_name && font_size) - font_string = g_strdup_printf ("%s %dpx", font_name, font_size); - else - { - if (font_size) - font_string = g_strdup_printf ("%dpx", font_size); - else - font_string = font_name; - } + shell_theme_node_get_foreground_color (theme_node, &color); + clutter_text_set_color (CLUTTER_TEXT (label), &color); - clutter_text_set_font_name (CLUTTER_TEXT (label), font_string); - - if (font_string != font_name) - g_free (font_string); - } - - g_free (font_name); - - if (real_color) - { - clutter_text_set_color (CLUTTER_TEXT (label), real_color); - clutter_color_free (real_color); - } + font = shell_theme_node_get_font (theme_node); + font_string = pango_font_description_to_string (font); + clutter_text_set_font_name (CLUTTER_TEXT (label), font_string); + g_free (font_string); } static void @@ -195,19 +135,6 @@ nbtk_button_dispose_old_bg (NbtkButton *button) } } -static void -nbtk_button_stylable_changed (NbtkStylable *stylable) -{ - NbtkButton *button = NBTK_BUTTON (stylable); - ClutterActor *bg_image; - - nbtk_button_dispose_old_bg (button); - - bg_image = nbtk_widget_get_border_image ((NbtkWidget*) button); - if (bg_image) - button->priv->old_bg = g_object_ref (bg_image); -} - static void nbtk_animation_completed (ClutterAnimation *animation, NbtkButton *button) @@ -221,11 +148,21 @@ nbtk_button_style_changed (NbtkWidget *widget) NbtkButton *button = NBTK_BUTTON (widget); NbtkButtonPrivate *priv = button->priv; NbtkButtonClass *button_class = NBTK_BUTTON_GET_CLASS (button); + ShellThemeNode *theme_node = nbtk_widget_get_theme_node (NBTK_WIDGET (button)); + ClutterActor *bg_image; + double spacing; - /* get the spacing value */ - nbtk_stylable_get (NBTK_STYLABLE (widget), - "border-spacing", &priv->spacing, - NULL); + nbtk_button_dispose_old_bg (button); + + bg_image = nbtk_widget_get_border_image ((NbtkWidget*) button); + if (bg_image) + button->priv->old_bg = g_object_ref (bg_image); + + NBTK_WIDGET_CLASS (nbtk_button_parent_class)->style_changed (widget); + + spacing = 6; + shell_theme_node_get_length (theme_node, "border-spacing", FALSE, &spacing); + priv->spacing = round (spacing); /* update the label styling */ nbtk_button_update_label_style (button); @@ -526,6 +463,7 @@ nbtk_button_class_init (NbtkButtonClass *klass) actor_class->unmap = nbtk_button_unmap; widget_class->draw_background = nbtk_button_draw_background; + widget_class->style_changed = nbtk_button_style_changed; pspec = g_param_spec_string ("label", "Label", @@ -579,12 +517,6 @@ nbtk_button_init (NbtkButton *button) button->priv->spacing = 6; clutter_actor_set_reactive ((ClutterActor *) button, TRUE); - - g_signal_connect (button, "style-changed", - G_CALLBACK (nbtk_button_style_changed), NULL); - - g_signal_connect (button, "stylable-changed", - G_CALLBACK (nbtk_button_stylable_changed), NULL); } /** @@ -672,7 +604,8 @@ nbtk_button_set_label (NbtkButton *button, nbtk_bin_set_child ((NbtkBin*) button, label); } - nbtk_stylable_changed ((NbtkStylable*) button); + /* Fake a style change so that we reset the style properties on the label */ + nbtk_widget_style_changed (NBTK_WIDGET (button)); g_object_notify (G_OBJECT (button), "label"); } diff --git a/src/nbtk/nbtk-entry.c b/src/nbtk/nbtk-entry.c index e71efaca6..286d4c143 100644 --- a/src/nbtk/nbtk-entry.c +++ b/src/nbtk/nbtk-entry.c @@ -57,7 +57,6 @@ #include "nbtk-entry.h" #include "nbtk-widget.h" -#include "nbtk-stylable.h" #include "nbtk-texture-cache.h" #include "nbtk-marshal.h" #include "nbtk-clipboard.h" @@ -100,11 +99,7 @@ struct _NbtkEntryPrivate static guint entry_signals[LAST_SIGNAL] = { 0, }; -static void nbtk_stylable_iface_init (NbtkStylableIface *iface); - -G_DEFINE_TYPE_WITH_CODE (NbtkEntry, nbtk_entry, NBTK_TYPE_WIDGET, - G_IMPLEMENT_INTERFACE (NBTK_TYPE_STYLABLE, - nbtk_stylable_iface_init)); +G_DEFINE_TYPE (NbtkEntry, nbtk_entry, NBTK_TYPE_WIDGET); static void nbtk_entry_set_property (GObject *gobject, @@ -174,91 +169,32 @@ nbtk_entry_finalize (GObject *object) priv->hint = NULL; } -static void -nbtk_stylable_iface_init (NbtkStylableIface *iface) -{ - static gboolean is_initialized = FALSE; - - if (!is_initialized) - { - GParamSpec *pspec; - static const ClutterColor default_color - = { 0x0, 0x9c, 0xcf, 0xff }; - - is_initialized = TRUE; - - pspec = clutter_param_spec_color ("caret-color", - "Caret Color", - "Color of the entry's caret", - &default_color, - G_PARAM_READWRITE); - nbtk_stylable_iface_install_property (iface, NBTK_TYPE_ENTRY, pspec); - - pspec = clutter_param_spec_color ("selection-background-color", - "Selection Background Color", - "Color of the entry's selection", - &default_color, - G_PARAM_READWRITE); - nbtk_stylable_iface_install_property (iface, NBTK_TYPE_ENTRY, pspec); - } -} - static void nbtk_entry_style_changed (NbtkWidget *self) { NbtkEntryPrivate *priv = NBTK_ENTRY_PRIV (self); - ClutterColor *color = NULL; - ClutterColor *caret_color = NULL; - ClutterColor *selection_background_color = NULL; - gchar *font_name; + ShellThemeNode *theme_node; + ClutterColor color; + const PangoFontDescription *font; gchar *font_string; - gint font_size; - nbtk_stylable_get (NBTK_STYLABLE (self), - "color", &color, - "caret-color", &caret_color, - "selection-background-color", &selection_background_color, - "font-family", &font_name, - "font-size", &font_size, - NULL); + theme_node = nbtk_widget_get_theme_node (self); - if (color) - { - clutter_text_set_color (CLUTTER_TEXT (priv->entry), color); - clutter_color_free (color); - } + shell_theme_node_get_foreground_color (theme_node, &color); + clutter_text_set_color (CLUTTER_TEXT (priv->entry), &color); - if (caret_color) - { - clutter_text_set_cursor_color (CLUTTER_TEXT (priv->entry), caret_color); - clutter_color_free (caret_color); - } + if (shell_theme_node_get_color (theme_node, "caret-color", FALSE, &color)) + clutter_text_set_cursor_color (CLUTTER_TEXT (priv->entry), &color); - if (selection_background_color) - { - clutter_text_set_selection_color (CLUTTER_TEXT (priv->entry), - selection_background_color); - clutter_color_free (selection_background_color); - } + if (shell_theme_node_get_color (theme_node, "selection-background-color", FALSE, &color)) + clutter_text_set_selection_color (CLUTTER_TEXT (priv->entry), &color); - if (font_name || font_size) - { - if (font_name && font_size) - { - font_string = g_strdup_printf ("%s %dpx", font_name, font_size); - g_free (font_name); - } - else - { - if (font_size) - font_string = g_strdup_printf ("%dpx", font_size); - else - font_string = font_name; - } + font = shell_theme_node_get_font (theme_node); + font_string = pango_font_description_to_string (font); + clutter_text_set_font_name (CLUTTER_TEXT (priv->entry), font_string); + g_free (font_string); - clutter_text_set_font_name (CLUTTER_TEXT (priv->entry), font_string); - g_free (font_string); - } + NBTK_WIDGET_CLASS (nbtk_entry_parent_class)->style_changed (self); } static void @@ -635,6 +571,7 @@ nbtk_entry_class_init (NbtkEntryClass *klass) { GObjectClass *gobject_class = G_OBJECT_CLASS (klass); ClutterActorClass *actor_class = CLUTTER_ACTOR_CLASS (klass); + NbtkWidgetClass *widget_class = NBTK_WIDGET_CLASS (klass); GParamSpec *pspec; g_type_class_add_private (klass, sizeof (NbtkEntryPrivate)); @@ -655,6 +592,8 @@ nbtk_entry_class_init (NbtkEntryClass *klass) actor_class->key_press_event = nbtk_entry_key_press_event; actor_class->key_focus_in = nbtk_entry_key_focus_in; + widget_class->style_changed = nbtk_entry_style_changed; + pspec = g_param_spec_string ("text", "Text", "Text of the entry", @@ -724,9 +663,6 @@ nbtk_entry_init (NbtkEntry *entry) /* set cursor hidden until we receive focus */ clutter_text_set_cursor_visible ((ClutterText *) priv->entry, FALSE); - - g_signal_connect (entry, "style-changed", - G_CALLBACK (nbtk_entry_style_changed), NULL); } /** diff --git a/src/nbtk/nbtk-label.c b/src/nbtk/nbtk-label.c index 1a4a63b85..a563bc377 100644 --- a/src/nbtk/nbtk-label.c +++ b/src/nbtk/nbtk-label.c @@ -44,7 +44,6 @@ #include "nbtk-label.h" #include "nbtk-widget.h" -#include "nbtk-stylable.h" enum { @@ -105,43 +104,23 @@ nbtk_label_get_property (GObject *gobject, static void nbtk_label_style_changed (NbtkWidget *self) { - NbtkLabelPrivate *priv = NBTK_LABEL (self)->priv; - ClutterColor *color = NULL; - gchar *font_name; + NbtkLabelPrivate *priv; + ShellThemeNode *theme_node; + ClutterColor color; + const PangoFontDescription *font; gchar *font_string; - gint font_size; - nbtk_stylable_get (NBTK_STYLABLE (self), - "color", &color, - "font-family", &font_name, - "font-size", &font_size, - NULL); + priv = NBTK_LABEL (self)->priv; + theme_node = nbtk_widget_get_theme_node (self); + shell_theme_node_get_foreground_color (theme_node, &color); + clutter_text_set_color (CLUTTER_TEXT (priv->label), &color); - if (color) - { - clutter_text_set_color (CLUTTER_TEXT (priv->label), color); - clutter_color_free (color); - } - - if (font_name || font_size) - { - if (font_name && font_size) - { - font_string = g_strdup_printf ("%s %dpx", font_name, font_size); - g_free (font_name); - } - else - { - if (font_size) - font_string = g_strdup_printf ("%dpx", font_size); - else - font_string = font_name; - } - - clutter_text_set_font_name (CLUTTER_TEXT (priv->label), font_string); - g_free (font_string); - } + font = shell_theme_node_get_font (theme_node); + font_string = pango_font_description_to_string (font); + clutter_text_set_font_name (CLUTTER_TEXT (priv->label), font_string); + g_free (font_string); + NBTK_WIDGET_CLASS (nbtk_label_parent_class)->style_changed (self); } static void @@ -248,6 +227,7 @@ nbtk_label_class_init (NbtkLabelClass *klass) { GObjectClass *gobject_class = G_OBJECT_CLASS (klass); ClutterActorClass *actor_class = CLUTTER_ACTOR_CLASS (klass); + NbtkWidgetClass *widget_class = NBTK_WIDGET_CLASS (klass); GParamSpec *pspec; g_type_class_add_private (klass, sizeof (NbtkLabelPrivate)); @@ -262,6 +242,8 @@ nbtk_label_class_init (NbtkLabelClass *klass) actor_class->map = nbtk_label_map; actor_class->unmap = nbtk_label_unmap; + widget_class->style_changed = nbtk_label_style_changed; + pspec = g_param_spec_string ("text", "Text", "Text of the label", @@ -282,9 +264,6 @@ nbtk_label_init (NbtkLabel *label) NULL); clutter_actor_set_parent (priv->label, CLUTTER_ACTOR (label)); - - g_signal_connect (label, "style-changed", - G_CALLBACK (nbtk_label_style_changed), NULL); } /** diff --git a/src/nbtk/nbtk-scroll-bar.c b/src/nbtk/nbtk-scroll-bar.c index 321584498..8800f0f0d 100644 --- a/src/nbtk/nbtk-scroll-bar.c +++ b/src/nbtk/nbtk-scroll-bar.c @@ -31,16 +31,11 @@ #include "nbtk-scroll-bar.h" #include "nbtk-bin.h" #include "nbtk-marshal.h" -#include "nbtk-stylable.h" #include "nbtk-enum-types.h" #include "nbtk-private.h" #include "nbtk-button.h" -static void nbtk_stylable_iface_init (NbtkStylableIface *iface); - -G_DEFINE_TYPE_WITH_CODE (NbtkScrollBar, nbtk_scroll_bar, NBTK_TYPE_BIN, - G_IMPLEMENT_INTERFACE (NBTK_TYPE_STYLABLE, - nbtk_stylable_iface_init)) +G_DEFINE_TYPE (NbtkScrollBar, nbtk_scroll_bar, NBTK_TYPE_BIN) #define NBTK_SCROLL_BAR_GET_PRIVATE(o) (G_TYPE_INSTANCE_GET_PRIVATE ((o), NBTK_TYPE_SCROLL_BAR, NbtkScrollBarPrivate)) @@ -336,10 +331,10 @@ nbtk_scroll_bar_allocate (ClutterActor *actor, if (priv->adjustment) { + ShellThemeNode *theme_node = nbtk_widget_get_theme_node (NBTK_WIDGET (actor)); gfloat handle_size, position, avail_size; - gdouble value, lower, upper, page_size, increment; + gdouble value, lower, upper, page_size, increment, min_size, max_size; ClutterActorBox handle_box = { 0, }; - guint min_size, max_size; nbtk_adjustment_get_values (priv->adjustment, &value, @@ -355,10 +350,10 @@ nbtk_scroll_bar_allocate (ClutterActor *actor, else increment = page_size / (upper - lower); - nbtk_stylable_get (NBTK_STYLABLE (actor), - "min-size", &min_size, - "max-size", &max_size, - NULL); + min_size = 32.; + shell_theme_node_get_length (theme_node, "min-size", FALSE, &min_size); + max_size = G_MAXINT16; + shell_theme_node_get_length (theme_node, "max-size", FALSE, &max_size); if (upper - lower - page_size <= 0) position = 0; @@ -407,11 +402,12 @@ nbtk_scroll_bar_style_changed (NbtkWidget *widget) { NbtkScrollBarPrivate *priv = NBTK_SCROLL_BAR (widget)->priv; - nbtk_stylable_changed ((NbtkStylable *) priv->bw_stepper); - nbtk_stylable_changed ((NbtkStylable *) priv->fw_stepper); - nbtk_stylable_changed ((NbtkStylable *) priv->trough); - nbtk_stylable_changed ((NbtkStylable *) priv->handle); + nbtk_widget_style_changed (NBTK_WIDGET (priv->bw_stepper)); + nbtk_widget_style_changed (NBTK_WIDGET (priv->fw_stepper)); + nbtk_widget_style_changed (NBTK_WIDGET (priv->trough)); + nbtk_widget_style_changed (NBTK_WIDGET (priv->handle)); + NBTK_WIDGET_CLASS (nbtk_scroll_bar_parent_class)->style_changed (widget); } static void @@ -494,6 +490,7 @@ nbtk_scroll_bar_class_init (NbtkScrollBarClass *klass) { GObjectClass *object_class = G_OBJECT_CLASS (klass); ClutterActorClass *actor_class = CLUTTER_ACTOR_CLASS (klass); + NbtkWidgetClass *widget_class = NBTK_WIDGET_CLASS (klass); GParamSpec *pspec; g_type_class_add_private (klass, sizeof (NbtkScrollBarPrivate)); @@ -510,6 +507,8 @@ nbtk_scroll_bar_class_init (NbtkScrollBarClass *klass) actor_class->map = nbtk_scroll_bar_map; actor_class->unmap = nbtk_scroll_bar_unmap; + widget_class->style_changed = nbtk_scroll_bar_style_changed; + g_object_class_install_property (object_class, PROP_ADJUSTMENT, @@ -545,35 +544,6 @@ nbtk_scroll_bar_class_init (NbtkScrollBarClass *klass) G_TYPE_NONE, 0); } -static void -nbtk_stylable_iface_init (NbtkStylableIface *iface) -{ - static gboolean is_initialized = FALSE; - - if (!is_initialized) - { - GParamSpec *pspec; - - is_initialized = TRUE; - - pspec = g_param_spec_uint ("min-size", - "Minimum grabber size", - "Minimum size of the scroll grabber, in px", - 0, G_MAXUINT, 32, - G_PARAM_READWRITE); - nbtk_stylable_iface_install_property (iface, - NBTK_TYPE_SCROLL_BAR, pspec); - - pspec = g_param_spec_uint ("max-size", - "Maximum grabber size", - "Maximum size of the scroll grabber, in px", - 0, G_MAXINT16, G_MAXINT16, - G_PARAM_READWRITE); - nbtk_stylable_iface_install_property (iface, - NBTK_TYPE_SCROLL_BAR, pspec); - } -} - static void move_slider (NbtkScrollBar *bar, gfloat x, gfloat y) { @@ -1035,8 +1005,6 @@ nbtk_scroll_bar_init (NbtkScrollBar *self) clutter_actor_set_reactive (CLUTTER_ACTOR (self), TRUE); - g_signal_connect (self, "style-changed", - G_CALLBACK (nbtk_scroll_bar_style_changed), NULL); g_signal_connect (self, "notify::reactive", G_CALLBACK (nbtk_scroll_bar_notify_reactive), NULL); } diff --git a/src/nbtk/nbtk-scroll-view.c b/src/nbtk/nbtk-scroll-view.c index 22919a847..e57e1cf02 100644 --- a/src/nbtk/nbtk-scroll-view.c +++ b/src/nbtk/nbtk-scroll-view.c @@ -26,24 +26,23 @@ #include "nbtk-marshal.h" #include "nbtk-scroll-bar.h" #include "nbtk-scrollable.h" -#include "nbtk-stylable.h" #include static void clutter_container_iface_init (ClutterContainerIface *iface); -static void nbtk_stylable_iface_init (NbtkStylableIface *iface); static ClutterContainerIface *nbtk_scroll_view_parent_iface = NULL; G_DEFINE_TYPE_WITH_CODE (NbtkScrollView, nbtk_scroll_view, NBTK_TYPE_BIN, G_IMPLEMENT_INTERFACE (CLUTTER_TYPE_CONTAINER, - clutter_container_iface_init) - G_IMPLEMENT_INTERFACE (NBTK_TYPE_STYLABLE, - nbtk_stylable_iface_init)) + clutter_container_iface_init)) #define SCROLL_VIEW_PRIVATE(o) (G_TYPE_INSTANCE_GET_PRIVATE ((o), \ NBTK_TYPE_SCROLL_VIEW, \ NbtkScrollViewPrivate)) +/* Default width (or height - the narrow dimension) for the scrollbars*/ +#define DEFAULT_SCROLLBAR_WIDTH 24 + struct _NbtkScrollViewPrivate { /* a pointer to the child; this is actually stored @@ -165,6 +164,28 @@ nbtk_scroll_view_pick (ClutterActor *actor, const ClutterColor *color) clutter_actor_paint (priv->vscroll); } +static double +get_scrollbar_width (NbtkScrollView *scroll_view) +{ + ShellThemeNode *theme_node = nbtk_widget_get_theme_node (NBTK_WIDGET (scroll_view)); + double result = DEFAULT_SCROLLBAR_WIDTH; + + shell_theme_node_get_length (theme_node, "scrollbar-width", FALSE, &result); + + return result; +} + +static double +get_scrollbar_height (NbtkScrollView *scroll_view) +{ + ShellThemeNode *theme_node = nbtk_widget_get_theme_node (NBTK_WIDGET (scroll_view)); + double result = DEFAULT_SCROLLBAR_WIDTH; + + shell_theme_node_get_length (theme_node, "scrollbar-height", FALSE, &result); + + return result; +} + static void nbtk_scroll_view_get_preferred_width (ClutterActor *actor, gfloat for_height, @@ -172,7 +193,6 @@ nbtk_scroll_view_get_preferred_width (ClutterActor *actor, gfloat *natural_width_p) { NbtkPadding padding; - guint xthickness; NbtkScrollViewPrivate *priv = NBTK_SCROLL_VIEW (actor)->priv; @@ -180,9 +200,6 @@ nbtk_scroll_view_get_preferred_width (ClutterActor *actor, return; nbtk_widget_get_padding (NBTK_WIDGET (actor), &padding); - nbtk_stylable_get (NBTK_STYLABLE (actor), - "scrollbar-width", &xthickness, - NULL); /* Our natural width is the natural width of the child */ clutter_actor_get_preferred_width (priv->child, @@ -199,7 +216,7 @@ nbtk_scroll_view_get_preferred_width (ClutterActor *actor, NULL, &natural_height); if (for_height < natural_height) - *natural_width_p += xthickness; + *natural_width_p += get_scrollbar_width (NBTK_SCROLL_VIEW (actor)); } /* Add space for padding */ @@ -217,7 +234,6 @@ nbtk_scroll_view_get_preferred_height (ClutterActor *actor, gfloat *natural_height_p) { NbtkPadding padding; - guint ythickness; NbtkScrollViewPrivate *priv = NBTK_SCROLL_VIEW (actor)->priv; @@ -225,9 +241,6 @@ nbtk_scroll_view_get_preferred_height (ClutterActor *actor, return; nbtk_widget_get_padding (NBTK_WIDGET (actor), &padding); - nbtk_stylable_get (NBTK_STYLABLE (actor), - "scrollbar-height", &ythickness, - NULL); /* Our natural height is the natural height of the child */ clutter_actor_get_preferred_height (priv->child, @@ -244,7 +257,7 @@ nbtk_scroll_view_get_preferred_height (ClutterActor *actor, NULL, &natural_width); if (for_width < natural_width) - *natural_height_p += ythickness; + *natural_height_p += get_scrollbar_height (NBTK_SCROLL_VIEW (actor)); } /* Add space for padding */ @@ -285,10 +298,8 @@ nbtk_scroll_view_allocate (ClutterActor *actor, avail_width = (box->x2 - box->x1) - padding.left - padding.right; avail_height = (box->y2 - box->y1) - padding.top - padding.bottom; - nbtk_stylable_get (NBTK_STYLABLE (actor), - "scrollbar-width", &sb_width, - "scrollbar-height", &sb_height, - NULL); + sb_width = get_scrollbar_width (NBTK_SCROLL_VIEW (actor)); + sb_height = get_scrollbar_width (NBTK_SCROLL_VIEW (actor)); if (!CLUTTER_ACTOR_IS_VISIBLE (priv->vscroll)) sb_width = 0; @@ -334,8 +345,10 @@ nbtk_scroll_view_style_changed (NbtkWidget *widget) { NbtkScrollViewPrivate *priv = NBTK_SCROLL_VIEW (widget)->priv; - nbtk_stylable_changed ((NbtkStylable *) priv->hscroll); - nbtk_stylable_changed ((NbtkStylable *) priv->vscroll); + nbtk_widget_style_changed (NBTK_WIDGET (priv->hscroll)); + nbtk_widget_style_changed (NBTK_WIDGET (priv->vscroll)); + + NBTK_WIDGET_CLASS (nbtk_scroll_view_parent_class)->style_changed (widget); } static gboolean @@ -418,6 +431,7 @@ nbtk_scroll_view_class_init (NbtkScrollViewClass *klass) GParamSpec *pspec; GObjectClass *object_class = G_OBJECT_CLASS (klass); ClutterActorClass *actor_class = CLUTTER_ACTOR_CLASS (klass); + NbtkWidgetClass *widget_class = NBTK_WIDGET_CLASS (klass); g_type_class_add_private (klass, sizeof (NbtkScrollViewPrivate)); @@ -433,6 +447,8 @@ nbtk_scroll_view_class_init (NbtkScrollViewClass *klass) actor_class->allocate = nbtk_scroll_view_allocate; actor_class->scroll_event = nbtk_scroll_view_scroll_event; + widget_class->style_changed = nbtk_scroll_view_style_changed; + g_object_class_install_property (object_class, PROP_HSCROLL, g_param_spec_object ("hscroll", @@ -460,33 +476,6 @@ nbtk_scroll_view_class_init (NbtkScrollViewClass *klass) } -static void -nbtk_stylable_iface_init (NbtkStylableIface *iface) -{ - static gboolean is_initialized = FALSE; - - if (!is_initialized) - { - GParamSpec *pspec; - - is_initialized = TRUE; - - pspec = g_param_spec_uint ("scrollbar-width", - "Vertical scroll-bar thickness", - "Thickness of vertical scrollbar, in px", - 0, G_MAXUINT, 24, - G_PARAM_READWRITE); - nbtk_stylable_iface_install_property (iface, NBTK_TYPE_SCROLL_VIEW, pspec); - - pspec = g_param_spec_uint ("scrollbar-height", - "Horizontal scroll-bar thickness", - "Thickness of horizontal scrollbar, in px", - 0, G_MAXUINT, 24, - G_PARAM_READWRITE); - nbtk_stylable_iface_install_property (iface, NBTK_TYPE_SCROLL_VIEW, pspec); - } -} - static void child_adjustment_changed_cb (NbtkAdjustment *adjustment, ClutterActor *bar) @@ -594,9 +583,6 @@ nbtk_scroll_view_init (NbtkScrollView *self) priv->mouse_scroll = TRUE; g_object_set (G_OBJECT (self), "reactive", TRUE, "clip-to-allocation", TRUE, NULL); - - g_signal_connect (self, "style-changed", - G_CALLBACK (nbtk_scroll_view_style_changed), NULL); } static void diff --git a/src/nbtk/nbtk-stylable.c b/src/nbtk/nbtk-stylable.c deleted file mode 100644 index eefdaedbb..000000000 --- a/src/nbtk/nbtk-stylable.c +++ /dev/null @@ -1,849 +0,0 @@ -/* - * nbtk-stylable.c: Interface for stylable objects - * - * Copyright 2008 Intel Corporation - * Copyright 2009 Intel Corporation. - * - * This program is free software; you can redistribute it and/or modify it - * under the terms and conditions of the GNU Lesser General Public License, - * version 2.1, as published by the Free Software Foundation. - * - * This program is distributed in the hope it will be useful, but WITHOUT ANY - * WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS - * FOR A PARTICULAR PURPOSE. See the GNU Lesser General Public License for - * more details. - * - * You should have received a copy of the GNU Lesser General Public License - * along with this program; if not, write to the Free Software Foundation, - * Inc., 51 Franklin St - Fifth Floor, Boston, MA 02110-1301 USA. - * - * Written by: Emmanuele Bassi - * Thomas Wood - * - */ - -/** - * SECTION:nbtk-stylable - * @short_description: Interface for stylable objects - * - * Stylable objects are classes that can have "style properties", that is - * properties that can be changed by attaching a #NbtkStyle to them. - * - * Objects can choose to subclass #NbtkWidget, and thus inherit all the - * #NbtkWidget style properties; or they can subclass #NbtkWidget and - * reimplement the #NbtkStylable interface to add new style properties - * specific for them (and their subclasses); or, finally, they can simply - * subclass #GObject and implement #NbtkStylable to install new properties. - */ - -#ifdef HAVE_CONFIG_H -#include "config.h" -#endif - -#include -#include - -#include -#include -#include - -#include "nbtk-marshal.h" -#include "nbtk-private.h" -#include "nbtk-stylable.h" - -enum -{ - STYLE_CHANGED, - STYLE_NOTIFY, - CHANGED, - - LAST_SIGNAL -}; - -static GObjectNotifyContext property_notify_context = { 0, }; - -static GParamSpecPool *style_property_spec_pool = NULL; - -static GQuark quark_real_owner = 0; -static GQuark quark_style = 0; - -static guint stylable_signals[LAST_SIGNAL] = { 0, }; - -static void -nbtk_stylable_notify_dispatcher (GObject *gobject, - guint n_pspecs, - GParamSpec **pspecs) -{ - guint i; - - for (i = 0; i < n_pspecs; i++) - g_signal_emit (gobject, stylable_signals[STYLE_NOTIFY], - g_quark_from_string (pspecs[i]->name), - pspecs[i]); -} - -static void -nbtk_stylable_base_finalize (gpointer g_iface) -{ - GList *list, *node; - - list = g_param_spec_pool_list_owned (style_property_spec_pool, - G_TYPE_FROM_INTERFACE (g_iface)); - - for (node = list; node; node = node->next) - { - GParamSpec *pspec = node->data; - - g_param_spec_pool_remove (style_property_spec_pool, pspec); - g_param_spec_unref (pspec); - } - - g_list_free (list); -} - -static void -nbtk_stylable_base_init (gpointer g_iface) -{ - static gboolean initialised = FALSE; - - if (G_UNLIKELY (!initialised)) - { - GType iface_type = G_TYPE_FROM_INTERFACE (g_iface); - - initialised = TRUE; - - quark_real_owner = g_quark_from_static_string ("nbtk-stylable-real-owner-quark"); - quark_style = g_quark_from_static_string ("nbtk-stylable-style-quark"); - - style_property_spec_pool = g_param_spec_pool_new (FALSE); - - property_notify_context.quark_notify_queue = g_quark_from_static_string ("NbtkStylable-style-property-notify-queue"); - property_notify_context.dispatcher = nbtk_stylable_notify_dispatcher; - - /** - * NbtkStylable:style: - * - * The #NbtkStyle attached to a stylable object. - */ - g_object_interface_install_property (g_iface, - g_param_spec_object ("style", - "Style", - "A style object", - NBTK_TYPE_STYLE, - NBTK_PARAM_READWRITE)); - - /** - * NbtkStylable::style-changed: - * @stylable: the #NbtkStylable that received the signal - * @old_style: the previously set #NbtkStyle for @stylable - * - * The ::style-changed signal is emitted each time one of the style - * properties have changed. - */ - stylable_signals[STYLE_CHANGED] = - g_signal_new (I_("style-changed"), - iface_type, - G_SIGNAL_RUN_FIRST, - G_STRUCT_OFFSET (NbtkStylableIface, style_changed), - NULL, NULL, - _nbtk_marshal_VOID__VOID, - G_TYPE_NONE, 0); - - /** - * NbtkStylable::stylable-changed: - * @actor: the actor that received the signal - * - * The ::changed signal is emitted each time any of the properties of the - * stylable has changed. - */ - stylable_signals[CHANGED] = - g_signal_new (I_("stylable-changed"), - iface_type, - G_SIGNAL_RUN_LAST, - G_STRUCT_OFFSET (NbtkStylableIface, stylable_changed), - NULL, NULL, - _nbtk_marshal_VOID__VOID, - G_TYPE_NONE, 0); - - stylable_signals[STYLE_NOTIFY] = - g_signal_new (I_("style-notify"), - iface_type, - G_SIGNAL_RUN_FIRST | G_SIGNAL_NO_RECURSE | G_SIGNAL_DETAILED | G_SIGNAL_NO_HOOKS | G_SIGNAL_ACTION, - G_STRUCT_OFFSET (NbtkStylableIface, style_notify), - NULL, NULL, - _nbtk_marshal_VOID__PARAM, - G_TYPE_NONE, 1, - G_TYPE_PARAM); - } -} - -GType -nbtk_stylable_get_type (void) -{ - static GType our_type = 0; - - if (G_UNLIKELY (our_type == 0)) - { - GTypeInfo stylable_info = { - sizeof (NbtkStylableIface), - nbtk_stylable_base_init, - nbtk_stylable_base_finalize - }; - - our_type = g_type_register_static (G_TYPE_INTERFACE, - I_("NbtkStylable"), - &stylable_info, 0); - } - - return our_type; -} - -void -nbtk_stylable_freeze_notify (NbtkStylable *stylable) -{ - g_return_if_fail (NBTK_IS_STYLABLE (stylable)); - - g_object_ref (stylable); - g_object_notify_queue_freeze (G_OBJECT (stylable), &property_notify_context); - g_object_unref (stylable); -} - -void -nbtk_stylable_thaw_notify (NbtkStylable *stylable) -{ - GObjectNotifyQueue *nqueue; - - g_return_if_fail (NBTK_IS_STYLABLE (stylable)); - - g_object_ref (stylable); - - nqueue = g_object_notify_queue_from_object (G_OBJECT (stylable), - &property_notify_context); - - if (!nqueue || !nqueue->freeze_count) - g_warning ("%s: property-changed notification for %s(%p) is not frozen", - G_STRFUNC, G_OBJECT_TYPE_NAME (stylable), stylable); - else - g_object_notify_queue_thaw (G_OBJECT (stylable), nqueue); - - g_object_unref (stylable); -} - -void -nbtk_stylable_notify (NbtkStylable *stylable, - const gchar *property_name) -{ - GParamSpec *pspec; - - g_return_if_fail (NBTK_IS_STYLABLE (stylable)); - g_return_if_fail (property_name != NULL); - - g_object_ref (stylable); - - pspec = g_param_spec_pool_lookup (style_property_spec_pool, - property_name, - G_OBJECT_TYPE (stylable), - TRUE); - - if (!pspec) - g_warning ("%s: object class `%s' has no style property named `%s'", - G_STRFUNC, - G_OBJECT_TYPE_NAME (stylable), - property_name); - else - { - GObjectNotifyQueue *nqueue; - - nqueue = g_object_notify_queue_freeze (G_OBJECT (stylable), - &property_notify_context); - g_object_notify_queue_add (G_OBJECT (stylable), nqueue, pspec); - g_object_notify_queue_thaw (G_OBJECT (stylable), nqueue); - } - - g_object_unref (stylable); -} - -/** - * nbtk_stylable_iface_install_property: - * @iface: a #NbtkStylableIface - * @owner_type: #GType of the style property owner - * @pspec: a #GParamSpec - * - * Installs a property for @owner_type using @pspec as the property - * description. - * - * This function should be used inside the #NbtkStylableIface initialization - * function of a class, for instance: - * - * - * G_DEFINE_TYPE_WITH_CODE (FooActor, foo_actor, CLUTTER_TYPE_ACTOR, - * G_IMPLEMENT_INTERFACE (NBTK_TYPE_STYLABLE, - * nbtk_stylable_init)); - * ... - * static void - * nbtk_stylable_init (NbtkStylableIface *iface) - * { - * static gboolean is_initialized = FALSE; - * - * if (!is_initialized) - * { - * ... - * nbtk_stylable_iface_install_property (stylable, - * FOO_TYPE_ACTOR, - * g_param_spec_int ("x-spacing", - * "X Spacing", - * "Horizontal spacing", - * -1, G_MAXINT, - * 2, - * G_PARAM_READWRITE)); - * ... - * } - * } - * - */ -void -nbtk_stylable_iface_install_property (NbtkStylableIface *iface, - GType owner_type, - GParamSpec *pspec) -{ - g_return_if_fail (NBTK_IS_STYLABLE_IFACE (iface)); - g_return_if_fail (owner_type != G_TYPE_INVALID); - g_return_if_fail (G_IS_PARAM_SPEC (pspec)); - g_return_if_fail (pspec->flags & G_PARAM_READABLE); - g_return_if_fail (!(pspec->flags & (G_PARAM_CONSTRUCT_ONLY | G_PARAM_CONSTRUCT -))); - - if (g_param_spec_pool_lookup (style_property_spec_pool, pspec->name, - owner_type, - FALSE)) - { - g_warning ("%s: class `%s' already contains a style property named `%s'", - G_STRLOC, - g_type_name (owner_type), - pspec->name); - return; - } - - g_param_spec_ref_sink (pspec); - g_param_spec_set_qdata_full (pspec, quark_real_owner, - g_strdup (g_type_name (owner_type)), - g_free); - - g_param_spec_pool_insert (style_property_spec_pool, - pspec, - owner_type); -} - -/** - * nbtk_stylable_list_properties: - * @stylable: a #NbtkStylable - * @n_props: (out): return location for the number of properties, or %NULL - * - * Retrieves all the #GParamSpecs installed by @stylable. - * - * Return value: (transfer container) (array length=n_props): an array - * of #GParamSpecs. Free it with g_free() when done. - */ -GParamSpec ** -nbtk_stylable_list_properties (NbtkStylable *stylable, - guint *n_props) -{ - GParamSpec **pspecs = NULL; - guint n; - - g_return_val_if_fail (NBTK_IS_STYLABLE (stylable), NULL); - - pspecs = g_param_spec_pool_list (style_property_spec_pool, - G_OBJECT_TYPE (stylable), - &n); - if (n_props) - *n_props = n; - - return pspecs; -} - -/** - * nbtk_stylable_find_property: - * @stylable: a #NbtkStylable - * @property_name: the name of the property to find - * - * Finds the #GParamSpec installed by @stylable for the property - * with @property_name. - * - * Return value: (transfer none): a #GParamSpec for the given property, - * or %NULL if no property with that name was found - */ -GParamSpec * -nbtk_stylable_find_property (NbtkStylable *stylable, - const gchar *property_name) -{ - g_return_val_if_fail (NBTK_IS_STYLABLE (stylable), NULL); - g_return_val_if_fail (property_name != NULL, NULL); - - return g_param_spec_pool_lookup (style_property_spec_pool, - property_name, - G_OBJECT_TYPE (stylable), - TRUE); -} - -static inline void -nbtk_stylable_get_property_internal (NbtkStylable *stylable, - GParamSpec *pspec, - GValue *value) -{ - NbtkStyle *style; - GValue real_value = { 0, }; - - style = nbtk_stylable_get_style (stylable); - - if (!style) - { - g_value_reset (value); - return; - } - - nbtk_style_get_property (style, stylable, pspec, &real_value); - - g_value_copy (&real_value, value); - g_value_unset (&real_value); - -} - -/** - * nbtk_stylable_get_property: - * @stylable: a #NbtkStylable - * @property_name: the name of the property - * @value: (out): return location for an empty #GValue - * - * Retrieves the value of @property_name for @stylable, and puts it - * into @value. - */ -void -nbtk_stylable_get_property (NbtkStylable *stylable, - const gchar *property_name, - GValue *value) -{ - GParamSpec *pspec; - - g_return_if_fail (NBTK_IS_STYLABLE (stylable)); - g_return_if_fail (property_name != NULL); - g_return_if_fail (value != NULL); - - pspec = nbtk_stylable_find_property (stylable, property_name); - if (!pspec) - { - g_warning ("Stylable class `%s' doesn't have a property named `%s'", - g_type_name (G_OBJECT_TYPE (stylable)), - property_name); - return; - } - - if (!(pspec->flags & G_PARAM_READABLE)) - { - g_warning ("Style property `%s' of class `%s' is not readable", - pspec->name, - g_type_name (G_OBJECT_TYPE (stylable))); - return; - } - - if (G_VALUE_TYPE (value) != G_PARAM_SPEC_VALUE_TYPE (pspec)) - { - g_warning ("Passed value is not of the requested type `%s' for " - "the style property `%s' of class `%s'", - g_type_name (G_PARAM_SPEC_VALUE_TYPE (pspec)), - pspec->name, - g_type_name (G_OBJECT_TYPE (stylable))); - return; - } - - nbtk_stylable_get_property_internal (stylable, pspec, value); -} - -/** - * nbtk_stylable_get: - * @stylable: a #NbtkStylable - * @first_property_name: name of the first property to get - * @Varargs: return location for the first property, followed optionally - * by more name/return location pairs, followed by %NULL - * - * Gets the style properties for @stylable. - * - * In general, a copy is made of the property contents and the called - * is responsible for freeing the memory in the appropriate manner for - * the property type. - * - * - * Using nbtk_stylable_get(<!-- -->) - * An example of using nbtk_stylable_get() to get the contents of - * two style properties - one of type #G_TYPE_INT and one of type - * #CLUTTER_TYPE_COLOR: - * - * gint x_spacing; - * ClutterColor *bg_color; - * - * nbtk_stylable_get (stylable, - * "x-spacing", &x_spacing, - * "bg-color", &bg_color, - * NULL); - * - * /* do something with x_spacing and bg_color */ - * - * clutter_color_free (bg_color); - * - * - */ -void -nbtk_stylable_get (NbtkStylable *stylable, - const gchar *first_property_name, - ...) -{ - NbtkStyle *style; - va_list args; - - g_return_if_fail (NBTK_IS_STYLABLE (stylable)); - g_return_if_fail (first_property_name != NULL); - - style = nbtk_stylable_get_style (stylable); - - va_start (args, first_property_name); - nbtk_style_get_valist (style, stylable, first_property_name, args); - va_end (args); -} - -/** - * nbtk_stylable_get_default_value: - * @stylable: a #NbtkStylable - * @property_name: name of the property to query - * @value_out: (out): return location for the default value - * - * Query @stylable for the default value of property @property_name and - * fill @value_out with the result. - * - * Returns: %TRUE if property @property_name exists and the default value has - * been returned. - */ -gboolean -nbtk_stylable_get_default_value (NbtkStylable *stylable, - const gchar *property_name, - GValue *value_out) -{ - GParamSpec *pspec; - - pspec = nbtk_stylable_find_property (stylable, property_name); - if (!pspec) - { - g_warning ("%s: no style property named `%s' found for class `%s'", - G_STRLOC, - property_name, - g_type_name (G_OBJECT_TYPE (stylable))); - return FALSE; - } - - if (!(pspec->flags & G_PARAM_READABLE)) - { - g_warning ("Style property `%s' of class `%s' is not readable", - pspec->name, - g_type_name (G_OBJECT_TYPE (stylable))); - return FALSE; - } - - g_value_init (value_out, G_PARAM_SPEC_VALUE_TYPE (pspec)); - g_param_value_set_default (pspec, value_out); - return TRUE; -} - -/** - * nbtk_stylable_get_style: - * @stylable: a #NbtkStylable - * - * Retrieves the #NbtkStyle used by @stylable. This function does not - * alter the reference count of the returned object. - * - * Return value: (transfer none): a #NbtkStyle - */ -NbtkStyle * -nbtk_stylable_get_style (NbtkStylable *stylable) -{ - NbtkStylableIface *iface; - - g_return_val_if_fail (NBTK_IS_STYLABLE (stylable), NULL); - - iface = NBTK_STYLABLE_GET_IFACE (stylable); - if (iface->get_style) - return iface->get_style (stylable); - - return g_object_get_data (G_OBJECT (stylable), "nbtk-stylable-style"); -} - -/** - * nbtk_stylable_set_style: - * @stylable: a #NbtkStylable - * @style: a #NbtkStyle - * - * Sets @style as the new #NbtkStyle to be used by @stylable. - * - * The #NbtkStylable will take ownership of the passed #NbtkStyle. - * - * After the #NbtkStle has been set, the NbtkStylable::style-set signal - * will be emitted. - */ -void -nbtk_stylable_set_style (NbtkStylable *stylable, - NbtkStyle *style) -{ - NbtkStylableIface *iface; - NbtkStyle *old_style; - - g_return_if_fail (NBTK_IS_STYLABLE (stylable)); - g_return_if_fail (NBTK_IS_STYLE (style)); - - iface = NBTK_STYLABLE_GET_IFACE (stylable); - - old_style = nbtk_stylable_get_style (stylable); - g_object_ref (old_style); - - if (iface->set_style) - iface->set_style (stylable, style); - else - { - g_object_set_qdata_full (G_OBJECT (stylable), - quark_style, - g_object_ref_sink (style), - g_object_unref); - } - - g_signal_emit (stylable, stylable_signals[STYLE_CHANGED], 0, old_style); - g_object_unref (old_style); - - g_object_notify (G_OBJECT (stylable), "style"); -} - -/** - * nbtk_stylable_get_container: - * @stylable: a #NbtkStylable - * - * Obtain the parent #NbtkStylable that contains @stylable. - * - * Return value: (transfer none): The parent #NbtkStylable - */ -NbtkStylable* -nbtk_stylable_get_container (NbtkStylable *stylable) -{ - NbtkStylableIface *iface; - - g_return_val_if_fail (NBTK_IS_STYLABLE (stylable), NULL); - - iface = NBTK_STYLABLE_GET_IFACE (stylable); - - if (iface->get_container) - return iface->get_container (stylable); - else - return NULL; -} - -/** - * nbtk_stylable_get_base_style: - * @stylable: a #NbtkStylable - * - * Get the parent ancestor #NbtkStylable of @stylable. - * - * Return value: (transfer none): the parent #NbtkStylable - */ -NbtkStylable* -nbtk_stylable_get_base_style (NbtkStylable *stylable) -{ - NbtkStylableIface *iface; - - g_return_val_if_fail (NBTK_IS_STYLABLE (stylable), NULL); - - iface = NBTK_STYLABLE_GET_IFACE (stylable); - - if (iface->get_base_style) - return iface->get_base_style (stylable); - else - return NULL; -} - - -/** - * nbtk_stylable_get_style_id: - * @stylable: a #NbtkStylable - * - * Get the ID value of @stylable - * - * Return value: the id of @stylable - */ -const gchar* -nbtk_stylable_get_style_id (NbtkStylable *stylable) -{ - NbtkStylableIface *iface; - - g_return_val_if_fail (NBTK_IS_STYLABLE (stylable), NULL); - - iface = NBTK_STYLABLE_GET_IFACE (stylable); - - if (iface->get_style_id) - return iface->get_style_id (stylable); - else - return NULL; -} - -/** - * nbtk_stylable_get_style_type: - * @stylable: a #NbtkStylable - * - * Get the type name of @stylable - * - * Return value: the type name of @stylable - */ -const gchar* -nbtk_stylable_get_style_type (NbtkStylable *stylable) -{ - NbtkStylableIface *iface; - - g_return_val_if_fail (NBTK_IS_STYLABLE (stylable), NULL); - - iface = NBTK_STYLABLE_GET_IFACE (stylable); - - if (iface->get_style_type) - return iface->get_style_type (stylable); - else - return G_OBJECT_TYPE_NAME (stylable); -} - -/** - * nbtk_stylable_get_style_class: - * @stylable: a #NbtkStylable - * - * Get the style class name of @stylable - * - * Return value: the type name of @stylable - */ -const gchar* -nbtk_stylable_get_style_class (NbtkStylable *stylable) -{ - NbtkStylableIface *iface; - - g_return_val_if_fail (NBTK_IS_STYLABLE (stylable), NULL); - - iface = NBTK_STYLABLE_GET_IFACE (stylable); - - if (iface->get_style_class) - return iface->get_style_class (stylable); - else - return NULL; -} - -/** - * nbtk_stylable_get_pseudo_class: - * @stylable: a #NbtkStylable - * - * Get the pseudo class name of @stylable - * - * Return value: the pseudo class name of @stylable - */ -const gchar* -nbtk_stylable_get_pseudo_class (NbtkStylable *stylable) -{ - NbtkStylableIface *iface; - - g_return_val_if_fail (NBTK_IS_STYLABLE (stylable), NULL); - - iface = NBTK_STYLABLE_GET_IFACE (stylable); - - if (iface->get_pseudo_class) - return iface->get_pseudo_class (stylable); - else - return NULL; -} - -/** - * nbtk_stylable_get_attribute: - * @stylable: a #NbtkStylable - * @name: attribute name - * - * Get the named attribute from @stylable - * - * Return value: the value of the attribute - */ -gchar* -nbtk_stylable_get_attribute (NbtkStylable *stylable, - const gchar *name) -{ - NbtkStylableIface *iface; - GValue value = { 0, }; - GValue string_value = { 0, }; - gchar *ret; - GParamSpec *pspec; - - g_return_val_if_fail (NBTK_IS_STYLABLE (stylable), NULL); - - iface = NBTK_STYLABLE_GET_IFACE (stylable); - - if (iface->get_attribute) - return iface->get_attribute (stylable, name); - - /* look up a generic gobject property */ - pspec = g_object_class_find_property (G_OBJECT_GET_CLASS (stylable), name); - - /* if no such property exists, return NULL */ - if (pspec == NULL) - return NULL; - - g_value_init (&value, G_PARAM_SPEC_VALUE_TYPE (pspec)); - g_object_get_property (G_OBJECT (stylable), name, &value); - - g_value_init (&string_value, G_TYPE_STRING); - if (g_value_transform (&value, &string_value)) - ret = g_strdup (g_value_get_string (&string_value)); - else - ret = NULL; - - g_value_unset (&value); - g_value_unset (&string_value); - - return ret; -} - -/** - * nbtk_stylable_get_viewport: - * @stylable: a #NbtkStylable - * @x: location to store X coordinate - * @y: location to store Y coordinate - * @width: location to store width - * @height: location to store height - * - * Obtain the position and dimensions of @stylable. - * - * Return value: true if the function succeeded - */ -gboolean -nbtk_stylable_get_viewport (NbtkStylable *stylable, - gint *x, - gint *y, - gint *width, - gint *height) -{ - NbtkStylableIface *iface; - - g_return_val_if_fail (NBTK_IS_STYLABLE (stylable), FALSE); - - iface = NBTK_STYLABLE_GET_IFACE (stylable); - if (iface->get_viewport) - return iface->get_viewport (stylable, x, y, width, height); - else - return FALSE; -} - - -/** - * nbtk_stylable_changed: - * @stylable: A #NbtkStylable - * - * Emit the "stylable-changed" signal on @stylable - */ -void -nbtk_stylable_changed (NbtkStylable *stylable) -{ - g_signal_emit (stylable, stylable_signals[CHANGED], 0, NULL); -} diff --git a/src/nbtk/nbtk-stylable.h b/src/nbtk/nbtk-stylable.h deleted file mode 100644 index 9a8dd1e8c..000000000 --- a/src/nbtk/nbtk-stylable.h +++ /dev/null @@ -1,123 +0,0 @@ -/* - * nbtk-stylable.h: Interface for stylable objects - * - * Copyright 2008, 2009 Intel Corporation - * - * This program is free software; you can redistribute it and/or modify it - * under the terms and conditions of the GNU Lesser General Public License, - * version 2.1, as published by the Free Software Foundation. - * - * This program is distributed in the hope it will be useful, but WITHOUT ANY - * WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS - * FOR A PARTICULAR PURPOSE. See the GNU Lesser General Public License for - * more details. - * - * You should have received a copy of the GNU Lesser General Public License - * along with this program; if not, write to the Free Software Foundation, - * Inc., 51 Franklin St - Fifth Floor, Boston, MA 02110-1301 USA. - * Boston, MA 02111-1307, USA. - * - * Written by: Emmanuele Bassi - * Thomas Wood - * - */ - -#if !defined(NBTK_H_INSIDE) && !defined(NBTK_COMPILATION) -#error "Only can be included directly.h" -#endif - -#ifndef __NBTK_STYLABLE_H__ -#define __NBTK_STYLABLE_H__ - -#include -#include - -G_BEGIN_DECLS - -#define NBTK_TYPE_STYLABLE (nbtk_stylable_get_type ()) -#define NBTK_STYLABLE(obj) (G_TYPE_CHECK_INSTANCE_CAST ((obj), NBTK_TYPE_STYLABLE, NbtkStylable)) -#define NBTK_IS_STYLABLE(obj) (G_TYPE_CHECK_INSTANCE_TYPE ((obj), NBTK_TYPE_STYLABLE)) -#define NBTK_STYLABLE_IFACE(iface) (G_TYPE_CHECK_CLASS_CAST ((iface), NBTK_TYPE_STYLABLE, NbtkStylableIface)) -#define NBTK_IS_STYLABLE_IFACE(iface) (G_TYPE_CHECK_CLASS_TYPE ((iface), NBTK_TYPE_STYLABLE)) -#define NBTK_STYLABLE_GET_IFACE(obj) (G_TYPE_INSTANCE_GET_INTERFACE ((obj), NBTK_TYPE_STYLABLE, NbtkStylableIface)) - -/* NbtkStylableIface is defined in nbtk-style.h */ - -struct _NbtkStylableIface -{ - GTypeInterface g_iface; - - /* virtual functions */ - NbtkStyle *(* get_style) (NbtkStylable *stylable); - void (* set_style) (NbtkStylable *stylable, - NbtkStyle *style); - - /* context virtual functions */ - NbtkStylable *(*get_container) (NbtkStylable *stylable); - NbtkStylable *(*get_base_style) (NbtkStylable *stylable); - const gchar *(*get_style_id) (NbtkStylable *stylable); - const gchar *(*get_style_type) (NbtkStylable *stylable); - const gchar *(*get_style_class) (NbtkStylable *stylable); - const gchar *(*get_pseudo_class) (NbtkStylable *stylable); - gchar *(*get_attribute) (NbtkStylable *stylable, - const gchar *name); - gboolean (*get_viewport) (NbtkStylable *stylable, - gint *x, - gint *y, - gint *width, - gint *height); - - /* signals, not vfuncs */ - void (* style_notify) (NbtkStylable *stylable, - GParamSpec *pspec); - void (* style_changed) (NbtkStylable *stylable); - - void (* stylable_changed) (NbtkStylable *stylable); -}; - -GType nbtk_stylable_get_type (void) G_GNUC_CONST; - -void nbtk_stylable_iface_install_property (NbtkStylableIface *iface, - GType owner_type, - GParamSpec *pspec); - -void nbtk_stylable_freeze_notify (NbtkStylable *stylable); -void nbtk_stylable_notify (NbtkStylable *stylable, - const gchar *property_name); -void nbtk_stylable_thaw_notify (NbtkStylable *stylable); -GParamSpec **nbtk_stylable_list_properties (NbtkStylable *stylable, - guint *n_props); -GParamSpec * nbtk_stylable_find_property (NbtkStylable *stylable, - const gchar *property_name); -void nbtk_stylable_set_style (NbtkStylable *stylable, - NbtkStyle *style); -NbtkStyle * nbtk_stylable_get_style (NbtkStylable *stylable); - -void nbtk_stylable_get (NbtkStylable *stylable, - const gchar *first_property_name, - ...) G_GNUC_NULL_TERMINATED; -void nbtk_stylable_get_property (NbtkStylable *stylable, - const gchar *property_name, - GValue *value); -gboolean nbtk_stylable_get_default_value (NbtkStylable *stylable, - const gchar *property_name, - GValue *value_out); - -NbtkStylable* nbtk_stylable_get_container (NbtkStylable *stylable); -NbtkStylable* nbtk_stylable_get_base_style (NbtkStylable *stylable); -const gchar* nbtk_stylable_get_style_id (NbtkStylable *stylable); -const gchar* nbtk_stylable_get_style_type (NbtkStylable *stylable); -const gchar* nbtk_stylable_get_style_class (NbtkStylable *stylable); -const gchar* nbtk_stylable_get_pseudo_class (NbtkStylable *stylable); -gchar* nbtk_stylable_get_attribute (NbtkStylable *stylable, - const gchar *name); -gboolean nbtk_stylable_get_viewport (NbtkStylable *stylable, - gint *x, - gint *y, - gint *width, - gint *height); - -void nbtk_stylable_changed (NbtkStylable *stylable); -G_END_DECLS - -#endif /* __NBTK_STYLABLE_H__ */ diff --git a/src/nbtk/nbtk-style.c b/src/nbtk/nbtk-style.c deleted file mode 100644 index 4c3514097..000000000 --- a/src/nbtk/nbtk-style.c +++ /dev/null @@ -1,742 +0,0 @@ -/* - * Copyright 2009 Intel Corporation. - * - * This program is free software; you can redistribute it and/or modify it - * under the terms and conditions of the GNU Lesser General Public License, - * version 2.1, as published by the Free Software Foundation. - * - * This program is distributed in the hope it will be useful, but WITHOUT ANY - * WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS - * FOR A PARTICULAR PURPOSE. See the GNU Lesser General Public License for - * more details. - * - * You should have received a copy of the GNU Lesser General Public License - * along with this program; if not, write to the Free Software Foundation, - * Inc., 51 Franklin St - Fifth Floor, Boston, MA 02110-1301 USA. - * - */ - -/** - * SECTION:nbtk-style - * @short_description: a data store for style properties - * - * #NbtkStyle is a property data store that can read properties from a style - * sheet. It is queried with objects that implement the NbtkStylable - * interface. - */ - - -#include - -#include -#include - -#include -#include -#include - -#include - -#include - -#include "nbtk-stylable.h" -#include "nbtk-style.h" -#include "nbtk-types.h" -#include "nbtk-marshal.h" -#include "nbtk-widget.h" - -enum -{ - CHANGED, - - LAST_SIGNAL -}; - -#define NBTK_STYLE_GET_PRIVATE(obj) \ - (G_TYPE_INSTANCE_GET_PRIVATE ((obj), NBTK_TYPE_STYLE, NbtkStylePrivate)) - -#define NBTK_STYLE_ERROR g_style_error_quark () - -typedef struct { - GType value_type; - gchar *value_name; - GValue value; -} StyleProperty; - -struct _NbtkStylePrivate -{ - ccss_stylesheet_t *stylesheet; - GList *image_paths; - - GHashTable *style_hash; - GHashTable *node_hash; -}; - -typedef struct { - ccss_node_t parent; - NbtkStylable *stylable; - NbtkStylableIface *iface; -} nbtk_style_node_t; - -static ccss_function_t const * peek_css_functions (void); - -static ccss_node_class_t * peek_node_class (void); - -static guint style_signals[LAST_SIGNAL] = { 0, }; - -static NbtkStyle *default_style = NULL; - -G_DEFINE_TYPE (NbtkStyle, nbtk_style, G_TYPE_OBJECT); - -static GQuark -g_style_error_quark (void) -{ - return g_quark_from_static_string ("nbtk-style-error-quark"); -} - -static gboolean -nbtk_style_real_load_from_file (NbtkStyle *style, - const gchar *filename, - GError **error, - gint priority) -{ - NbtkStylePrivate *priv; - ccss_grammar_t *grammar; - GError *internal_error; - gchar *path; - GList *l; - - g_return_val_if_fail (NBTK_IS_STYLE (style), FALSE); - g_return_val_if_fail (filename != NULL, FALSE); - - priv = NBTK_STYLE (style)->priv; - - if (!g_file_test (filename, G_FILE_TEST_IS_REGULAR)) - { - internal_error = g_error_new (NBTK_STYLE_ERROR, - NBTK_STYLE_ERROR_INVALID_FILE, - _("Invalid theme file '%s'"), filename); - g_propagate_error (error, internal_error); - return FALSE; - } - - - /* add the path of the stylesheet to the search path */ - path = g_path_get_dirname (filename); - - /* make sure path is valid */ - if (!path) - return TRUE; - - for (l = priv->image_paths; l; l = l->next) - { - if (g_str_equal ((gchar *)l->data, path)) - { - /* we have this path already */ - g_free (path); - path = NULL; - } - } - - /* Add the new path */ - if (path) - priv->image_paths = g_list_append (priv->image_paths, path); - - /* now load the stylesheet */ - if (!priv->stylesheet) - { - grammar = ccss_grammar_create_css (); - ccss_grammar_add_functions (grammar, peek_css_functions ()); - priv->stylesheet = ccss_grammar_create_stylesheet_from_file (grammar, - filename, - path); - ccss_grammar_destroy (grammar); - } - else - { - ccss_stylesheet_add_from_file (priv->stylesheet, filename, priority, path); - } - - g_signal_emit (style, style_signals[CHANGED], 0, NULL); - - return TRUE; -} - -/** - * nbtk_style_load_from_file: - * @style: a #NbtkStyle - * @filename: filename of the style sheet to load - * @error: a #GError or #NULL - * - * Load style information from the specified file. - * - * returns: TRUE if the style information was loaded successfully. Returns - * FALSE on error. - */ -gboolean -nbtk_style_load_from_file (NbtkStyle *style, - const gchar *filename, - GError **error) -{ - return nbtk_style_real_load_from_file (style, filename, error, - CCSS_STYLESHEET_AUTHOR); -} - -static void -nbtk_style_finalize (GObject *gobject) -{ - NbtkStylePrivate *priv = ((NbtkStyle *)gobject)->priv; - GList *l; - - for (l = priv->image_paths; l; l = g_list_delete_link (l, l)) - { - g_free (l->data); - } - - G_OBJECT_CLASS (nbtk_style_parent_class)->finalize (gobject); -} - -static void -nbtk_style_class_init (NbtkStyleClass *klass) -{ - GObjectClass *gobject_class = G_OBJECT_CLASS (klass); - - g_type_class_add_private (klass, sizeof (NbtkStylePrivate)); - - gobject_class->finalize = nbtk_style_finalize; - - /** - * NbtkStyle::changed: - * - * Indicates that the style data has changed in some way. For example, a new - * stylesheet may have been loaded. - */ - - style_signals[CHANGED] = - g_signal_new ("changed", - G_TYPE_FROM_CLASS (klass), - G_SIGNAL_RUN_LAST, - G_STRUCT_OFFSET (NbtkStyleClass, changed), - NULL, NULL, - _nbtk_marshal_VOID__VOID, - G_TYPE_NONE, 0); -} - -/* url loader for libccss */ -static char * -ccss_url (GSList const *args, - void *user_data) -{ - const gchar *given_path, *filename; - gchar *test_path; - - g_return_val_if_fail (args, NULL); - - given_path = (char const *) args->data; - - /* we can only deal with local paths */ - if (!g_str_has_prefix (given_path, "file://")) - return NULL; - filename = &given_path[7]; - - /* - * Handle absolute paths correctly - */ - if (*filename == '/') - return strdup (filename); - - /* first try looking in the theme dir */ - test_path = g_build_filename (g_get_user_config_dir (), - "nbtk", - filename, - NULL); - if (g_file_test (test_path, G_FILE_TEST_IS_REGULAR)) - return test_path; - g_free (test_path); - - if (user_data) - { - test_path = g_build_filename ((gchar *) user_data, filename, NULL); - - if (g_file_test (test_path, G_FILE_TEST_IS_REGULAR)) - return test_path; - - g_free (test_path); - } - else - { - g_warning ("No path available css url resolver!"); - } - - /* couldn't find the image anywhere, so just return the filename */ - return strdup (given_path); -} - -static ccss_function_t const * -peek_css_functions (void) -{ - static ccss_function_t const ccss_functions[] = - { - { "url", ccss_url }, - { NULL } - }; - - return ccss_functions; -} - - -static void -nbtk_style_init (NbtkStyle *style) -{ - NbtkStylePrivate *priv; - - style->priv = priv = NBTK_STYLE_GET_PRIVATE (style); - - /* create a hash table to look up pointer keys and values */ - style->priv->node_hash = g_hash_table_new_full (NULL, NULL, - NULL, g_free); - style->priv->style_hash = g_hash_table_new_full (NULL, NULL, - NULL, (GDestroyNotify) ccss_style_destroy); - -} - -/** - * nbtk_style_new: - * - * Creates a new #NbtkStyle object. This must be freed using #g_object_unref - * when no longer required. - * - * Returns: a newly allocated #NbtkStyle - */ -NbtkStyle * -nbtk_style_new (void) -{ - return g_object_new (NBTK_TYPE_STYLE, NULL); -} - -/** - * nbtk_style_get_default: - * - * Return the default NbtkStyle object. This includes the current theme (if - * any). - * - * Returns: (transfer none): a #NbtkStyle object. This must not be freed or - * unref'd by applications - */ -NbtkStyle * -nbtk_style_get_default (void) -{ - if (G_LIKELY (default_style)) - return default_style; - - default_style = g_object_new (NBTK_TYPE_STYLE, NULL); - - return default_style; -} - -/* functions for ccss */ - -static nbtk_style_node_t * -get_container (nbtk_style_node_t *node) -{ - nbtk_style_node_t *container; - ClutterActor *parent; - - g_return_val_if_fail (node, NULL); - g_return_val_if_fail (node->iface, NULL); - g_return_val_if_fail (node->stylable, NULL); - - parent = clutter_actor_get_parent (CLUTTER_ACTOR (node->stylable)); - while (parent && !NBTK_IS_WIDGET (parent)) - parent = clutter_actor_get_parent (CLUTTER_ACTOR (parent)); - - if (!parent) - return NULL; - - container = g_new0 (nbtk_style_node_t, 1); - ccss_node_init ((ccss_node_t*) container, peek_node_class ()); - container->iface = node->iface; - container->stylable = NBTK_STYLABLE (parent); - - return container; -} - -static const gchar* -get_style_id (nbtk_style_node_t *node) -{ - return nbtk_stylable_get_style_id (node->stylable); -} - -static const gchar* -get_style_type (nbtk_style_node_t *node) -{ - return nbtk_stylable_get_style_type (node->stylable); -} - -static const gchar* -get_style_class (nbtk_style_node_t *node) -{ - return nbtk_stylable_get_style_class (node->stylable); -} - -static const gchar* -get_pseudo_class (nbtk_style_node_t *node) -{ - return nbtk_stylable_get_pseudo_class (node->stylable); -} - -static const gchar* -get_attribute (nbtk_style_node_t *node, const char *name) -{ - return nbtk_stylable_get_attribute (node->stylable, name); -} - -static void -release (nbtk_style_node_t *node) -{ - g_return_if_fail (node); - - g_free (node); -} - -static ccss_node_class_t * -peek_node_class (void) -{ - static ccss_node_class_t _node_class = { - .is_a = NULL, - .get_container = (ccss_node_get_container_f) get_container, - .get_id = (ccss_node_get_id_f) get_style_id, - .get_type = (ccss_node_get_type_f) get_style_type, - .get_class = (ccss_node_get_class_f) get_style_class, - .get_pseudo_class = (ccss_node_get_pseudo_class_f) get_pseudo_class, - .get_viewport = NULL,// (ccss_node_get_viewport_f) get_viewport, - .get_attribute = (ccss_node_get_attribute_f) get_attribute, - .release = (ccss_node_release_f) release - }; - - return &_node_class; -} - -static void -nbtk_style_fetch_ccss_property (ccss_style_t *ccss_style, - GParamSpec *pspec, - GValue *value) -{ - gboolean value_set = FALSE; - - g_value_init (value, G_PARAM_SPEC_VALUE_TYPE (pspec)); - - if (G_PARAM_SPEC_VALUE_TYPE (pspec)) - { - double number; - - if (G_IS_PARAM_SPEC_INT (pspec)) - { - if (ccss_style_get_double (ccss_style, pspec->name, &number)) - { - g_value_set_int (value, (gint) number); - value_set = TRUE; - } - } - else if (G_IS_PARAM_SPEC_UINT (pspec)) - { - if (ccss_style_get_double (ccss_style, pspec->name, &number)) - { - g_value_set_uint (value, (guint) number); - value_set = TRUE; - } - } - else if (G_PARAM_SPEC_VALUE_TYPE (pspec) == NBTK_TYPE_BORDER_IMAGE && - !g_strcmp0 ("border-image", pspec->name)) - { - ccss_border_image_t const *border_image; - - if (ccss_style_get_property (ccss_style, - "border-image", - (ccss_property_base_t const **) &border_image)) - { - if (border_image && - border_image->base.state == CCSS_PROPERTY_STATE_SET) - { - g_value_set_boxed (value, border_image); - value_set = TRUE; - } - } - } - else if (NBTK_TYPE_PADDING == G_PARAM_SPEC_VALUE_TYPE (pspec) && - 0 == g_strcmp0 ("padding", pspec->name)) - { - NbtkPadding padding = { 0, }; - gboolean padding_set = 0; - - if (ccss_style_get_double (ccss_style, "padding-top", &number)) - { - padding.top = number; - padding_set = TRUE; - } - - if (ccss_style_get_double (ccss_style, "padding-right", &number)) - { - padding.right = number; - padding_set = TRUE; - } - - if (ccss_style_get_double (ccss_style, "padding-bottom", &number)) - { - padding.bottom = number; - padding_set = TRUE; - } - - if (ccss_style_get_double (ccss_style, "padding-left", &number)) - { - padding.left = number; - padding_set = TRUE; - } - - if (padding_set) - { - g_value_set_boxed (value, &padding); - value_set = TRUE; - } - } - else - { - gchar *string = NULL; - - ccss_style_get_string (ccss_style, pspec->name, &string); - - if (string) - { - if (CLUTTER_IS_PARAM_SPEC_COLOR (pspec)) - { - ClutterColor color = { 0, }; - - clutter_color_from_string (&color, string); - clutter_value_set_color (value, &color); - - value_set = TRUE; - } - else - if (G_IS_PARAM_SPEC_STRING (pspec)) - { - g_value_set_string (value, string); - value_set = TRUE; - } - g_free (string); - } - } - } - - /* no value was found in css, so copy in the default value */ - if (!value_set) - g_param_value_set_default (pspec, value); -} - -static ccss_style_t* -nbtk_style_get_ccss_query (NbtkStyle *style, - NbtkStylable *stylable) -{ - NbtkStylableIface *iface = NBTK_STYLABLE_GET_IFACE (stylable); - ccss_style_t *ccss_style; - nbtk_style_node_t *ccss_node; - - ccss_node = g_hash_table_lookup (style->priv->node_hash, stylable); - - if (!ccss_node) - { - ccss_node = g_new0 (nbtk_style_node_t, 1); - ccss_node_init ((ccss_node_t*) ccss_node, peek_node_class ()); - ccss_node->iface = iface; - ccss_node->stylable = stylable; - - g_hash_table_insert (style->priv->node_hash, stylable, ccss_node); - g_signal_connect_swapped (stylable, "stylable-changed", - G_CALLBACK (g_hash_table_remove), - style->priv->node_hash); - - - g_object_weak_ref ((GObject*) stylable, - (GWeakNotify) g_hash_table_remove, style->priv->node_hash); - } - - - ccss_style = g_hash_table_lookup (style->priv->style_hash, stylable); - - if (!ccss_style) - { - ccss_style = ccss_stylesheet_query (style->priv->stylesheet, - (ccss_node_t *) ccss_node); - - g_hash_table_insert (style->priv->style_hash, stylable, ccss_style); - - /* remove the cache if the stylable changes */ - g_signal_connect_swapped (stylable, "stylable-changed", - G_CALLBACK (g_hash_table_remove), - style->priv->style_hash); - - g_object_weak_ref ((GObject*) stylable, - (GWeakNotify) g_hash_table_remove, style->priv->style_hash); - } - - return ccss_style; - -} - - -/** - * nbtk_style_get_property: - * @style: the style data store object - * @stylable: a stylable to retreive the data for - * @pspec: a #GParamSpec describing the property required - * @value: (out): a #GValue to place the return value in - * - * Requests the property described in @pspec for the specified stylable - */ - -void -nbtk_style_get_property (NbtkStyle *style, - NbtkStylable *stylable, - GParamSpec *pspec, - GValue *value) -{ - NbtkStylePrivate *priv; - gboolean value_set = FALSE; - - g_return_if_fail (NBTK_IS_STYLE (style)); - g_return_if_fail (NBTK_IS_STYLABLE (stylable)); - g_return_if_fail (pspec != NULL); - g_return_if_fail (value != NULL); - - priv = style->priv; - - /* look up the property in the css */ - if (priv->stylesheet) - { - ccss_style_t *ccss_style; - - ccss_style = nbtk_style_get_ccss_query (style, stylable); - if (ccss_style) - { - nbtk_style_fetch_ccss_property (ccss_style, pspec, value); - value_set = TRUE; - } - } - - /* no value was found in css, so copy in the default value */ - if (!value_set) - { - g_value_init (value, G_PARAM_SPEC_VALUE_TYPE (pspec)); - g_param_value_set_default (pspec, value); - } -} - -/** - * nbtk_style_get_valist: - * @style: a #NbtkStyle - * @stylable: a #NbtkStylable - * @first_property_name: name of the first property to get - * @va_args: return location for the first property, followed optionally - * by more name/return location pairs, followed by %NULL - * - * Gets the style properties for @stylable from @style. - * - * Please refer to nbtk_style_get() for further information. - */ -void -nbtk_style_get_valist (NbtkStyle *style, - NbtkStylable *stylable, - const gchar *first_property_name, - va_list va_args) -{ - NbtkStylePrivate *priv; - const gchar *name = first_property_name; - gboolean values_set = FALSE; - - g_return_if_fail (NBTK_IS_STYLE (style)); - g_return_if_fail (NBTK_IS_STYLABLE (stylable)); - g_return_if_fail (style->priv != NULL); - - priv = style->priv; - - /* look up the property in the css */ - if (priv->stylesheet) - { - ccss_style_t *ccss_style; - - ccss_style = nbtk_style_get_ccss_query (style, stylable); - - if (ccss_style) - { - while (name) - { - GValue value = { 0, }; - gchar *error = NULL; - GParamSpec *pspec = nbtk_stylable_find_property (stylable, name); - nbtk_style_fetch_ccss_property (ccss_style, pspec, &value); - G_VALUE_LCOPY (&value, va_args, 0, &error); - if (error) - { - g_warning ("%s: %s", G_STRLOC, error); - g_free (error); - g_value_unset (&value); - break; - } - g_value_unset (&value); - name = va_arg (va_args, gchar*); - } - values_set = TRUE; - } - } - - if (!values_set) - { - /* Set the remaining properties to their default values - * even if broken out of the above loop. */ - while (name) - { - GValue value = { 0, }; - gchar *error = NULL; - nbtk_stylable_get_default_value (stylable, name, &value); - G_VALUE_LCOPY (&value, va_args, 0, &error); - if (error) - { - g_warning ("%s: %s", G_STRLOC, error); - g_free (error); - g_value_unset (&value); - break; - } - g_value_unset (&value); - name = va_arg (va_args, gchar*); - } - } -} - -/** - * nbtk_style_get: - * @style: a #NbtkStyle - * @stylable: a #NbtkStylable - * @first_property_name: name of the first property to get - * @Varargs: return location for the first property, followed optionally - * by more name/return location pairs, followed by %NULL - * - * Gets the style properties for @stylable from @style. - * - * In general, a copy is made of the property contents and the caller - * is responsible for freeing the memory in the appropriate manner for - * the property type. - */ -void -nbtk_style_get (NbtkStyle *style, - NbtkStylable *stylable, - const gchar *first_property_name, - ...) -{ - va_list va_args; - - g_return_if_fail (NBTK_IS_STYLE (style)); - g_return_if_fail (first_property_name != NULL); - - va_start (va_args, first_property_name); - nbtk_style_get_valist (style, stylable, first_property_name, va_args); - va_end (va_args); -} diff --git a/src/nbtk/nbtk-style.h b/src/nbtk/nbtk-style.h deleted file mode 100644 index 35efc12e8..000000000 --- a/src/nbtk/nbtk-style.h +++ /dev/null @@ -1,94 +0,0 @@ -/* - * Copyright 2009 Intel Corporation. - * - * This program is free software; you can redistribute it and/or modify it - * under the terms and conditions of the GNU Lesser General Public License, - * version 2.1, as published by the Free Software Foundation. - * - * This program is distributed in the hope it will be useful, but WITHOUT ANY - * WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS - * FOR A PARTICULAR PURPOSE. See the GNU Lesser General Public License for - * more details. - * - * You should have received a copy of the GNU Lesser General Public License - * along with this program; if not, write to the Free Software Foundation, - * Inc., 51 Franklin St - Fifth Floor, Boston, MA 02110-1301 USA. - * - */ - -#if !defined(NBTK_H_INSIDE) && !defined(NBTK_COMPILATION) -#error "Only can be included directly.h" -#endif - -#ifndef __NBTK_STYLE_H__ -#define __NBTK_STYLE_H__ - -#include -#include - -G_BEGIN_DECLS - -#define NBTK_TYPE_STYLE (nbtk_style_get_type ()) -#define NBTK_STYLE(obj) (G_TYPE_CHECK_INSTANCE_CAST ((obj), NBTK_TYPE_STYLE, NbtkStyle)) -#define NBTK_IS_STYLE(obj) (G_TYPE_CHECK_INSTANCE_TYPE ((obj), NBTK_TYPE_STYLE)) -#define NBTK_STYLE_CLASS(klass) (G_TYPE_CHECK_CLASS_CAST ((klass), NBTK_TYPE_STYLE, NbtkStyleClass)) -#define NBTK_IS_STYLE_CLASS(klass) (G_TYPE_CHECK_CLASS_TYPE ((klass), NBTK_TYPE_STYLE)) -#define NBTK_STYLE_GET_CLASS(obj) (G_TYPE_INSTANCE_GET_CLASS ((obj), NBTK_TYPE_STYLE, NbtkStyleClass)) - -typedef struct _NbtkStyle NbtkStyle; -typedef struct _NbtkStylePrivate NbtkStylePrivate; -typedef struct _NbtkStyleClass NbtkStyleClass; - -/* forward declaration */ -typedef struct _NbtkStylable NbtkStylable; /* dummy typedef */ -typedef struct _NbtkStylableIface NbtkStylableIface; - -typedef enum { /*< prefix=NBTK_STYLE_ERROR >*/ - NBTK_STYLE_ERROR_INVALID_FILE -} NbtkStyleError; - -/** - * NbtkStyle: - * - * The contents of this structure is private and should only be accessed using - * the provided API. - */ -struct _NbtkStyle -{ - /*< private >*/ - GObject parent_instance; - - NbtkStylePrivate *priv; -}; - -struct _NbtkStyleClass -{ - GObjectClass parent_class; - - void (* changed) (NbtkStyle *style); -}; - -GType nbtk_style_get_type (void) G_GNUC_CONST; - -NbtkStyle * nbtk_style_get_default (void); -NbtkStyle * nbtk_style_new (void); - -gboolean nbtk_style_load_from_file (NbtkStyle *style, - const gchar *filename, - GError **error); -void nbtk_style_get_property (NbtkStyle *style, - NbtkStylable *stylable, - GParamSpec *pspec, - GValue *value); -void nbtk_style_get (NbtkStyle *style, - NbtkStylable *stylable, - const gchar *first_property_name, - ...) G_GNUC_NULL_TERMINATED; -void nbtk_style_get_valist (NbtkStyle *style, - NbtkStylable *stylable, - const gchar *first_property_name, - va_list va_args); - -G_END_DECLS - -#endif /* __NBTK_STYLE_H__ */ diff --git a/src/nbtk/nbtk-tooltip.c b/src/nbtk/nbtk-tooltip.c index 4bae5274a..1f832d70d 100644 --- a/src/nbtk/nbtk-tooltip.c +++ b/src/nbtk/nbtk-tooltip.c @@ -44,7 +44,6 @@ #include "nbtk-tooltip.h" #include "nbtk-widget.h" -#include "nbtk-stylable.h" #include "nbtk-private.h" enum @@ -120,44 +119,24 @@ nbtk_tooltip_get_property (GObject *gobject, static void nbtk_tooltip_style_changed (NbtkWidget *self) { - ClutterColor *color = NULL; NbtkTooltipPrivate *priv; - gchar *font_name; + ShellThemeNode *theme_node; + ClutterColor color; + const PangoFontDescription *font; gchar *font_string; - gint font_size; priv = NBTK_TOOLTIP (self)->priv; + theme_node = nbtk_widget_get_theme_node (self); - nbtk_stylable_get (NBTK_STYLABLE (self), - "color", &color, - "font-family", &font_name, - "font-size", &font_size, - NULL); + shell_theme_node_get_foreground_color (theme_node, &color); + clutter_text_set_color (CLUTTER_TEXT (priv->label), &color); - if (color) - { - clutter_text_set_color (CLUTTER_TEXT (priv->label), color); - clutter_color_free (color); - } - - if (font_name || font_size) - { - if (font_name && font_size) - { - font_string = g_strdup_printf ("%s %dpx", font_name, font_size); - g_free (font_name); - } - else - if (font_size) - font_string = g_strdup_printf ("%dpx", font_size); - else - font_string = font_name; - - clutter_text_set_font_name (CLUTTER_TEXT (priv->label), font_string); - - g_free (font_string); - } + font = shell_theme_node_get_font (theme_node); + font_string = pango_font_description_to_string (font); + clutter_text_set_font_name (CLUTTER_TEXT (priv->label), font_string); + g_free (font_string); + NBTK_WIDGET_CLASS (nbtk_tooltip_parent_class)->style_changed (self); } static void @@ -405,6 +384,7 @@ nbtk_tooltip_class_init (NbtkTooltipClass *klass) { GObjectClass *gobject_class = G_OBJECT_CLASS (klass); ClutterActorClass *actor_class = CLUTTER_ACTOR_CLASS (klass); + NbtkWidgetClass *widget_class = NBTK_WIDGET_CLASS (klass); GParamSpec *pspec; g_type_class_add_private (klass, sizeof (NbtkTooltipPrivate)); @@ -419,6 +399,8 @@ nbtk_tooltip_class_init (NbtkTooltipClass *klass) actor_class->map = nbtk_tooltip_map; actor_class->unmap = nbtk_tooltip_unmap; + widget_class->style_changed = nbtk_tooltip_style_changed; + pspec = g_param_spec_string ("label", "Label", "Label of the tooltip", @@ -452,9 +434,6 @@ nbtk_tooltip_init (NbtkTooltip *tooltip) g_object_set (tooltip, "show-on-set-parent", FALSE, NULL); clutter_actor_set_reactive (CLUTTER_ACTOR (tooltip), FALSE); - - g_signal_connect (tooltip, "style-changed", - G_CALLBACK (nbtk_tooltip_style_changed), NULL); } static void diff --git a/src/nbtk/nbtk-types.h b/src/nbtk/nbtk-types.h index 77acfad78..bb7eee427 100644 --- a/src/nbtk/nbtk-types.h +++ b/src/nbtk/nbtk-types.h @@ -28,13 +28,10 @@ G_BEGIN_DECLS -#define NBTK_TYPE_BORDER_IMAGE (nbtk_border_image_get_type ()) #define NBTK_TYPE_PADDING (nbtk_padding_get_type ()) typedef struct _NbtkPadding NbtkPadding; -GType nbtk_border_image_get_type (void) G_GNUC_CONST; - /** * NbtkPadding: * @top: padding from the top diff --git a/src/nbtk/nbtk-widget.c b/src/nbtk/nbtk-widget.c index bc6cc9c68..4cc6c42e9 100644 --- a/src/nbtk/nbtk-widget.c +++ b/src/nbtk/nbtk-widget.c @@ -31,18 +31,16 @@ #include #include -#include #include "nbtk-widget.h" #include "nbtk-marshal.h" #include "nbtk-private.h" -#include "nbtk-stylable.h" #include "nbtk-texture-cache.h" #include "nbtk-texture-frame.h" #include "nbtk-tooltip.h" -typedef ccss_border_image_t NbtkBorderImage; +#include /* * Forward declaration for sake of NbtkWidgetChild @@ -52,13 +50,14 @@ struct _NbtkWidgetPrivate NbtkPadding border; NbtkPadding padding; - NbtkStyle *style; + ShellTheme *theme; + ShellThemeNode *theme_node; gchar *pseudo_class; gchar *style_class; ClutterActor *border_image; ClutterActor *background_image; - ClutterColor *bg_color; + ClutterColor bg_color; gboolean is_stylable : 1; gboolean has_tooltip : 1; @@ -82,7 +81,7 @@ enum { PROP_0, - PROP_STYLE, + PROP_THEME, PROP_PSEUDO_CLASS, PROP_STYLE_CLASS, @@ -92,12 +91,16 @@ enum PROP_TOOLTIP_TEXT }; -static void nbtk_stylable_iface_init (NbtkStylableIface *iface); +enum +{ + STYLE_CHANGED, + LAST_SIGNAL +}; -G_DEFINE_ABSTRACT_TYPE_WITH_CODE (NbtkWidget, nbtk_widget, CLUTTER_TYPE_ACTOR, - G_IMPLEMENT_INTERFACE (NBTK_TYPE_STYLABLE, - nbtk_stylable_iface_init)); +static guint signals[LAST_SIGNAL] = { 0, }; + +G_DEFINE_ABSTRACT_TYPE (NbtkWidget, nbtk_widget, CLUTTER_TYPE_ACTOR); #define NBTK_WIDGET_GET_PRIVATE(obj) (G_TYPE_INSTANCE_GET_PRIVATE ((obj), NBTK_TYPE_WIDGET, NbtkWidgetPrivate)) @@ -111,9 +114,8 @@ nbtk_widget_set_property (GObject *gobject, switch (prop_id) { - case PROP_STYLE: - nbtk_stylable_set_style (NBTK_STYLABLE (actor), - g_value_get_object (value)); + case PROP_THEME: + nbtk_widget_set_theme (actor, g_value_get_object (value)); break; case PROP_PSEUDO_CLASS: @@ -157,8 +159,8 @@ nbtk_widget_get_property (GObject *gobject, switch (prop_id) { - case PROP_STYLE: - g_value_set_object (value, priv->style); + case PROP_THEME: + g_value_set_object (value, priv->theme); break; case PROP_PSEUDO_CLASS: @@ -193,10 +195,10 @@ nbtk_widget_dispose (GObject *gobject) NbtkWidget *actor = NBTK_WIDGET (gobject); NbtkWidgetPrivate *priv = NBTK_WIDGET (actor)->priv; - if (priv->style) + if (priv->theme) { - g_object_unref (priv->style); - priv->style = NULL; + g_object_unref (priv->theme); + priv->theme = NULL; } if (priv->border_image) @@ -205,12 +207,6 @@ nbtk_widget_dispose (GObject *gobject) priv->border_image = NULL; } - if (priv->bg_color) - { - clutter_color_free (priv->bg_color); - priv->bg_color = NULL; - } - if (priv->tooltip) { ClutterContainer *parent; @@ -386,7 +382,7 @@ nbtk_widget_paint (ClutterActor *self) klass->draw_background (NBTK_WIDGET (self), priv->border_image, - priv->bg_color); + &priv->bg_color); if (priv->background_image != NULL) clutter_actor_paint (priv->background_image); @@ -407,7 +403,7 @@ nbtk_widget_parent_set (ClutterActor *widget, /* don't send the style changed signal if we no longer have a parent actor */ if (new_parent) - nbtk_stylable_changed ((NbtkStylable*) widget); + nbtk_widget_style_changed (NBTK_WIDGET (widget)); } static void @@ -446,69 +442,67 @@ nbtk_widget_unmap (ClutterActor *actor) clutter_actor_unmap ((ClutterActor *) priv->tooltip); } +static void notify_children_of_style_change (ClutterContainer *container); + static void -nbtk_widget_style_changed (NbtkStylable *self) +notify_children_of_style_change_foreach (ClutterActor *actor, + gpointer user_data) +{ + if (NBTK_IS_WIDGET (actor)) + nbtk_widget_style_changed (NBTK_WIDGET (actor)); + else if (CLUTTER_IS_CONTAINER (actor)) + notify_children_of_style_change ((ClutterContainer *)actor); +} + +static void +notify_children_of_style_change (ClutterContainer *container) +{ + /* notify our children that their parent stylable has changed */ + clutter_container_foreach (container, + notify_children_of_style_change_foreach, + NULL); +} + +static void +nbtk_widget_real_style_changed (NbtkWidget *self) { NbtkWidgetPrivate *priv = NBTK_WIDGET (self)->priv; - NbtkBorderImage *border_image = NULL; + ShellThemeNode *theme_node; + ShellThemeImage *theme_image; NbtkTextureCache *texture_cache; ClutterTexture *texture; - gchar *bg_file = NULL; - NbtkPadding *padding = NULL; + const char *bg_file = NULL; gboolean relayout_needed = FALSE; gboolean has_changed = FALSE; - ClutterColor *color; + NbtkPadding padding; + ClutterColor color; /* application has request this widget is not stylable */ if (!priv->is_stylable) return; - /* cache these values for use in the paint function */ - nbtk_stylable_get (self, - "background-color", &color, - "background-image", &bg_file, - "border-image", &border_image, - "padding", &padding, - NULL); + theme_node = nbtk_widget_get_theme_node (self); - if (color) + shell_theme_node_get_background_color (theme_node, &color); + if (!clutter_color_equal (&color, &priv->bg_color)) { - if (priv->bg_color && clutter_color_equal (color, priv->bg_color)) - { - /* color is the same ... */ - clutter_color_free (color); - } - else - { - clutter_color_free (priv->bg_color); - priv->bg_color = color; - has_changed = TRUE; - } + priv->bg_color = color; + has_changed = TRUE; } - else - if (priv->bg_color) - { - clutter_color_free (priv->bg_color); - priv->bg_color = NULL; - has_changed = TRUE; - } + padding.top = shell_theme_node_get_padding (theme_node, SHELL_SIDE_TOP); + padding.right = shell_theme_node_get_padding (theme_node, SHELL_SIDE_RIGHT); + padding.bottom = shell_theme_node_get_padding (theme_node, SHELL_SIDE_BOTTOM); + padding.left = shell_theme_node_get_padding (theme_node, SHELL_SIDE_LEFT); - - if (padding) + if (priv->padding.top != padding.top || + priv->padding.left != padding.left || + priv->padding.right != padding.right || + priv->padding.bottom != padding.bottom) { - if (priv->padding.top != padding->top || - priv->padding.left != padding->left || - priv->padding.right != padding->right || - priv->padding.bottom != padding->bottom) - { - /* Padding changed. Need to relayout. */ - has_changed = TRUE; - relayout_needed = TRUE; - } - - priv->padding = *padding; - g_boxed_free (NBTK_TYPE_PADDING, padding); + priv->padding = padding; + has_changed = TRUE; + relayout_needed = TRUE; } if (priv->border_image) @@ -525,26 +519,27 @@ nbtk_widget_style_changed (NbtkStylable *self) texture_cache = nbtk_texture_cache_get_default (); - /* Check if the URL is actually present, not garbage in the property */ - if (border_image && border_image->uri) + theme_image = shell_theme_node_get_background_theme_image (theme_node); + if (theme_image) { + const char *filename; gint border_left, border_right, border_top, border_bottom; gint width, height; + filename = shell_theme_image_get_filename (theme_image); + /* `border-image' takes precedence over `background-image'. * Firefox lets the background-image shine thru when border-image has * alpha an channel, maybe that would be an option for the future. */ texture = nbtk_texture_cache_get_texture (texture_cache, - border_image->uri, + filename, FALSE); clutter_texture_get_base_size (CLUTTER_TEXTURE (texture), &width, &height); - border_left = ccss_position_get_size (&border_image->left, width); - border_top = ccss_position_get_size (&border_image->top, height); - border_right = ccss_position_get_size (&border_image->right, width); - border_bottom = ccss_position_get_size (&border_image->bottom, height); + shell_theme_image_get_borders (theme_image, + &border_left, &border_right, &border_top, &border_bottom); priv->border_image = nbtk_texture_frame_new (texture, border_top, @@ -552,14 +547,13 @@ nbtk_widget_style_changed (NbtkStylable *self) border_bottom, border_left); clutter_actor_set_parent (priv->border_image, CLUTTER_ACTOR (self)); - g_boxed_free (NBTK_TYPE_BORDER_IMAGE, border_image); has_changed = TRUE; relayout_needed = TRUE; } - if (bg_file != NULL && - strcmp (bg_file, "none")) + bg_file = shell_theme_node_get_background_image (theme_node); + if (bg_file != NULL) { texture = nbtk_texture_cache_get_texture (texture_cache, bg_file, @@ -577,7 +571,6 @@ nbtk_widget_style_changed (NbtkStylable *self) has_changed = TRUE; relayout_needed = TRUE; } - g_free (bg_file); /* If there are any properties above that need to cause a relayout thay * should set this flag. @@ -590,37 +583,89 @@ nbtk_widget_style_changed (NbtkStylable *self) clutter_actor_queue_redraw ((ClutterActor *) self); } - priv->is_style_dirty = FALSE; + if (CLUTTER_IS_CONTAINER (self)) + notify_children_of_style_change ((ClutterContainer *)self); } -static void -nbtk_widget_stylable_child_notify (ClutterActor *actor, - gpointer user_data) +void +nbtk_widget_style_changed (NbtkWidget *widget) { - if (NBTK_IS_STYLABLE (actor)) - nbtk_stylable_changed ((NbtkStylable*) actor); -} - -static void -nbtk_widget_stylable_changed (NbtkStylable *stylable) -{ - - NBTK_WIDGET (stylable)->priv->is_style_dirty = TRUE; + widget->priv->is_style_dirty = TRUE; + if (widget->priv->theme_node) + { + g_object_unref (widget->priv->theme_node); + widget->priv->theme_node = NULL; + } /* update the style only if we are mapped */ - if (!CLUTTER_ACTOR_IS_MAPPED ((ClutterActor *) stylable)) + if (!CLUTTER_ACTOR_IS_MAPPED (CLUTTER_ACTOR (widget))) return; - g_signal_emit_by_name (stylable, "style-changed", 0); + nbtk_widget_ensure_style (widget); +} +static void +on_theme_context_changed (ShellThemeContext *context, + ClutterStage *stage) +{ + notify_children_of_style_change (CLUTTER_CONTAINER (stage)); +} - if (CLUTTER_IS_CONTAINER (stylable)) +static ShellThemeNode * +get_root_theme_node (ClutterStage *stage) +{ + ShellThemeContext *context = shell_theme_context_get_for_stage (stage); + + if (!g_object_get_data (G_OBJECT (context), "nbtk-theme-initialized")) { - /* notify our children that their parent stylable has changed */ - clutter_container_foreach ((ClutterContainer *) stylable, - nbtk_widget_stylable_child_notify, - NULL); + g_object_set_data (G_OBJECT (context), "nbtk-theme-initialized", GUINT_TO_POINTER (1)); + g_signal_connect (G_OBJECT (context), "changed", + G_CALLBACK (on_theme_context_changed), stage); } + + return shell_theme_context_get_root_node (context); +} + +ShellThemeNode * +nbtk_widget_get_theme_node (NbtkWidget *widget) +{ + NbtkWidgetPrivate *priv = widget->priv; + + if (priv->theme_node == NULL) + { + ShellThemeNode *parent_node = NULL; + ClutterStage *stage = NULL; + ClutterActor *parent; + + parent = clutter_actor_get_parent (CLUTTER_ACTOR (widget)); + while (parent != NULL) + { + if (parent_node == NULL && NBTK_IS_WIDGET (parent)) + parent_node = nbtk_widget_get_theme_node (NBTK_WIDGET (parent)); + else if (CLUTTER_IS_STAGE (parent)) + stage = CLUTTER_STAGE (parent); + + parent = clutter_actor_get_parent (parent); + } + + if (stage == NULL) + { + g_warning ("nbtk_widget_get_theme_node called on a widget not in a stage"); + stage = CLUTTER_STAGE (clutter_stage_get_default ()); + } + + if (parent_node == NULL) + parent_node = get_root_theme_node (CLUTTER_STAGE (stage)); + + priv->theme_node = shell_theme_node_new (shell_theme_context_get_for_stage (stage), + parent_node, priv->theme, + G_OBJECT_TYPE (widget), + clutter_actor_get_name (CLUTTER_ACTOR (widget)), + priv->style_class, + priv->pseudo_class); + } + + return priv->theme_node; } static gboolean @@ -693,6 +738,7 @@ nbtk_widget_class_init (NbtkWidgetClass *klass) actor_class->hide = nbtk_widget_hide; klass->draw_background = nbtk_widget_real_draw_background; + klass->style_changed = nbtk_widget_real_style_changed; /** * NbtkWidget:pseudo-class: @@ -720,7 +766,19 @@ nbtk_widget_class_init (NbtkWidgetClass *klass) "", NBTK_PARAM_READWRITE)); - g_object_class_override_property (gobject_class, PROP_STYLE, "style"); + /** + * NbtkWidget:theme + * + * A theme set on this actor overriding the global theming for this actor + * and its descendants + */ + g_object_class_install_property (gobject_class, + PROP_THEME, + g_param_spec_object ("theme", + "Theme", + "Theme override", + SHELL_TYPE_THEME, + NBTK_PARAM_READWRITE)); /** * NbtkWidget:stylable: @@ -764,108 +822,66 @@ nbtk_widget_class_init (NbtkWidgetClass *klass) NBTK_PARAM_READWRITE); g_object_class_install_property (gobject_class, PROP_TOOLTIP_TEXT, pspec); + /** + * NbtkWidget::style-changed: + * + * Emitted when the style information that the widget derives from the + * theme changes + */ + signals[STYLE_CHANGED] = + g_signal_new ("style-changed", + G_TYPE_FROM_CLASS (klass), + G_SIGNAL_RUN_LAST, + G_STRUCT_OFFSET (NbtkWidgetClass, style_changed), + NULL, NULL, + _nbtk_marshal_VOID__VOID, + G_TYPE_NONE, 0); } -static NbtkStyle * -nbtk_widget_get_style (NbtkStylable *stylable) +/** + * nbtk_widget_set_theme: + * @actor: a #NbtkWidget + * @theme: a new style class string + * + * Overrides the theme that would be inherited from the actor's parent + * or the stage with an entirely new theme (set of stylesheets). + */ +void +nbtk_widget_set_theme (NbtkWidget *actor, + ShellTheme *theme) { - NbtkWidgetPrivate *priv = NBTK_WIDGET (stylable)->priv; + NbtkWidgetPrivate *priv = actor->priv; - return priv->style; + g_return_if_fail (NBTK_IS_WIDGET (actor)); + + priv = actor->priv; + + if (theme !=priv->theme) + { + if (priv->theme) + g_object_unref (priv->theme); + priv->theme = g_object_ref (priv->theme); + + nbtk_widget_style_changed (actor); + + g_object_notify (G_OBJECT (actor), "theme"); + } } -static void -nbtk_style_changed_cb (NbtkStyle *style, - NbtkStylable *stylable) +/** + * nbtk_widget_get_theme: + * @actor: a #NbtkWidget + * + * Gets the overriding theme set on the actor. See nbtk_widget_set_theme() + * + * Return value: (transfer none): the overriding theme, or %NULL + */ +ShellTheme * +nbtk_widget_get_theme (NbtkWidget *actor) { - nbtk_stylable_changed (stylable); -} + g_return_val_if_fail (NBTK_IS_WIDGET (actor), NULL); - -static void -nbtk_widget_set_style (NbtkStylable *stylable, - NbtkStyle *style) -{ - NbtkWidgetPrivate *priv = NBTK_WIDGET (stylable)->priv; - - if (priv->style) - g_object_unref (priv->style); - - priv->style = g_object_ref_sink (style); - - g_signal_connect (priv->style, - "changed", - G_CALLBACK (nbtk_style_changed_cb), - stylable); -} - -static NbtkStylable* -nbtk_widget_get_container (NbtkStylable *stylable) -{ - ClutterActor *parent; - - g_return_val_if_fail (NBTK_IS_WIDGET (stylable), NULL); - - parent = clutter_actor_get_parent (CLUTTER_ACTOR (stylable)); - - if (NBTK_IS_STYLABLE (parent)) - return NBTK_STYLABLE (parent); - else - return NULL; -} - -static NbtkStylable* -nbtk_widget_get_base_style (NbtkStylable *stylable) -{ - return NULL; -} - -static const gchar* -nbtk_widget_get_style_id (NbtkStylable *stylable) -{ - g_return_val_if_fail (NBTK_IS_WIDGET (stylable), NULL); - - return clutter_actor_get_name (CLUTTER_ACTOR (stylable)); -} - -static const gchar* -nbtk_widget_get_style_type (NbtkStylable *stylable) -{ - return G_OBJECT_TYPE_NAME (stylable); -} - -static const gchar* -nbtk_widget_get_style_class (NbtkStylable *stylable) -{ - g_return_val_if_fail (NBTK_IS_WIDGET (stylable), NULL); - - return NBTK_WIDGET (stylable)->priv->style_class; -} - -static const gchar* -nbtk_widget_get_pseudo_class (NbtkStylable *stylable) -{ - g_return_val_if_fail (NBTK_IS_WIDGET (stylable), NULL); - - return NBTK_WIDGET (stylable)->priv->pseudo_class; -} - -static gboolean -nbtk_widget_get_viewport (NbtkStylable *stylable, - gint *x, - gint *y, - gint *width, - gint *height) -{ - g_return_val_if_fail (NBTK_IS_WIDGET (stylable), FALSE); - - *x = 0; - *y = 0; - - *width = clutter_actor_get_width (CLUTTER_ACTOR (stylable)); - *height = clutter_actor_get_height (CLUTTER_ACTOR (stylable)); - - return TRUE; + return actor->priv->theme; } /** @@ -881,7 +897,7 @@ nbtk_widget_set_style_class_name (NbtkWidget *actor, { NbtkWidgetPrivate *priv = actor->priv; - g_return_if_fail (NBTK_WIDGET (actor)); + g_return_if_fail (NBTK_IS_WIDGET (actor)); priv = actor->priv; @@ -890,7 +906,7 @@ nbtk_widget_set_style_class_name (NbtkWidget *actor, g_free (priv->style_class); priv->style_class = g_strdup (style_class); - nbtk_stylable_changed ((NbtkStylable*) actor); + nbtk_widget_style_changed (actor); g_object_notify (G_OBJECT (actor), "style-class"); } @@ -909,7 +925,7 @@ nbtk_widget_set_style_class_name (NbtkWidget *actor, const gchar* nbtk_widget_get_style_class_name (NbtkWidget *actor) { - g_return_val_if_fail (NBTK_WIDGET (actor), NULL); + g_return_val_if_fail (NBTK_IS_WIDGET (actor), NULL); return actor->priv->style_class; } @@ -926,7 +942,7 @@ nbtk_widget_get_style_class_name (NbtkWidget *actor) const gchar* nbtk_widget_get_style_pseudo_class (NbtkWidget *actor) { - g_return_val_if_fail (NBTK_WIDGET (actor), NULL); + g_return_val_if_fail (NBTK_IS_WIDGET (actor), NULL); return actor->priv->pseudo_class; } @@ -944,7 +960,7 @@ nbtk_widget_set_style_pseudo_class (NbtkWidget *actor, { NbtkWidgetPrivate *priv; - g_return_if_fail (NBTK_WIDGET (actor)); + g_return_if_fail (NBTK_IS_WIDGET (actor)); priv = actor->priv; @@ -953,99 +969,18 @@ nbtk_widget_set_style_pseudo_class (NbtkWidget *actor, g_free (priv->pseudo_class); priv->pseudo_class = g_strdup (pseudo_class); - nbtk_stylable_changed ((NbtkStylable*) actor); + nbtk_widget_style_changed (actor); g_object_notify (G_OBJECT (actor), "pseudo-class"); } } - -static void -nbtk_stylable_iface_init (NbtkStylableIface *iface) -{ - static gboolean is_initialized = FALSE; - - if (!is_initialized) - { - GParamSpec *pspec; - ClutterColor color = { 0x00, 0x00, 0x00, 0xff }; - ClutterColor bg_color = { 0xff, 0xff, 0xff, 0x00 }; - - is_initialized = TRUE; - - pspec = clutter_param_spec_color ("background-color", - "Background Color", - "The background color of an actor", - &bg_color, - G_PARAM_READWRITE); - nbtk_stylable_iface_install_property (iface, NBTK_TYPE_WIDGET, pspec); - - pspec = clutter_param_spec_color ("color", - "Text Color", - "The color of the text of an actor", - &color, - G_PARAM_READWRITE); - nbtk_stylable_iface_install_property (iface, NBTK_TYPE_WIDGET, pspec); - - pspec = g_param_spec_string ("background-image", - "Background Image", - "Background image filename", - NULL, - G_PARAM_READWRITE); - nbtk_stylable_iface_install_property (iface, NBTK_TYPE_WIDGET, pspec); - - pspec = g_param_spec_string ("font-family", - "Font Family", - "Name of the font to use", - "Sans", - G_PARAM_READWRITE); - nbtk_stylable_iface_install_property (iface, NBTK_TYPE_WIDGET, pspec); - - pspec = g_param_spec_int ("font-size", - "Font Size", - "Size of the font to use in pixels", - 0, G_MAXINT, 12, - G_PARAM_READWRITE); - nbtk_stylable_iface_install_property (iface, NBTK_TYPE_WIDGET, pspec); - - pspec = g_param_spec_boxed ("border-image", - "Border image", - "9-slice image to use for drawing borders and background", - NBTK_TYPE_BORDER_IMAGE, - G_PARAM_READWRITE); - nbtk_stylable_iface_install_property (iface, NBTK_TYPE_WIDGET, pspec); - - pspec = g_param_spec_boxed ("padding", - "Padding", - "Padding between the widget's borders " - "and its content", - NBTK_TYPE_PADDING, - G_PARAM_READWRITE); - nbtk_stylable_iface_install_property (iface, NBTK_TYPE_WIDGET, pspec); - - iface->style_changed = nbtk_widget_style_changed; - iface->stylable_changed = nbtk_widget_stylable_changed; - - iface->get_style = nbtk_widget_get_style; - iface->set_style = nbtk_widget_set_style; - iface->get_base_style = nbtk_widget_get_base_style; - iface->get_container = nbtk_widget_get_container; - iface->get_style_id = nbtk_widget_get_style_id; - iface->get_style_type = nbtk_widget_get_style_type; - iface->get_style_class = nbtk_widget_get_style_class; - iface->get_pseudo_class = nbtk_widget_get_pseudo_class; - /* iface->get_attribute = nbtk_widget_get_attribute; */ - iface->get_viewport = nbtk_widget_get_viewport; - } -} - - static void nbtk_widget_name_notify (NbtkWidget *widget, GParamSpec *pspec, gpointer data) { - nbtk_stylable_changed ((NbtkStylable*) widget); + nbtk_widget_style_changed (widget); } static void @@ -1058,44 +993,6 @@ nbtk_widget_init (NbtkWidget *actor) /* connect style changed */ g_signal_connect (actor, "notify::name", G_CALLBACK (nbtk_widget_name_notify), NULL); - - /* set the default style */ - nbtk_widget_set_style (NBTK_STYLABLE (actor), nbtk_style_get_default ()); - -} - -static NbtkBorderImage * -nbtk_border_image_copy (const NbtkBorderImage *border_image) -{ - NbtkBorderImage *copy; - - g_return_val_if_fail (border_image != NULL, NULL); - - copy = g_slice_new (NbtkBorderImage); - *copy = *border_image; - - return copy; -} - -static void -nbtk_border_image_free (NbtkBorderImage *border_image) -{ - if (G_LIKELY (border_image)) - g_slice_free (NbtkBorderImage, border_image); -} - -GType -nbtk_border_image_get_type (void) -{ - static GType our_type = 0; - - if (G_UNLIKELY (our_type == 0)) - our_type = - g_boxed_type_register_static (I_("NbtkBorderImage"), - (GBoxedCopyFunc) nbtk_border_image_copy, - (GBoxedFreeFunc) nbtk_border_image_free); - - return our_type; } /** @@ -1112,11 +1009,11 @@ nbtk_widget_ensure_style (NbtkWidget *widget) if (widget->priv->is_style_dirty) { - g_signal_emit_by_name (widget, "style-changed", 0); + g_signal_emit (widget, signals[STYLE_CHANGED], 0); + widget->priv->is_style_dirty = FALSE; } } - /** * nbtk_widget_get_border_image: * @actor: A #NbtkWidget @@ -1349,6 +1246,5 @@ nbtk_widget_draw_background (NbtkWidget *self) klass = NBTK_WIDGET_GET_CLASS (self); klass->draw_background (NBTK_WIDGET (self), priv->border_image, - priv->bg_color); - + &priv->bg_color); } diff --git a/src/nbtk/nbtk-widget.h b/src/nbtk/nbtk-widget.h index 1f5fe667c..8d367b0fa 100644 --- a/src/nbtk/nbtk-widget.h +++ b/src/nbtk/nbtk-widget.h @@ -29,6 +29,8 @@ #include #include +#include +#include G_BEGIN_DECLS @@ -72,6 +74,7 @@ struct _NbtkWidgetClass void (* draw_background) (NbtkWidget *self, ClutterActor *background, const ClutterColor *color); + void (* style_changed) (NbtkWidget *self); }; GType nbtk_widget_get_type (void) G_GNUC_CONST; @@ -83,6 +86,9 @@ void nbtk_widget_set_style_class_name (NbtkWidget *actor, const gchar *style_class); G_CONST_RETURN gchar *nbtk_widget_get_style_class_name (NbtkWidget *actor); +void nbtk_widget_set_theme (NbtkWidget *actor, + ShellTheme *theme); +ShellTheme *nbtk_widget_get_theme (NbtkWidget *actor); void nbtk_widget_set_has_tooltip (NbtkWidget *widget, gboolean has_tooltip); gboolean nbtk_widget_get_has_tooltip (NbtkWidget *widget); @@ -96,6 +102,10 @@ void nbtk_widget_ensure_style (NbtkWidget *widget); /* Only to be used by sub-classes of NbtkWidget */ +void nbtk_widget_style_changed (NbtkWidget *widget); + +ShellThemeNode *nbtk_widget_get_theme_node (NbtkWidget *widget); + ClutterActor *nbtk_widget_get_background_image (NbtkWidget *actor); ClutterActor *nbtk_widget_get_border_image (NbtkWidget *actor); void nbtk_widget_get_padding (NbtkWidget *widget, diff --git a/tests/Makefile.am b/tests/Makefile.am index 35ba1c76e..ee86ec54b 100644 --- a/tests/Makefile.am +++ b/tests/Makefile.am @@ -16,5 +16,6 @@ run-test.sh: run-test.sh.in $(AM_V_GEN) sed \ -e "s|@GJS_JS_DIR[@]|$(GJS_JS_DIR)|" \ -e "s|@GJS_JS_NATIVE_DIR[@]|$(GJS_JS_NATIVE_DIR)|" \ + -e "s|@MUTTER_LIB_DIR[@]|$(MUTTER_LIB_DIR)|" \ -e "s|@srcdir[@]|$(srcdir)|" \ $< > $@ && chmod a+x $@ diff --git a/tests/interactive/css-fonts.js b/tests/interactive/css-fonts.js new file mode 100644 index 000000000..f0525bbe8 --- /dev/null +++ b/tests/interactive/css-fonts.js @@ -0,0 +1,39 @@ +/* -*- mode: js2; js2-basic-offset: 4; indent-tabs-mode: nil -*- */ + +const Clutter = imports.gi.Clutter; +const Nbtk = imports.gi.Nbtk; + +const UI = imports.testcommon.ui; + +UI.init(); +let stage = Clutter.Stage.get_default(); + +let b = new Nbtk.BoxLayout({ vertical: true, + width: stage.width, + height: stage.height }); +stage.add_actor(b); + +let t; + +t = new Nbtk.Label({ "text": "Bold", style_class: "bold" }); +b.add(t); +t = new Nbtk.Label({ "text": "Monospace", style_class: "monospace" }); +b.add(t); +t = new Nbtk.Label({ "text": "Italic", style_class: "italic" }); +b.add(t); +t = new Nbtk.Label({ "text": "Bold Italic", style_class: "bold italic" }); +b.add(t); +t = new Nbtk.Label({ "text": "Big Italic", style_class: "big italic" }); +b.add(t); +t = new Nbtk.Label({ "text": "Big Bold", style_class: "big bold" }); +b.add(t); + +let b2 = new Nbtk.BoxLayout({ vertical: true, style_class: "monospace" }); +b.add(b2); +t = new Nbtk.Label({ "text": "Big Monospace", style_class: "big" }); +b2.add(t); +t = new Nbtk.Label({ "text": "Italic Monospace", style_class: "italic" }); +b2.add(t); + +stage.show(); +Clutter.main(); diff --git a/tests/interactive/scrolling.js b/tests/interactive/scrolling.js new file mode 100644 index 000000000..c1e3d56d9 --- /dev/null +++ b/tests/interactive/scrolling.js @@ -0,0 +1,28 @@ +/* -*- mode: js2; js2-basic-offset: 4; indent-tabs-mode: nil -*- */ + +const Clutter = imports.gi.Clutter; +const Nbtk = imports.gi.Nbtk; + +const UI = imports.testcommon.ui; + +UI.init(); +let stage = Clutter.Stage.get_default(); + +let v = new Nbtk.ScrollView({}); +stage.add_actor(v); +let b = new Nbtk.BoxLayout({ vertical: true, + width: stage.width, + height: stage.height }); +v.add_actor(b); + +let cc_a = "a".charCodeAt(0); +let s = ""; +for (let i = 0; i < 26 * 3; i++) { + s += String.fromCharCode(cc_a + i % 26); + + let t = new Nbtk.Label({ "text": s}); + b.add(t); +} + +stage.show(); +Clutter.main(); diff --git a/tests/run-test.sh.in b/tests/run-test.sh.in index ce1ce3e3b..4436187d8 100644 --- a/tests/run-test.sh.in +++ b/tests/run-test.sh.in @@ -26,7 +26,7 @@ builddir=`cd $builddir && pwd` srcdir=$builddir/@srcdir@ srcdir=`cd $srcdir && pwd` -GI_TYPELIB_PATH="$builddir/../src" +GI_TYPELIB_PATH="@MUTTER_LIB_DIR@/mutter:$builddir/../src" GJS_DEBUG_OUTPUT=stderr $verbose || GJS_DEBUG_TOPICS="JS ERROR;JS LOG" GNOME_SHELL_TESTSDIR="$srcdir/" diff --git a/tests/testcommon/test.css b/tests/testcommon/test.css index 0e1b3ace7..6ce3d5dc0 100644 --- a/tests/testcommon/test.css +++ b/tests/testcommon/test.css @@ -1,13 +1,33 @@ @import "../../data/theme/gnome-shell.css"; -*.red { +stage { + font: 16pt serif; +} + +.red { background-color: red; } -*.green { +.green { background-color: green; } -*.blue { +.blue { background-color: blue; } + +.bold { + font-weight: bold; +} + +.italic { + font-style: italic; +} + +.big { + font-size: 150%; +} + +.monospace { + font-family: monospace; +} diff --git a/tests/testcommon/ui.js b/tests/testcommon/ui.js index e6ea34eba..fdae57f96 100644 --- a/tests/testcommon/ui.js +++ b/tests/testcommon/ui.js @@ -3,6 +3,7 @@ const Clutter = imports.gi.Clutter; const GLib = imports.gi.GLib; const Nbtk = imports.gi.Nbtk; +const Shell = imports.gi.Shell; const Environment = imports.ui.environment; @@ -10,7 +11,9 @@ function init() { Clutter.init(null, null); Environment.init(); - let style = Nbtk.Style.get_default(); + let stage = Clutter.Stage.get_default(); + let context = Shell.ThemeContext.get_for_stage (stage); let stylesheetPath = GLib.getenv("GNOME_SHELL_TESTSDIR") + "/testcommon/test.css"; - style.load_from_file(stylesheetPath); + let theme = new Shell.Theme ({ application_stylesheet: stylesheetPath }); + context.set_theme (theme); }