From db0c2b5959ac8a326e27430fede4c198b72bce65 Mon Sep 17 00:00:00 2001 From: "Owen W. Taylor" Date: Sat, 19 Sep 2009 21:10:15 -0400 Subject: [PATCH] Port our imported parts of Nbtk to ShellTheme ShellTheme replaces both NbtkStyle and ccss_stylesheet_t. The interface NbtkStylable is replaced by usage of ShellThemeNode. A concrete node class allows some significant optimizations of property inheritance that would have been much more difficult to achieve with the highly abstract pair of NbtkStylable and ccss_node_t. Some operations that were previously on NbtkStylable (like the ::style-changed signal) are directly on NtkWidget. Custom properties are no longer registered as param-specs; instead you call directly into shell theme node to look up a length or color: shell_theme_node_get_length (theme_node, "border-spacing", FALSE, &spacing); The dependency on libccss is dropped, while preserving all existing functionality and adding proper parsing and inheritance of font properties and proper inheritance for the 'color' property. Some more javascript tests for CSS functionality are added; workarounds for a CSS bug where *.some-class was needed instead of .some-class are removed. --- configure.ac | 2 +- data/theme/gnome-shell.css | 16 +- js/ui/main.js | 5 +- src/Makefile-nbtk.am | 4 - src/Makefile.am | 28 +- src/nbtk/nbtk-bin.c | 1 - src/nbtk/nbtk-button.c | 131 ++--- src/nbtk/nbtk-entry.c | 102 +--- src/nbtk/nbtk-label.c | 53 +- src/nbtk/nbtk-scroll-bar.c | 62 +-- src/nbtk/nbtk-scroll-view.c | 88 ++-- src/nbtk/nbtk-stylable.c | 849 --------------------------------- src/nbtk/nbtk-stylable.h | 123 ----- src/nbtk/nbtk-style.c | 742 ---------------------------- src/nbtk/nbtk-style.h | 94 ---- src/nbtk/nbtk-tooltip.c | 49 +- src/nbtk/nbtk-types.h | 3 - src/nbtk/nbtk-widget.c | 550 +++++++++------------ src/nbtk/nbtk-widget.h | 10 + tests/Makefile.am | 1 + tests/interactive/css-fonts.js | 39 ++ tests/interactive/scrolling.js | 28 ++ tests/run-test.sh.in | 2 +- tests/testcommon/test.css | 26 +- tests/testcommon/ui.js | 7 +- 25 files changed, 502 insertions(+), 2513 deletions(-) delete mode 100644 src/nbtk/nbtk-stylable.c delete mode 100644 src/nbtk/nbtk-stylable.h delete mode 100644 src/nbtk/nbtk-style.c delete mode 100644 src/nbtk/nbtk-style.h create mode 100644 tests/interactive/css-fonts.js create mode 100644 tests/interactive/scrolling.js 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); }