mirror of
https://gitlab.gnome.org/GNOME/gtk.git
synced 2024-12-25 21:21:21 +00:00
inspector: Stop using a treeview for menus
Replace this with a GtkColumnView.
This commit is contained in:
parent
a377f95aac
commit
ab7a04d89f
@ -20,48 +20,227 @@
|
||||
|
||||
#include "menu.h"
|
||||
|
||||
#include "gtktreestore.h"
|
||||
#include "gtkwidgetprivate.h"
|
||||
#include "gtklabel.h"
|
||||
#include "gtkstack.h"
|
||||
#include "gtkcolumnview.h"
|
||||
#include "gtkcolumnviewcolumn.h"
|
||||
#include "gtktreelistmodel.h"
|
||||
#include "gtknoselection.h"
|
||||
#include "gtksignallistitemfactory.h"
|
||||
#include "gtktreeexpander.h"
|
||||
#include "gtklistitem.h"
|
||||
|
||||
|
||||
enum
|
||||
typedef struct _MenuItem MenuItem;
|
||||
|
||||
G_DECLARE_FINAL_TYPE (MenuItem, menu_item, MENU, ITEM, GObject);
|
||||
|
||||
struct _MenuItem
|
||||
{
|
||||
COLUMN_TYPE,
|
||||
COLUMN_LABEL,
|
||||
COLUMN_ACTION,
|
||||
COLUMN_TARGET,
|
||||
COLUMN_ICON
|
||||
GObject parent;
|
||||
|
||||
char *label;
|
||||
char *action;
|
||||
char *target;
|
||||
char *icon;
|
||||
GMenuModel *model;
|
||||
};
|
||||
|
||||
G_DEFINE_TYPE (MenuItem, menu_item, G_TYPE_OBJECT);
|
||||
|
||||
static void
|
||||
menu_item_init (MenuItem *self)
|
||||
{
|
||||
}
|
||||
|
||||
static void
|
||||
menu_item_finalize (GObject *object)
|
||||
{
|
||||
MenuItem *self = MENU_ITEM (object);
|
||||
|
||||
g_free (self->label);
|
||||
g_free (self->action);
|
||||
g_free (self->target);
|
||||
g_free (self->icon);
|
||||
g_clear_object (&self->model);
|
||||
|
||||
G_OBJECT_CLASS (menu_item_parent_class)->finalize (object);
|
||||
}
|
||||
|
||||
static void
|
||||
menu_item_class_init (MenuItemClass *class)
|
||||
{
|
||||
G_OBJECT_CLASS (class)->finalize = menu_item_finalize;
|
||||
}
|
||||
|
||||
static MenuItem *
|
||||
menu_item_new (const char *label,
|
||||
const char *action,
|
||||
const char *target,
|
||||
const char *icon,
|
||||
GMenuModel *model)
|
||||
{
|
||||
MenuItem *self;
|
||||
|
||||
self = g_object_new (menu_item_get_type (), NULL);
|
||||
self->label = g_strdup (label);
|
||||
self->action = g_strdup (action);
|
||||
self->target = g_strdup (target);
|
||||
self->icon = g_strdup (icon);
|
||||
g_set_object (&self->model, model);
|
||||
|
||||
return self;
|
||||
}
|
||||
|
||||
struct _GtkInspectorMenuPrivate
|
||||
{
|
||||
GtkTreeStore *model;
|
||||
GtkColumnView *view;
|
||||
GtkTreeListModel *tree_model;
|
||||
};
|
||||
|
||||
G_DEFINE_TYPE_WITH_PRIVATE (GtkInspectorMenu, gtk_inspector_menu, GTK_TYPE_BOX)
|
||||
|
||||
static GListModel * create_model (gpointer item, gpointer user_data);
|
||||
|
||||
static void
|
||||
setup_label (GtkListItemFactory *factory,
|
||||
GtkListItem *item)
|
||||
{
|
||||
GtkWidget *expander;
|
||||
GtkWidget *label;
|
||||
|
||||
expander = gtk_tree_expander_new ();
|
||||
label = gtk_label_new (NULL);
|
||||
gtk_label_set_xalign (GTK_LABEL (label), 0.);
|
||||
gtk_tree_expander_set_child (GTK_TREE_EXPANDER (expander), label);
|
||||
|
||||
gtk_list_item_set_child (item, expander);
|
||||
}
|
||||
|
||||
static void
|
||||
bind_label (GtkListItemFactory *factory,
|
||||
GtkListItem *item)
|
||||
{
|
||||
GtkWidget *expander;
|
||||
GtkWidget *label;
|
||||
GtkTreeListRow *row;
|
||||
MenuItem *menu_item;
|
||||
|
||||
row = gtk_list_item_get_item (item);
|
||||
menu_item = gtk_tree_list_row_get_item (row);
|
||||
|
||||
expander = gtk_list_item_get_child (item);
|
||||
gtk_tree_expander_set_list_row (GTK_TREE_EXPANDER (expander), row);
|
||||
|
||||
label = gtk_tree_expander_get_child (GTK_TREE_EXPANDER (expander));
|
||||
gtk_label_set_label (GTK_LABEL (label), menu_item->label);
|
||||
}
|
||||
|
||||
static void
|
||||
setup_action (GtkListItemFactory *factory,
|
||||
GtkListItem *item)
|
||||
{
|
||||
GtkWidget *label;
|
||||
|
||||
label = gtk_label_new (NULL);
|
||||
gtk_label_set_xalign (GTK_LABEL (label), 0.);
|
||||
|
||||
gtk_list_item_set_child (item, label);
|
||||
}
|
||||
|
||||
static void
|
||||
bind_action (GtkListItemFactory *factory,
|
||||
GtkListItem *item)
|
||||
{
|
||||
GtkWidget *label;
|
||||
GtkTreeListRow *row;
|
||||
MenuItem *menu_item;
|
||||
|
||||
row = gtk_list_item_get_item (item);
|
||||
menu_item = gtk_tree_list_row_get_item (row);
|
||||
|
||||
label = gtk_list_item_get_child (item);
|
||||
gtk_label_set_label (GTK_LABEL (label), menu_item->action);
|
||||
}
|
||||
|
||||
static void
|
||||
setup_target (GtkListItemFactory *factory,
|
||||
GtkListItem *item)
|
||||
{
|
||||
GtkWidget *label;
|
||||
|
||||
label = gtk_label_new (NULL);
|
||||
gtk_label_set_xalign (GTK_LABEL (label), 0.);
|
||||
|
||||
gtk_list_item_set_child (item, label);
|
||||
}
|
||||
|
||||
static void
|
||||
bind_target (GtkListItemFactory *factory,
|
||||
GtkListItem *item)
|
||||
{
|
||||
GtkWidget *label;
|
||||
GtkTreeListRow *row;
|
||||
MenuItem *menu_item;
|
||||
|
||||
row = gtk_list_item_get_item (item);
|
||||
menu_item = gtk_tree_list_row_get_item (row);
|
||||
|
||||
label = gtk_list_item_get_child (item);
|
||||
gtk_label_set_label (GTK_LABEL (label), menu_item->target);
|
||||
}
|
||||
|
||||
static void
|
||||
gtk_inspector_menu_init (GtkInspectorMenu *sl)
|
||||
{
|
||||
GtkTreeListModel *store;
|
||||
GtkColumnViewColumn *column;
|
||||
GtkListItemFactory *factory;
|
||||
|
||||
sl->priv = gtk_inspector_menu_get_instance_private (sl);
|
||||
gtk_widget_init_template (GTK_WIDGET (sl));
|
||||
}
|
||||
|
||||
static void add_menu (GtkInspectorMenu *sl,
|
||||
GtkStackPage *page,
|
||||
GMenuModel *menu,
|
||||
GtkTreeIter *parent);
|
||||
store = gtk_tree_list_model_new (G_LIST_MODEL (g_list_store_new (menu_item_get_type ())),
|
||||
FALSE, FALSE,
|
||||
create_model,
|
||||
sl, NULL);
|
||||
|
||||
gtk_column_view_set_model (sl->priv->view, GTK_SELECTION_MODEL (gtk_no_selection_new (G_LIST_MODEL (store))));
|
||||
|
||||
column = g_list_model_get_item (gtk_column_view_get_columns (sl->priv->view), 0);
|
||||
factory = gtk_signal_list_item_factory_new ();
|
||||
g_signal_connect (factory, "setup", G_CALLBACK (setup_label), NULL);
|
||||
g_signal_connect (factory, "bind", G_CALLBACK (bind_label), NULL);
|
||||
gtk_column_view_column_set_factory (column, factory);
|
||||
g_object_unref (factory);
|
||||
g_object_unref (column);
|
||||
|
||||
column = g_list_model_get_item (gtk_column_view_get_columns (sl->priv->view), 1);
|
||||
factory = gtk_signal_list_item_factory_new ();
|
||||
g_signal_connect (factory, "setup", G_CALLBACK (setup_action), NULL);
|
||||
g_signal_connect (factory, "bind", G_CALLBACK (bind_action), NULL);
|
||||
gtk_column_view_column_set_factory (column, factory);
|
||||
g_object_unref (factory);
|
||||
g_object_unref (column);
|
||||
|
||||
column = g_list_model_get_item (gtk_column_view_get_columns (sl->priv->view), 2);
|
||||
factory = gtk_signal_list_item_factory_new ();
|
||||
g_signal_connect (factory, "setup", G_CALLBACK (setup_target), NULL);
|
||||
g_signal_connect (factory, "bind", G_CALLBACK (bind_target), NULL);
|
||||
gtk_column_view_column_set_factory (column, factory);
|
||||
g_object_unref (factory);
|
||||
g_object_unref (column);
|
||||
|
||||
sl->priv->tree_model = store;
|
||||
}
|
||||
|
||||
static void
|
||||
add_item (GtkInspectorMenu *sl,
|
||||
GtkStackPage *page,
|
||||
GMenuModel *menu,
|
||||
int idx,
|
||||
GtkTreeIter *parent)
|
||||
GListStore *store)
|
||||
{
|
||||
GtkTreeIter iter;
|
||||
GVariant *value;
|
||||
char *label = NULL;
|
||||
char *action = NULL;
|
||||
@ -78,33 +257,18 @@ add_item (GtkInspectorMenu *sl,
|
||||
g_variant_unref (value);
|
||||
}
|
||||
|
||||
gtk_tree_store_append (sl->priv->model, &iter, parent);
|
||||
gtk_tree_store_set (sl->priv->model, &iter,
|
||||
COLUMN_TYPE, "item",
|
||||
COLUMN_LABEL, label,
|
||||
COLUMN_ACTION, action,
|
||||
COLUMN_TARGET, target,
|
||||
COLUMN_ICON, icon,
|
||||
-1);
|
||||
|
||||
model = g_menu_model_get_item_link (menu, idx, G_MENU_LINK_SECTION);
|
||||
if (model)
|
||||
{
|
||||
if (label == NULL)
|
||||
gtk_tree_store_set (sl->priv->model, &iter,
|
||||
COLUMN_LABEL, _("Unnamed section"),
|
||||
-1);
|
||||
add_menu (sl, page, model, &iter);
|
||||
g_object_unref (model);
|
||||
label = g_strdup (_("Unnamed section"));
|
||||
}
|
||||
|
||||
else
|
||||
model = g_menu_model_get_item_link (menu, idx, G_MENU_LINK_SUBMENU);
|
||||
if (model)
|
||||
{
|
||||
add_menu (sl, page, model, &iter);
|
||||
g_object_unref (model);
|
||||
}
|
||||
|
||||
g_list_store_append (store, menu_item_new (label, action, target, icon, model));
|
||||
|
||||
g_clear_object (&model);
|
||||
g_free (label);
|
||||
g_free (action);
|
||||
g_free (target);
|
||||
@ -113,18 +277,32 @@ add_item (GtkInspectorMenu *sl,
|
||||
|
||||
static void
|
||||
add_menu (GtkInspectorMenu *sl,
|
||||
GtkStackPage *page,
|
||||
GMenuModel *menu,
|
||||
GtkTreeIter *parent)
|
||||
GListStore *store)
|
||||
{
|
||||
int n_items;
|
||||
int i;
|
||||
|
||||
g_object_set (page, "visible", TRUE, NULL);
|
||||
|
||||
n_items = g_menu_model_get_n_items (menu);
|
||||
for (i = 0; i < n_items; i++)
|
||||
add_item (sl, page, menu, i, parent);
|
||||
add_item (sl, menu, i, store);
|
||||
}
|
||||
|
||||
static GListModel *
|
||||
create_model (gpointer item,
|
||||
gpointer user_data)
|
||||
{
|
||||
MenuItem *self = item;
|
||||
GtkInspectorMenu *sl = user_data;
|
||||
GListStore *store;
|
||||
|
||||
if (self->model == NULL)
|
||||
return NULL;
|
||||
|
||||
store = g_list_store_new (menu_item_get_type ());
|
||||
add_menu (sl, self->model, store);
|
||||
|
||||
return G_LIST_MODEL (store);
|
||||
}
|
||||
|
||||
void
|
||||
@ -133,15 +311,21 @@ gtk_inspector_menu_set_object (GtkInspectorMenu *sl,
|
||||
{
|
||||
GtkWidget *stack;
|
||||
GtkStackPage *page;
|
||||
GListStore *store;
|
||||
|
||||
stack = gtk_widget_get_parent (GTK_WIDGET (sl));
|
||||
page = gtk_stack_get_page (GTK_STACK (stack), GTK_WIDGET (sl));
|
||||
|
||||
g_object_set (page, "visible", FALSE, NULL);
|
||||
gtk_tree_store_clear (sl->priv->model);
|
||||
|
||||
store = G_LIST_STORE (gtk_tree_list_model_get_model (sl->priv->tree_model));
|
||||
g_list_store_remove_all (store);
|
||||
|
||||
if (G_IS_MENU_MODEL (object))
|
||||
add_menu (sl, page, G_MENU_MODEL (object), NULL);
|
||||
{
|
||||
g_object_set (page, "visible", TRUE, NULL);
|
||||
add_menu (sl, G_MENU_MODEL (object), store);
|
||||
}
|
||||
}
|
||||
|
||||
static void
|
||||
@ -150,7 +334,7 @@ gtk_inspector_menu_class_init (GtkInspectorMenuClass *klass)
|
||||
GtkWidgetClass *widget_class = GTK_WIDGET_CLASS (klass);
|
||||
|
||||
gtk_widget_class_set_template_from_resource (widget_class, "/org/gtk/libgtk/inspector/menu.ui");
|
||||
gtk_widget_class_bind_template_child_private (widget_class, GtkInspectorMenu, model);
|
||||
gtk_widget_class_bind_template_child_private (widget_class, GtkInspectorMenu, view);
|
||||
}
|
||||
|
||||
// vim: set et sw=2 ts=2:
|
||||
|
@ -16,58 +16,26 @@
|
||||
<property name="vexpand">1</property>
|
||||
<property name="vscrollbar-policy">always</property>
|
||||
<child>
|
||||
<object class="GtkTreeView">
|
||||
<property name="model">model</property>
|
||||
<object class="GtkColumnView" id="view">
|
||||
<child>
|
||||
<object class="GtkTreeViewColumn">
|
||||
<object class="GtkColumnViewColumn">
|
||||
<property name="title" translatable="yes">Label</property>
|
||||
<child>
|
||||
<object class="GtkCellRendererText">
|
||||
<property name="scale">0.8</property>
|
||||
</object>
|
||||
<attributes>
|
||||
<attribute name="text">1</attribute>
|
||||
</attributes>
|
||||
</child>
|
||||
</object>
|
||||
</child>
|
||||
<child>
|
||||
<object class="GtkTreeViewColumn">
|
||||
<object class="GtkColumnViewColumn">
|
||||
<property name="title" translatable="yes">Action</property>
|
||||
<child>
|
||||
<object class="GtkCellRendererText">
|
||||
<property name="scale">0.8</property>
|
||||
</object>
|
||||
<attributes>
|
||||
<attribute name="text">2</attribute>
|
||||
</attributes>
|
||||
</child>
|
||||
</object>
|
||||
</child>
|
||||
<child>
|
||||
<object class="GtkTreeViewColumn">
|
||||
<object class="GtkColumnViewColumn">
|
||||
<property name="title" translatable="yes">Target</property>
|
||||
<child>
|
||||
<object class="GtkCellRendererText">
|
||||
<property name="scale">0.8</property>
|
||||
</object>
|
||||
<attributes>
|
||||
<attribute name="text">3</attribute>
|
||||
</attributes>
|
||||
</child>
|
||||
</object>
|
||||
</child>
|
||||
<child>
|
||||
<object class="GtkTreeViewColumn">
|
||||
<object class="GtkColumnViewColumn">
|
||||
<property name="title" translatable="yes">Icon</property>
|
||||
<child>
|
||||
<object class="GtkCellRendererText">
|
||||
<property name="scale">0.8</property>
|
||||
</object>
|
||||
<attributes>
|
||||
<attribute name="text">4</attribute>
|
||||
</attributes>
|
||||
</child>
|
||||
<property name="expand">1</property>
|
||||
</object>
|
||||
</child>
|
||||
</object>
|
||||
|
Loading…
Reference in New Issue
Block a user