diff options
author | Felipe Erias Morandeira <femorandeira@igalia.com> | 2013-07-23 14:45:33 +0100 |
---|---|---|
committer | Felipe Erias Morandeira <femorandeira@igalia.com> | 2013-07-23 14:45:33 +0100 |
commit | efe88dcaa0d62ee01557c48b7864ba3ba34245f6 (patch) | |
tree | 8ec4a94a4b16c70c46e55f799802425aafc85895 | |
parent | a2adbcc4cad5f5219d59247ccdfc5de6d281a63d (diff) |
EosActionMenu places cancel, close and delete actions at the bottom. Internally, it uses a GtkOverlay to correctly position the two sets of actions.
[endlessm/eos-sdk#146]
-rw-r--r-- | endless/eosactionmenu.c | 67 | ||||
-rw-r--r-- | test/test-action-menu.c | 26 |
2 files changed, 71 insertions, 22 deletions
diff --git a/endless/eosactionmenu.c b/endless/eosactionmenu.c index 18468dd..0f45305 100644 --- a/endless/eosactionmenu.c +++ b/endless/eosactionmenu.c @@ -24,7 +24,10 @@ G_DEFINE_TYPE (EosActionMenu, eos_action_menu, GTK_TYPE_FRAME) struct _EosActionMenuPrivate { - GtkWidget *grid; + GtkWidget *overlay; + GtkWidget *center_grid; + GtkWidget *bottom_grid; + GtkActionGroup *action_group; }; @@ -59,15 +62,38 @@ eos_action_menu_init (EosActionMenu *self) context = gtk_widget_get_style_context (GTK_WIDGET (self)); gtk_style_context_add_class (context, _EOS_STYLE_CLASS_ACTION_MENU); - priv->grid = gtk_grid_new (); - g_object_set (G_OBJECT (priv->grid), - "hexpand", TRUE, + priv->overlay = gtk_overlay_new (); + g_object_set (G_OBJECT (priv->overlay), + "halign", GTK_ALIGN_FILL, + "valign", GTK_ALIGN_FILL, "hexpand", TRUE, + "vexpand", TRUE, + NULL); + + priv->center_grid = gtk_grid_new (); + g_object_set (G_OBJECT (priv->center_grid), + "orientation", GTK_ORIENTATION_VERTICAL, "halign", GTK_ALIGN_CENTER, "valign", GTK_ALIGN_CENTER, NULL); - gtk_container_add (GTK_CONTAINER (self), - GTK_WIDGET (priv->grid)); + + priv->bottom_grid = gtk_grid_new (); + g_object_set (G_OBJECT (priv->bottom_grid), + "orientation", GTK_ORIENTATION_VERTICAL, + "halign", GTK_ALIGN_CENTER, + "valign", GTK_ALIGN_END, + NULL); + + // this is ugly, but needed so the overlay takes all the available space + GtkWidget* placeholder = gtk_event_box_new(); + gtk_widget_set_hexpand (placeholder, TRUE); + gtk_widget_set_vexpand (placeholder, TRUE); + gtk_container_add (GTK_CONTAINER (priv->overlay), placeholder); + + gtk_overlay_add_overlay (GTK_OVERLAY (priv->overlay), priv->center_grid); + gtk_overlay_add_overlay (GTK_OVERLAY (priv->overlay), priv->bottom_grid); + + gtk_container_add (GTK_CONTAINER (self), priv->overlay); // TODO : name? priv->action_group = gtk_action_group_new ("EosActionMenu"); @@ -108,8 +134,15 @@ eos_action_menu_finalize (GObject *object) * @menu: a #EosActionMenu * @action: a #GtkAction: name, label, icon-name, is-important. * - * Adds an action to the #EosActionMenu, using its name, label, icon-name and - * is-important properties. + * Adds an action to the #EosActionMenu, using its #GtkAction:name, + * #GtkAction:label, #GtkAction:icon-name, #GtkAction:is-important and + * #GtkAction:stock-id properties. + * + * Cancel, close and delete actions are placed at the bottom of the menu. To + * indicate this, set the #GtkAction:stock-id property to one of + * #GTK_STOCK_CANCEL, #GTK_STOCK_CLOSE or #GTK_STOCK_DELETE. All other values of + * this property will be ignored. + * */ void eos_action_menu_add_action (EosActionMenu *menu, @@ -134,9 +167,16 @@ eos_action_menu_add_action (EosActionMenu *menu, gtk_activatable_set_related_action (GTK_ACTIVATABLE (action_button), action); - // TODO : maybe we need a finer control, taking is-important into account? - gtk_grid_attach_next_to (GTK_GRID (priv->grid), action_button, NULL, - GTK_POS_BOTTOM, 1, 1); + if (g_strcmp0 (gtk_action_get_stock_id (action), GTK_STOCK_CANCEL) == 0 || + g_strcmp0 (gtk_action_get_stock_id (action), GTK_STOCK_CLOSE) == 0 || + g_strcmp0 (gtk_action_get_stock_id (action), GTK_STOCK_DELETE) == 0) + { + gtk_container_add (GTK_CONTAINER (priv->bottom_grid), action_button); + } + else + { + gtk_container_add (GTK_CONTAINER (priv->center_grid), action_button); + } } } @@ -197,7 +237,10 @@ eos_action_menu_remove_action (EosActionMenu *menu, gtk_action_group_remove_action(priv->action_group, action); - children = gtk_container_get_children (GTK_CONTAINER (priv->grid)); + children = gtk_container_get_children (GTK_CONTAINER (priv->center_grid)); + + children = g_list_concat (children, + gtk_container_get_children (GTK_CONTAINER (priv->bottom_grid))); for (i = children; i != NULL; i = i->next) { diff --git a/test/test-action-menu.c b/test/test-action-menu.c index 46fc300..e066b70 100644 --- a/test/test-action-menu.c +++ b/test/test-action-menu.c @@ -57,7 +57,7 @@ test_am_add_action (ActionMenuFixture *fixture, eos_action_menu_add_action (fixture->action_menu, fixture->action1); - GtkWidget *button = gtk_grid_get_child_at (GTK_GRID (fixture->action_menu->priv->grid), 0, 0); + GtkWidget *button = gtk_grid_get_child_at (GTK_GRID (fixture->action_menu->priv->center_grid), 0, 0); g_assert (EOS_IS_ACTION_BUTTON (button)); @@ -106,11 +106,16 @@ test_am_list_actions (ActionMenuFixture *fixture, } static gboolean -menu_contains_button_with_label (GtkContainer *menu, const gchar* button_label) +menu_contains_button_with_label (EosActionMenu *menu, const gchar* button_label) { - GList* children = gtk_container_get_children (menu); + GList* children; gboolean found = FALSE; + children = gtk_container_get_children (GTK_CONTAINER (menu->priv->center_grid)); + + children = g_list_concat (children, + gtk_container_get_children (GTK_CONTAINER (menu->priv->bottom_grid))); + for (GList *i = children; i != NULL ; i = i->next) { if (EOS_IS_ACTION_BUTTON (i->data)) @@ -148,11 +153,11 @@ test_am_remove_action (ActionMenuFixture *fixture, g_assert (g_list_find (list, fixture->action3) != NULL); // the buttons have been removed as well - g_assert (menu_contains_button_with_label (GTK_CONTAINER (fixture->action_menu->priv->grid), + g_assert (menu_contains_button_with_label (fixture->action_menu, gtk_action_get_label (fixture->action1))); - g_assert (!menu_contains_button_with_label (GTK_CONTAINER (fixture->action_menu->priv->grid), + g_assert (!menu_contains_button_with_label (fixture->action_menu, gtk_action_get_label (fixture->action2))); - g_assert (menu_contains_button_with_label (GTK_CONTAINER (fixture->action_menu->priv->grid), + g_assert (menu_contains_button_with_label (fixture->action_menu, gtk_action_get_label (fixture->action3))); eos_action_menu_remove_action (fixture->action_menu, fixture->action1); @@ -165,7 +170,8 @@ test_am_remove_action (ActionMenuFixture *fixture, g_assert (g_list_find (list, fixture->action3) == NULL); // the container is empty - g_assert (gtk_container_get_children (GTK_CONTAINER (fixture->action_menu->priv->grid)) == NULL); + g_assert (gtk_container_get_children (GTK_CONTAINER (fixture->action_menu->priv->center_grid)) == NULL); + g_assert (gtk_container_get_children (GTK_CONTAINER (fixture->action_menu->priv->bottom_grid)) == NULL); } static void @@ -184,11 +190,11 @@ test_am_remove_action_by_name (ActionMenuFixture *fixture, g_assert (g_list_find (list, fixture->action2) == NULL); g_assert (g_list_find (list, fixture->action3) != NULL); - g_assert (menu_contains_button_with_label (GTK_CONTAINER (fixture->action_menu->priv->grid), + g_assert (menu_contains_button_with_label (fixture->action_menu, gtk_action_get_label (fixture->action1))); - g_assert (!menu_contains_button_with_label (GTK_CONTAINER (fixture->action_menu->priv->grid), + g_assert (!menu_contains_button_with_label (fixture->action_menu, gtk_action_get_label (fixture->action2))); - g_assert (menu_contains_button_with_label (GTK_CONTAINER (fixture->action_menu->priv->grid), + g_assert (menu_contains_button_with_label (fixture->action_menu, gtk_action_get_label (fixture->action3))); } |