popover menus: Take iconic into account
We don't want separators in both side of an iconic section and use a 10px margin to separate two iconic sections. Separators are also updated in case of dynamic insertion ( often used with menu items for plugins ) https://bugzilla.gnome.org/show_bug.cgi?id=738650
This commit is contained in:
committed by
Matthias Clasen
parent
fc6f22c3ce
commit
17f9eed14e
@@ -48,10 +48,16 @@ struct _GtkMenuSectionBox
|
||||
gint depth;
|
||||
};
|
||||
|
||||
typedef struct
|
||||
{
|
||||
gint n_items;
|
||||
gboolean previous_is_iconic;
|
||||
} MenuData;
|
||||
|
||||
G_DEFINE_TYPE (GtkMenuSectionBox, gtk_menu_section_box, GTK_TYPE_BOX)
|
||||
|
||||
void gtk_menu_section_box_sync_separators (GtkMenuSectionBox *box,
|
||||
gint *n_items);
|
||||
MenuData *data);
|
||||
void gtk_menu_section_box_new_submenu (GtkMenuTrackerItem *item,
|
||||
GtkMenuSectionBox *toplevel,
|
||||
GtkWidget *focus);
|
||||
@@ -62,12 +68,12 @@ static void
|
||||
gtk_menu_section_box_sync_item (GtkWidget *widget,
|
||||
gpointer user_data)
|
||||
{
|
||||
gint *n_items = user_data;
|
||||
MenuData *data = (MenuData *)user_data;
|
||||
|
||||
if (GTK_IS_MENU_SECTION_BOX (widget))
|
||||
gtk_menu_section_box_sync_separators (GTK_MENU_SECTION_BOX (widget), n_items);
|
||||
gtk_menu_section_box_sync_separators (GTK_MENU_SECTION_BOX (widget), data);
|
||||
else
|
||||
(*n_items)++;
|
||||
data->n_items++;
|
||||
}
|
||||
|
||||
/* We are trying to implement the following rules here:
|
||||
@@ -77,26 +83,32 @@ gtk_menu_section_box_sync_item (GtkWidget *widget,
|
||||
* rule 3: don't show a separator for the first section
|
||||
* rule 4: don't show a separator for the following sections if there are
|
||||
* no items before it
|
||||
* (rule 5: these rules don't apply exactly the same way for subsections)
|
||||
* rule 5: never show separators directly above or below an iconic box
|
||||
* (rule 6: these rules don't apply exactly the same way for subsections)
|
||||
*/
|
||||
void
|
||||
gtk_menu_section_box_sync_separators (GtkMenuSectionBox *box,
|
||||
gint *n_items)
|
||||
MenuData *data)
|
||||
{
|
||||
GtkWidget *parent_widget;
|
||||
gboolean previous_section_is_iconic;
|
||||
gboolean should_have_separator;
|
||||
gboolean should_have_top_margin = FALSE;
|
||||
gboolean is_not_empty_item;
|
||||
gboolean has_separator;
|
||||
gboolean has_label;
|
||||
gint n_items_before = *n_items;
|
||||
gboolean separator_condition;
|
||||
gint n_items_before;
|
||||
|
||||
gtk_container_foreach (GTK_CONTAINER (box->item_box), gtk_menu_section_box_sync_item, n_items);
|
||||
n_items_before = data->n_items;
|
||||
previous_section_is_iconic = data->previous_is_iconic;
|
||||
|
||||
if (box->iconic)
|
||||
{
|
||||
if (n_items_before > 0)
|
||||
gtk_widget_set_margin_top (GTK_WIDGET (box->item_box), 10);
|
||||
else
|
||||
gtk_widget_set_margin_top (GTK_WIDGET (box->item_box), 0);
|
||||
}
|
||||
gtk_container_foreach (GTK_CONTAINER (box->item_box), gtk_menu_section_box_sync_item, data);
|
||||
|
||||
is_not_empty_item = (data->n_items > n_items_before);
|
||||
|
||||
if (is_not_empty_item)
|
||||
data->previous_is_iconic = box->iconic;
|
||||
|
||||
if (box->separator == NULL)
|
||||
return;
|
||||
@@ -104,7 +116,19 @@ gtk_menu_section_box_sync_separators (GtkMenuSectionBox *box,
|
||||
has_separator = gtk_widget_get_parent (box->separator) != NULL;
|
||||
has_label = !GTK_IS_SEPARATOR (box->separator);
|
||||
|
||||
should_have_separator = (has_label || (n_items_before > 0 && box->depth <= 1)) && *n_items > n_items_before;
|
||||
separator_condition = has_label ? TRUE : n_items_before > 0 &&
|
||||
box->depth <= 1 &&
|
||||
!previous_section_is_iconic &&
|
||||
!box->iconic;
|
||||
|
||||
should_have_separator = separator_condition && is_not_empty_item;
|
||||
|
||||
should_have_top_margin = !should_have_separator &&
|
||||
(box->depth <= 1 || box->iconic) &&
|
||||
n_items_before > 0 &&
|
||||
is_not_empty_item;
|
||||
|
||||
gtk_widget_set_margin_top (GTK_WIDGET (box->item_box), should_have_top_margin ? 10 : 0);
|
||||
|
||||
if (should_have_separator == has_separator)
|
||||
return;
|
||||
@@ -119,9 +143,11 @@ static gboolean
|
||||
gtk_menu_section_box_handle_sync_separators (gpointer user_data)
|
||||
{
|
||||
GtkMenuSectionBox *box = user_data;
|
||||
gint n_items = 0;
|
||||
MenuData data;
|
||||
|
||||
gtk_menu_section_box_sync_separators (box, &n_items);
|
||||
data.n_items = 0;
|
||||
data.previous_is_iconic = FALSE;
|
||||
gtk_menu_section_box_sync_separators (box, &data);
|
||||
|
||||
box->separator_sync_idle = 0;
|
||||
|
||||
@@ -328,11 +354,7 @@ gtk_menu_section_box_dispose (GObject *object)
|
||||
box->separator_sync_idle = 0;
|
||||
}
|
||||
|
||||
if (box->separator)
|
||||
{
|
||||
gtk_widget_destroy (box->separator);
|
||||
box->separator = NULL;
|
||||
}
|
||||
g_clear_object (&box->separator);
|
||||
|
||||
if (box->tracker)
|
||||
{
|
||||
@@ -436,7 +458,10 @@ gtk_menu_section_box_new_section (GtkMenuTrackerItem *item,
|
||||
g_object_bind_property (item, "label", title, "label", G_BINDING_SYNC_CREATE);
|
||||
gtk_style_context_add_class (gtk_widget_get_style_context (title), GTK_STYLE_CLASS_SEPARATOR);
|
||||
gtk_widget_set_halign (title, GTK_ALIGN_START);
|
||||
|
||||
box->separator = gtk_box_new (GTK_ORIENTATION_VERTICAL, 0);
|
||||
g_object_ref_sink (box->separator);
|
||||
|
||||
g_object_set (box->separator,
|
||||
"margin-start", 12,
|
||||
"margin-end", 12,
|
||||
@@ -450,6 +475,8 @@ gtk_menu_section_box_new_section (GtkMenuTrackerItem *item,
|
||||
else
|
||||
{
|
||||
box->separator = separator;
|
||||
g_object_ref_sink (box->separator);
|
||||
|
||||
g_object_set (box->separator,
|
||||
"margin-start", 12,
|
||||
"margin-end", 12,
|
||||
@@ -459,8 +486,6 @@ gtk_menu_section_box_new_section (GtkMenuTrackerItem *item,
|
||||
gtk_widget_show (box->separator);
|
||||
}
|
||||
|
||||
g_object_add_weak_pointer (G_OBJECT (box->separator), (gpointer *)&(box->separator));
|
||||
|
||||
box->tracker = gtk_menu_tracker_new_for_item_link (item, G_MENU_LINK_SECTION, FALSE,
|
||||
gtk_menu_section_box_insert_func,
|
||||
gtk_menu_section_box_remove_func,
|
||||
|
||||
Reference in New Issue
Block a user