diff options
-rw-r--r-- | docs/reference/endless/Makefile.am | 2 | ||||
-rw-r--r-- | docs/reference/endless/endless-docs.xml | 1 | ||||
-rw-r--r-- | docs/reference/endless/endless-sections.txt | 5 | ||||
-rw-r--r-- | endless/Makefile.am | 4 | ||||
-rw-r--r-- | endless/eosactionbutton-private.h | 73 | ||||
-rw-r--r-- | endless/eosactionbutton.c | 559 | ||||
-rw-r--r-- | endless/eosenums.h | 28 | ||||
-rw-r--r-- | test/smoke-tests/action-buttons.js | 59 | ||||
-rw-r--r-- | test/smoke-tests/eosactionbutton.css | 56 |
9 files changed, 785 insertions, 2 deletions
diff --git a/docs/reference/endless/Makefile.am b/docs/reference/endless/Makefile.am index a90030d..da09231 100644 --- a/docs/reference/endless/Makefile.am +++ b/docs/reference/endless/Makefile.am @@ -49,7 +49,7 @@ EXTRA_HFILES= # Header files or dirs to ignore when scanning. Use base file/dir names # e.g. IGNORE_HFILES=gtkdebug.h gtkintl.h private_code -IGNORE_HFILES= eosinit-private.h eostopbar-private.h eosmainarea-private.h +IGNORE_HFILES= eosinit-private.h eostopbar-private.h eosmainarea-private.h eosactionbutton-private.h # Images to copy into HTML directory. # e.g. HTML_IMAGES=$(top_srcdir)/gtk/stock-icons/stock_about_24.png diff --git a/docs/reference/endless/endless-docs.xml b/docs/reference/endless/endless-docs.xml index 38d4ae3..0ae881f 100644 --- a/docs/reference/endless/endless-docs.xml +++ b/docs/reference/endless/endless-docs.xml @@ -20,6 +20,7 @@ <xi:include href="xml/application.xml"/> <xi:include href="xml/window.xml"/> <xi:include href="xml/page-manager.xml"/> + <xi:include href="xml/enums.xml"/> <!--<xi:include href="xml/hello.xml"/>--> </chapter> diff --git a/docs/reference/endless/endless-sections.txt b/docs/reference/endless/endless-sections.txt index fdb4b04..6b40e61 100644 --- a/docs/reference/endless/endless-sections.txt +++ b/docs/reference/endless/endless-sections.txt @@ -77,3 +77,8 @@ eos_page_manager_transition_type_get_type <SUBSECTION Private> EosPageManagerPrivate </SECTION> + +<SECTION> +<FILE>enums</FILE> +EosActionButtonSize +</SECTION> diff --git a/endless/Makefile.am b/endless/Makefile.am index 5333206..48712dd 100644 --- a/endless/Makefile.am +++ b/endless/Makefile.am @@ -9,7 +9,8 @@ endless_private_installed_headers = \ endless/eosmacros.h \ endless/eospagemanager.h \ endless/eostypes.h \ - endless/eoswindow.h + endless/eoswindow.h \ + endless/eosactionbutton-private.h endless_library_sources = \ endless/eosapplication.c \ @@ -18,6 +19,7 @@ endless_library_sources = \ endless/eospagemanager.c \ endless/eosmainarea.c endless/eosmainarea-private.h \ endless/eostopbar.c endless/eostopbar-private.h \ + endless/eosactionbutton.c \ endless/eoswindow.c # Endless GUI library diff --git a/endless/eosactionbutton-private.h b/endless/eosactionbutton-private.h new file mode 100644 index 0000000..27dcb62 --- /dev/null +++ b/endless/eosactionbutton-private.h @@ -0,0 +1,73 @@ +/* Copyright 2013 Endless Mobile, Inc. */ + +#ifndef EOS_ACTION_BUTTON_H +#define EOS_ACTION_BUTTON_H + +#include "eostypes.h" + +#include <gtk/gtk.h> + +G_BEGIN_DECLS + +#define EOS_TYPE_ACTION_BUTTON eos_action_button_get_type() + +#define EOS_ACTION_BUTTON(obj) \ + (G_TYPE_CHECK_INSTANCE_CAST ((obj), \ + EOS_TYPE_ACTION_BUTTON, EosActionButton)) + +#define EOS_ACTION_BUTTON_CLASS(klass) \ + (G_TYPE_CHECK_CLASS_CAST ((klass), \ + EOS_TYPE_ACTION_BUTTON, EosActionButtonClass)) + +#define EOS_IS_ACTION_BUTTON(obj) \ + (G_TYPE_CHECK_INSTANCE_TYPE ((obj), \ + EOS_TYPE_ACTION_BUTTON)) + +#define EOS_IS_ACTION_BUTTON_CLASS(klass) \ + (G_TYPE_CHECK_CLASS_TYPE ((klass), \ + EOS_TYPE_ACTION_BUTTON)) + +#define EOS_ACTION_BUTTON_GET_CLASS(obj) \ + (G_TYPE_INSTANCE_GET_CLASS ((obj), \ + EOS_TYPE_ACTION_BUTTON, EosActionButtonClass)) + +typedef struct _EosActionButton EosActionButton; +typedef struct _EosActionButtonClass EosActionButtonClass; +typedef struct _EosActionButtonPrivate EosActionButtonPrivate; + +struct _EosActionButton +{ + GtkButton parent; + + EosActionButtonPrivate *priv; +}; + +struct _EosActionButtonClass +{ + GtkButtonClass parent_class; +}; + +GType eos_action_button_get_type (void) G_GNUC_CONST; + +GtkWidget *eos_action_button_new (EosActionButtonSize size, + const gchar *label, + const gchar *icon_id); + +void eos_action_button_set_size (EosActionButton *button, + EosActionButtonSize size); + +EosActionButtonSize eos_action_button_get_size (EosActionButton *button); + +void eos_action_button_set_label (EosActionButton *button, + const gchar *label); + +const gchar *eos_action_button_get_label (EosActionButton *button); + +void eos_action_button_set_icon_id (EosActionButton *button, + const gchar *stock_id); + +const gchar *eos_action_button_get_icon_id (EosActionButton *button); + +G_END_DECLS + +#endif /* EOS_ACTION_BUTTON_H */ diff --git a/endless/eosactionbutton.c b/endless/eosactionbutton.c new file mode 100644 index 0000000..14106d4 --- /dev/null +++ b/endless/eosactionbutton.c @@ -0,0 +1,559 @@ +/* Copyright 2013 Endless Mobile, Inc. */ + +#include "config.h" +#include "eosactionbutton-private.h" + +#include <glib-object.h> +#include <gtk/gtk.h> +#include <math.h> + +#define _EOS_STYLE_CLASS_ACTION_BUTTON "action-button" + +G_DEFINE_TYPE (EosActionButton, eos_action_button, GTK_TYPE_BUTTON) + +#define EOS_ACTION_BUTTON_PRIVATE(o) \ + (G_TYPE_INSTANCE_GET_PRIVATE ((o), EOS_TYPE_ACTION_BUTTON, EosActionButtonPrivate)) + +struct _EosActionButtonPrivate +{ + /* properties */ + EosActionButtonSize size; + gchar *label; + gchar *icon_id; + + /* internal */ + GtkWidget *grid; + GtkWidget *icon_image; + GdkPixbuf *icon_pixbuf; + GtkWidget *label_widget; +}; + +typedef struct _EosActionButtonSizeDefinition EosActionButtonSizeDefinition; + +struct _EosActionButtonSizeDefinition +{ + EosActionButtonSize size; + gchar *name; + + gint width; + gint height; + gint icon_size; + gint border_width; +}; + +static EosActionButtonSizeDefinition *icon_sizes = NULL; + + +enum { + PROP_0, + PROP_SIZE, + PROP_LABEL, + PROP_ICON_ID +}; + +static void +eos_action_button_dispose (GObject *object); + +static void +eos_action_button_finalize (GObject *object); + +static void +eos_action_button_get_property (GObject *object, + guint property_id, + GValue *value, + GParamSpec *pspec); + +static void +eos_action_button_set_property (GObject *object, + guint property_id, + const GValue *value, + GParamSpec *pspec); + +static void +eos_action_button_get_preferred_width (GtkWidget *widget, + gint *minimum_size, + gint *natural_size); + +static void +eos_action_button_get_preferred_height (GtkWidget *widget, + gint *minimum_size, + gint *natural_size); + +static gboolean +eos_action_button_draw (GtkWidget *widget, + cairo_t *cr); + +/* ******* INIT ******* */ + +static void +eos_action_button_class_init (EosActionButtonClass *klass) +{ + GObjectClass *object_class = G_OBJECT_CLASS (klass); + GtkWidgetClass *widget_class = GTK_WIDGET_CLASS (klass); + + g_type_class_add_private (klass, sizeof (EosActionButtonPrivate)); + + object_class->get_property = eos_action_button_get_property; + object_class->set_property = eos_action_button_set_property; + object_class->dispose = eos_action_button_dispose; + object_class->finalize = eos_action_button_finalize; + + widget_class->draw = eos_action_button_draw; + widget_class->get_preferred_width = eos_action_button_get_preferred_width; + widget_class->get_preferred_height = eos_action_button_get_preferred_height; + + g_object_class_install_property (object_class, + PROP_SIZE, + g_param_spec_int ("size", + "Size", + "Size of the button", + EOS_ACTION_BUTTON_SIZE_PRIMARY, + EOS_ACTION_BUTTON_SIZE_QUATERNARY, + EOS_ACTION_BUTTON_SIZE_SECONDARY, + G_PARAM_READWRITE | G_PARAM_CONSTRUCT)); + + g_object_class_install_property (object_class, + PROP_LABEL, + g_param_spec_string ("label", + "Label", + "Text of the label widget beneath the button", + NULL, + G_PARAM_READWRITE | G_PARAM_CONSTRUCT)); + + g_object_class_install_property (object_class, + PROP_ICON_ID, + g_param_spec_string ("icon-id", + "Icon id", + "ID used to pick an icon for the button", + NULL, + G_PARAM_READWRITE | G_PARAM_CONSTRUCT)); + + // init icon sizes, inspired by gtkiconfactory.c + if (icon_sizes == NULL) + { + icon_sizes = g_new (EosActionButtonSizeDefinition, EOS_ACTION_BUTTON_SIZE_NUM_SIZES); + + icon_sizes[EOS_ACTION_BUTTON_SIZE_PRIMARY].size = EOS_ACTION_BUTTON_SIZE_PRIMARY; + icon_sizes[EOS_ACTION_BUTTON_SIZE_PRIMARY].name = "primary"; + icon_sizes[EOS_ACTION_BUTTON_SIZE_PRIMARY].width = 64; + icon_sizes[EOS_ACTION_BUTTON_SIZE_PRIMARY].height = 64; + icon_sizes[EOS_ACTION_BUTTON_SIZE_PRIMARY].icon_size = 36; + icon_sizes[EOS_ACTION_BUTTON_SIZE_PRIMARY].border_width = 8; + + icon_sizes[EOS_ACTION_BUTTON_SIZE_SECONDARY].size = EOS_ACTION_BUTTON_SIZE_SECONDARY; + icon_sizes[EOS_ACTION_BUTTON_SIZE_SECONDARY].name = "secondary"; + icon_sizes[EOS_ACTION_BUTTON_SIZE_SECONDARY].width = 48; + icon_sizes[EOS_ACTION_BUTTON_SIZE_SECONDARY].height = 48; + icon_sizes[EOS_ACTION_BUTTON_SIZE_SECONDARY].icon_size = 26; + icon_sizes[EOS_ACTION_BUTTON_SIZE_SECONDARY].border_width = 6; + + icon_sizes[EOS_ACTION_BUTTON_SIZE_TERTIARY].size = EOS_ACTION_BUTTON_SIZE_TERTIARY; + icon_sizes[EOS_ACTION_BUTTON_SIZE_TERTIARY].name = "tertiary"; + icon_sizes[EOS_ACTION_BUTTON_SIZE_TERTIARY].width = 36; + icon_sizes[EOS_ACTION_BUTTON_SIZE_TERTIARY].height = 36; + icon_sizes[EOS_ACTION_BUTTON_SIZE_TERTIARY].icon_size = 18; + icon_sizes[EOS_ACTION_BUTTON_SIZE_TERTIARY].border_width = 5; + + icon_sizes[EOS_ACTION_BUTTON_SIZE_QUATERNARY].size = EOS_ACTION_BUTTON_SIZE_QUATERNARY; + icon_sizes[EOS_ACTION_BUTTON_SIZE_QUATERNARY].name = "quaternary"; + icon_sizes[EOS_ACTION_BUTTON_SIZE_QUATERNARY].width = 26; + icon_sizes[EOS_ACTION_BUTTON_SIZE_QUATERNARY].height = 26; + icon_sizes[EOS_ACTION_BUTTON_SIZE_QUATERNARY].icon_size = 12; + icon_sizes[EOS_ACTION_BUTTON_SIZE_QUATERNARY].border_width = 4; + } +} + +static void +eos_action_button_init (EosActionButton *self) +{ + EosActionButtonPrivate *priv; + GtkStyleContext *context; + + self->priv = EOS_ACTION_BUTTON_PRIVATE (self); + priv = self->priv; + + context = gtk_widget_get_style_context (GTK_WIDGET (self)); + gtk_style_context_add_class (context, _EOS_STYLE_CLASS_ACTION_BUTTON); + + priv->icon_image = gtk_image_new(); + priv->label_widget = GTK_WIDGET (gtk_label_new ("")); + + priv->grid = gtk_grid_new (); + gtk_grid_attach(GTK_GRID (priv->grid), priv->icon_image, 0, 0, 1, 1); + gtk_grid_attach(GTK_GRID (priv->grid), priv->label_widget, 0, 1, 1, 1); + + gtk_container_add (GTK_CONTAINER (self), + GTK_WIDGET (priv->grid)); + + // TODO positioning is not really working right, it will be done manually in draw () + + gtk_widget_set_hexpand (GTK_WIDGET(self), FALSE); + gtk_widget_set_halign (GTK_WIDGET(self), GTK_ALIGN_CENTER); + gtk_widget_set_vexpand (GTK_WIDGET(self), FALSE); + gtk_widget_set_valign (GTK_WIDGET(self), GTK_ALIGN_CENTER); +} + +/* ******* LIFECYCLE ******* */ + +GtkWidget * +eos_action_button_new (EosActionButtonSize size, + const gchar *label, + const gchar *icon_id) +{ + return g_object_new (EOS_TYPE_ACTION_BUTTON, + "size", size, + "label", label, + "icon-id", icon_id, + NULL); +} + +static void +eos_action_button_dispose (GObject *object) +{ + G_OBJECT_CLASS (eos_action_button_parent_class)->dispose (object); +} + +static void +eos_action_button_finalize (GObject *object) +{ + G_OBJECT_CLASS (eos_action_button_parent_class)->finalize (object); +} + +/* ******* PROPERTIES ******* */ + +static void +eos_action_button_load_icon (EosActionButton *button) +{ + EosActionButtonPrivate *priv; + GtkIconInfo *icon_info; + GdkPixbuf *new_icon = NULL; + gboolean was_symbolic = TRUE; + GError *error = NULL; + + g_return_if_fail (EOS_IS_ACTION_BUTTON (button)); + + priv = button->priv; + + // TODO maybe use gtk_image_set_from_icon_set + + if (priv->icon_id != NULL) + { + icon_info = gtk_icon_theme_lookup_icon (gtk_icon_theme_get_default (), + priv->icon_id, + icon_sizes[priv->size].icon_size, + GTK_ICON_LOOKUP_FORCE_SIZE + | GTK_ICON_LOOKUP_GENERIC_FALLBACK + | GTK_ICON_LOOKUP_USE_BUILTIN ); + + new_icon = gtk_icon_info_load_symbolic_for_context (icon_info, + gtk_widget_get_style_context (GTK_WIDGET(button)), + &was_symbolic, + &error); + + if (!was_symbolic) + { + g_warning ("Icon for %s is not symbolic\n", priv->icon_id); + } + if (error != NULL) + { + g_warning ("Unable to load icon for %s : %s\n", priv->icon_id, error->message); + g_error_free (error); + } + g_object_ref (new_icon); + g_object_unref (icon_info); + } + else + { + new_icon = NULL; + } + + if (priv->icon_pixbuf != NULL) + { + g_object_unref (priv->icon_pixbuf); + } + + priv->icon_pixbuf = new_icon; + + gtk_image_set_from_pixbuf (GTK_IMAGE (priv->icon_image), priv->icon_pixbuf); +} + +void +eos_action_button_set_size (EosActionButton *button, + EosActionButtonSize size) +{ + EosActionButtonPrivate *priv; + int old_size; + + g_return_if_fail (EOS_IS_ACTION_BUTTON (button)); + + priv = button->priv; + + old_size = priv->size; + priv->size = size; + + // remove the old style class and set the new one + GtkStyleContext *context = gtk_widget_get_style_context (GTK_WIDGET (button)); + gtk_style_context_remove_class (context, icon_sizes[old_size].name); + gtk_style_context_add_class (context, icon_sizes[priv->size].name); + + if (old_size != priv->size) + { + eos_action_button_load_icon (button); + + g_object_notify (G_OBJECT (button), "size"); + gtk_widget_queue_resize(GTK_WIDGET (button)); + } +} + +EosActionButtonSize +eos_action_button_get_size (EosActionButton *button) +{ + EosActionButtonPrivate *priv; + + g_return_val_if_fail (EOS_IS_ACTION_BUTTON (button), -1); + + priv = button->priv; + + return priv->size; +} + +void +eos_action_button_set_label (EosActionButton *button, const gchar *label) +{ + EosActionButtonPrivate *priv; + gchar *new_label; + + g_return_if_fail (EOS_IS_ACTION_BUTTON (button)); + + priv = button->priv; + new_label = g_strdup (label); + g_free (priv->label); + priv->label = new_label; + + gtk_label_set_text (GTK_LABEL (priv->label_widget), priv->label); + + g_object_notify (G_OBJECT (button), "label"); +} + +const gchar * +eos_action_button_get_label (EosActionButton *button) +{ + EosActionButtonPrivate *priv; + + g_return_val_if_fail (EOS_IS_ACTION_BUTTON (button), NULL); + + priv = button->priv; + + return priv->label; +} + +void +eos_action_button_set_icon_id (EosActionButton *button, + const gchar* icon_id) +{ + EosActionButtonPrivate *priv; + + g_return_if_fail (EOS_IS_ACTION_BUTTON (button)); + priv = button->priv; + + if (g_strcmp0 (icon_id, priv->icon_id) != 0) + { + g_free (priv->icon_id); + priv->icon_id = g_strdup (icon_id); + + eos_action_button_load_icon (button); + g_object_notify (G_OBJECT (button), "icon-id"); + } +} + +const gchar * +eos_action_button_get_icon_id (EosActionButton *button) +{ + g_return_val_if_fail (EOS_IS_ACTION_BUTTON (button), NULL); + + return button->priv->icon_id; +} + +static void +eos_action_button_get_property (GObject *object, + guint property_id, + GValue *value, + GParamSpec *pspec) +{ + EosActionButton *button = EOS_ACTION_BUTTON (object); + EosActionButtonPrivate *priv = button->priv; + + switch (property_id) + { + case PROP_SIZE: + g_value_set_int (value, priv->size); + break; + case PROP_LABEL: + g_value_set_string (value, priv->label); + break; + case PROP_ICON_ID: + g_value_set_string (value, priv->icon_id); + break; + default: + G_OBJECT_WARN_INVALID_PROPERTY_ID (object, property_id, pspec); + } +} + +static void +eos_action_button_set_property (GObject *object, + guint property_id, + const GValue *value, + GParamSpec *pspec) +{ + EosActionButton *button = EOS_ACTION_BUTTON (object); + + switch (property_id) + { + case PROP_SIZE : + eos_action_button_set_size (button, g_value_get_int (value)); + break; + case PROP_LABEL : + eos_action_button_set_label (button, g_value_get_string (value)); + break; + case PROP_ICON_ID : + eos_action_button_set_icon_id (button, g_value_get_string (value)); + break; + default: + G_OBJECT_WARN_INVALID_PROPERTY_ID (object, property_id, pspec); + } +} + +/* ******* EXTENDED METHODS ******* */ + +static void +eos_action_button_get_real_size (GtkWidget *widget, + GtkOrientation orientation, + gint *minimum_size, + gint *natural_size) +{ + EosActionButton *button = EOS_ACTION_BUTTON (widget); + EosActionButtonPrivate *priv = button->priv; + GtkBorder margin; + GtkAllocation label_allocation; + GtkStyleContext *context = gtk_widget_get_style_context (widget); + + gtk_style_context_get_margin(context, + gtk_style_context_get_state (context), + &margin); + + gtk_widget_get_allocation (priv->label_widget, &label_allocation); + + if (minimum_size && orientation == GTK_ORIENTATION_HORIZONTAL) + *minimum_size = MAX (icon_sizes[priv->size].width + margin.left + margin.right, + label_allocation.width); + + if (minimum_size && orientation == GTK_ORIENTATION_VERTICAL) + *minimum_size = margin.top + icon_sizes[priv->size].height + margin.bottom + + label_allocation.height + margin.bottom; + + if (natural_size && orientation == GTK_ORIENTATION_HORIZONTAL) + *natural_size = MAX (icon_sizes[priv->size].width + margin.left + margin.right, + label_allocation.width); + + if (natural_size && orientation == GTK_ORIENTATION_VERTICAL) + *natural_size = margin.top + icon_sizes[priv->size].height + margin.bottom + + label_allocation.height + margin.bottom; +} + +static void +eos_action_button_get_preferred_width (GtkWidget *widget, + gint *minimum_size, + gint *natural_size) +{ + eos_action_button_get_real_size (widget, GTK_ORIENTATION_HORIZONTAL, + minimum_size, natural_size); +} + +static void +eos_action_button_get_preferred_height (GtkWidget *widget, + gint *minimum_size, + gint *natural_size) +{ + eos_action_button_get_real_size (widget, GTK_ORIENTATION_VERTICAL, + minimum_size, natural_size); +} + +static gboolean +eos_action_button_draw (GtkWidget *widget, + cairo_t *cr) +{ + EosActionButton *button = EOS_ACTION_BUTTON (widget); + EosActionButtonPrivate *priv = button->priv; + gint x, y; + gint focus_width; + gint focus_pad; + GtkAllocation allocation; + GtkStyleContext *context; + GtkStateFlags state; + gint width, height, border_width, border_height; + GtkBorder margin; + + context = gtk_widget_get_style_context (widget); + state = gtk_style_context_get_state (context); + + gtk_style_context_get_style (context, + "focus-line-width", &focus_width, + "focus-padding", &focus_pad, + NULL); + + gtk_style_context_get_margin(context, + state, + &margin); + + gtk_widget_get_allocation (widget, &allocation); + + x = 0; + y = 0; + width = allocation.width; + height = allocation.height; + + border_width = icon_sizes[priv->size].width; + border_height = icon_sizes[priv->size].height; + + cairo_save (cr); + + gtk_render_frame (context, cr, + x + (width - border_width)/2, + margin.top, + border_width, border_height); + + if (gtk_widget_has_visible_focus (widget)) + { + gtk_render_focus (context, cr, + x, y, width, height); + } + + // TODO is it really needed to restore and save the cairo_t here? + cairo_restore (cr); + cairo_save (cr); + + // *** image + + gtk_widget_get_allocation (priv->icon_image, &allocation); + cairo_translate (cr, + (width - allocation.width) / 2, + margin.top + (icon_sizes[priv->size].height - allocation.height) / 2); + + gtk_widget_draw (GTK_WIDGET (priv->icon_image), cr); + + // TODO same as previous + cairo_restore (cr); + cairo_save (cr); + + // *** label + + gtk_widget_get_allocation (priv->label_widget, &allocation); + cairo_translate (cr, x + (width - allocation.width)/2, + margin.top + icon_sizes[priv->size].height + margin.bottom); + + gtk_widget_draw (GTK_WIDGET (priv->label_widget), cr); + + cairo_restore (cr); + + return FALSE; +} diff --git a/endless/eosenums.h b/endless/eosenums.h index c5a88ae..873213d 100644 --- a/endless/eosenums.h +++ b/endless/eosenums.h @@ -9,4 +9,32 @@ /* Shared typedefs for enumerations */ +/** + * SECTION:enums + * @Short_description: Public enumerated types used throughout the Endless SDK + * @Title: Standard Enumerations + * + * Public enumerated types used throughout the Endless SDK. + */ + +/** + * EosActionButtonSize: + * @EOS_ACTION_BUTTON_SIZE_PRIMARY: size for primary buttons + * @EOS_ACTION_BUTTON_SIZE_SECONDARY: size for secondary buttons + * @EOS_ACTION_BUTTON_SIZE_TERTIARY: size for tertiary buttons + * @EOS_ACTION_BUTTON_SIZE_QUATERNARY: size for quaternary buttons + * @EOS_ACTION_BUTTON_SIZE_NUM_SIZES: total number of sizes + * + * Built-in sizes for internal action buttons. + */ +typedef enum +{ + EOS_ACTION_BUTTON_SIZE_PRIMARY = 0, + EOS_ACTION_BUTTON_SIZE_SECONDARY, + EOS_ACTION_BUTTON_SIZE_TERTIARY, + EOS_ACTION_BUTTON_SIZE_QUATERNARY, + EOS_ACTION_BUTTON_SIZE_NUM_SIZES +} EosActionButtonSize; + + #endif /* EOS_ENUMS_H */ diff --git a/test/smoke-tests/action-buttons.js b/test/smoke-tests/action-buttons.js new file mode 100644 index 0000000..04e3ae9 --- /dev/null +++ b/test/smoke-tests/action-buttons.js @@ -0,0 +1,59 @@ +// Copyright 2013 Endless Mobile, Inc. + +const Lang = imports.lang; +const Endless = imports.gi.Endless; +const Gtk = imports.gi.Gtk; + +const TEST_APPLICATION_ID = 'com.endlessm.example.test-action-buttons'; + +const TestApplication = new Lang.Class ({ + Name: 'TestApplication', + Extends: Endless.Application, + + vfunc_startup: function() { + this.parent(); + + this._page = new Gtk.Grid(); + + /* should be using Endless.EOS_ACTION_BUTTON_SIZE_PRIMARY */ + + this._eosButton0 = new Endless.ActionButton({size: 0, label: 'SMILE', 'icon-id': 'face-smile-symbolic' }); + this._page.attach(this._eosButton0, 0, 0, 1, 1); + + this._eosButton1 = new Endless.ActionButton({size: 1, label: 'POUT', 'icon-id': 'face-sad-symbolic' }); + this._page.attach(this._eosButton1, 0, 1, 1, 1); + + this._eosButton2 = new Endless.ActionButton({size: 2, label: '', 'icon-id': 'edit-delete-symbolic' }); + this._page.attach(this._eosButton2, 0, 2, 1, 1); + + this._eosButton3 = new Endless.ActionButton({size: 3, label: '', 'icon-id': 'object-select-symbolic' }); + this._page.attach(this._eosButton3, 0, 3, 1, 1); + + this._pm = new Endless.PageManager(); + this._pm.add(this._page, { name: "page" }); + + let provider = new Gtk.CssProvider (); + provider.load_from_path ('./test/smoke-tests/eosactionbutton.css'); + + this._window = new Endless.Window({ + application: this, + border_width: 16, + page_manager: this._pm + }); + + let context = new Gtk.StyleContext(); + context.add_provider_for_screen(this._window.get_screen(), + provider, + Gtk.STYLE_PROVIDER_PRIORITY_USER); + + this._window.show_all(); + }, + + _onButtonClicked: function () { + this._window.destroy(); + }, +}); + +let app = new TestApplication({ application_id: TEST_APPLICATION_ID, + flags: 0 }); +app.run(ARGV); diff --git a/test/smoke-tests/eosactionbutton.css b/test/smoke-tests/eosactionbutton.css new file mode 100644 index 0000000..6fd657b --- /dev/null +++ b/test/smoke-tests/eosactionbutton.css @@ -0,0 +1,56 @@ +EosActionButton { + background-color: transparent; + border-color: #012345; + border-radius: 32px; + border-width: 8px; + border-style: solid; + margin: 10px; +} + +/* ****** SIZES ****** */ + +EosActionButton.primary { + border-radius: 32px; + border-width: 8px; +} + +EosActionButton.secondary { + border-radius: 24px; + border-width: 6px; +} + +EosActionButton.tertiary { + border-radius: 18px; + border-width: 5px; +} + +EosActionButton.quaternary { + border-radius: 13px; + border-width: 4px; +} + +/* ****** STATES ****** */ + +EosActionButton:active { + border-color: #123456; +} + +EosActionButton:hover { + border-color: #234567; +} + +EosActionButton:insensitive { + border-color: #345678; +} + +EosActionButton:selected { + border-color: #456789; +} + +EosActionButton:focused { + border-color: #56789A; +} + +EosActionButton:inconsistent { + border-color: #6789AB; +} |