summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
-rw-r--r--endless/eosactionmenu.c67
-rw-r--r--test/test-action-menu.c26
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)));
}