inspector: Port actions to a list view

This commit is contained in:
Matthias Clasen 2019-05-08 02:20:18 +00:00
parent e1c1c46e34
commit 4cc27285b1
3 changed files with 196 additions and 163 deletions

View File

@ -55,9 +55,8 @@ gtk_inspector_action_editor_init (GtkInspectorActionEditor *editor)
{ {
editor->priv = gtk_inspector_action_editor_get_instance_private (editor); editor->priv = gtk_inspector_action_editor_get_instance_private (editor);
g_object_set (editor, g_object_set (editor,
"orientation", GTK_ORIENTATION_VERTICAL, "orientation", GTK_ORIENTATION_HORIZONTAL,
"spacing", 10, "spacing", 10,
"margin", 10,
NULL); NULL);
} }
@ -238,6 +237,9 @@ action_enabled_changed_cb (GActionGroup *group,
gboolean enabled, gboolean enabled,
GtkInspectorActionEditor *r) GtkInspectorActionEditor *r)
{ {
if (!g_str_equal (action_name, r->priv->name))
return;
r->priv->enabled = enabled; r->priv->enabled = enabled;
if (r->priv->parameter_entry) if (r->priv->parameter_entry)
{ {
@ -252,6 +254,9 @@ action_state_changed_cb (GActionGroup *group,
GVariant *state, GVariant *state,
GtkInspectorActionEditor *r) GtkInspectorActionEditor *r)
{ {
if (!g_str_equal (action_name, r->priv->name))
return;
if (r->priv->state_entry) if (r->priv->state_entry)
variant_editor_set_value (r->priv->state_entry, state); variant_editor_set_value (r->priv->state_entry, state);
} }
@ -261,17 +266,12 @@ constructed (GObject *object)
{ {
GtkInspectorActionEditor *r = GTK_INSPECTOR_ACTION_EDITOR (object); GtkInspectorActionEditor *r = GTK_INSPECTOR_ACTION_EDITOR (object);
GVariant *state; GVariant *state;
gchar *fullname;
GtkWidget *row; GtkWidget *row;
GtkWidget *label; GtkWidget *label;
r->priv->enabled = g_action_group_get_action_enabled (r->priv->group, r->priv->name); r->priv->enabled = g_action_group_get_action_enabled (r->priv->group, r->priv->name);
state = g_action_group_get_action_state (r->priv->group, r->priv->name); state = g_action_group_get_action_state (r->priv->group, r->priv->name);
fullname = g_strdup_printf ("%s.%s", r->priv->prefix, r->priv->name);
gtk_container_add (GTK_CONTAINER (r), gtk_label_new (fullname));
g_free (fullname);
r->priv->sg = gtk_size_group_new (GTK_SIZE_GROUP_HORIZONTAL); r->priv->sg = gtk_size_group_new (GTK_SIZE_GROUP_HORIZONTAL);
row = gtk_box_new (GTK_ORIENTATION_HORIZONTAL, 10); row = gtk_box_new (GTK_ORIENTATION_HORIZONTAL, 10);
@ -297,7 +297,7 @@ constructed (GObject *object)
{ {
r->priv->state_type = g_variant_type_copy (g_variant_get_type (state)); r->priv->state_type = g_variant_type_copy (g_variant_get_type (state));
row = gtk_box_new (GTK_ORIENTATION_HORIZONTAL, 10); row = gtk_box_new (GTK_ORIENTATION_HORIZONTAL, 10);
label = gtk_label_new (_("State")); label = gtk_label_new (_("Set State"));
gtk_size_group_add_widget (r->priv->sg, label); gtk_size_group_add_widget (r->priv->sg, label);
gtk_container_add (GTK_CONTAINER (row), label); gtk_container_add (GTK_CONTAINER (row), label);
r->priv->state_entry = variant_editor_new (r->priv->state_type, state_changed, r); r->priv->state_entry = variant_editor_new (r->priv->state_type, state_changed, r);

View File

@ -29,6 +29,9 @@
#include "gtkpopover.h" #include "gtkpopover.h"
#include "gtklabel.h" #include "gtklabel.h"
#include "gtkstack.h" #include "gtkstack.h"
#include "gtklistbox.h"
#include "gtkstylecontext.h"
#include "gtksizegroup.h"
enum enum
{ {
@ -42,9 +45,13 @@ enum
struct _GtkInspectorActionsPrivate struct _GtkInspectorActionsPrivate
{ {
GtkListStore *model; GtkWidget *list;
GtkSizeGroup *prefix;
GtkSizeGroup *name;
GtkSizeGroup *enabled;
GtkSizeGroup *parameter;
GtkSizeGroup *state;
GHashTable *groups; GHashTable *groups;
GHashTable *iters;
}; };
G_DEFINE_TYPE_WITH_PRIVATE (GtkInspectorActions, gtk_inspector_actions, GTK_TYPE_BOX) G_DEFINE_TYPE_WITH_PRIVATE (GtkInspectorActions, gtk_inspector_actions, GTK_TYPE_BOX)
@ -53,10 +60,6 @@ static void
gtk_inspector_actions_init (GtkInspectorActions *sl) gtk_inspector_actions_init (GtkInspectorActions *sl)
{ {
sl->priv = gtk_inspector_actions_get_instance_private (sl); sl->priv = gtk_inspector_actions_get_instance_private (sl);
sl->priv->iters = g_hash_table_new_full (g_str_hash,
g_str_equal,
g_free,
(GDestroyNotify) gtk_tree_iter_free);
sl->priv->groups = g_hash_table_new_full (g_direct_hash, sl->priv->groups = g_hash_table_new_full (g_direct_hash,
g_direct_equal, g_direct_equal,
NULL, NULL,
@ -70,11 +73,15 @@ add_action (GtkInspectorActions *sl,
const gchar *prefix, const gchar *prefix,
const gchar *name) const gchar *name)
{ {
GtkTreeIter iter;
gboolean enabled; gboolean enabled;
const gchar *parameter; const gchar *parameter;
GVariant *state; GVariant *state;
gchar *state_string; gchar *state_string;
GtkWidget *row;
GtkWidget *label;
GtkWidget *box;
char *key = g_strconcat (prefix, ".", name, NULL);
GtkWidget *editor;
enabled = g_action_group_get_action_enabled (group, name); enabled = g_action_group_get_action_enabled (group, name);
parameter = (const gchar *)g_action_group_get_action_parameter_type (group, name); parameter = (const gchar *)g_action_group_get_action_parameter_type (group, name);
@ -83,21 +90,82 @@ add_action (GtkInspectorActions *sl,
state_string = g_variant_print (state, FALSE); state_string = g_variant_print (state, FALSE);
else else
state_string = g_strdup (""); state_string = g_strdup ("");
gtk_list_store_append (sl->priv->model, &iter);
gtk_list_store_set (sl->priv->model, &iter, row = gtk_list_box_row_new ();
COLUMN_PREFIX, prefix, g_object_set_data_full (G_OBJECT (row), "key", key, g_free);
COLUMN_NAME, name,
COLUMN_ENABLED, enabled, gtk_list_box_row_set_activatable (GTK_LIST_BOX_ROW (row), FALSE);
COLUMN_PARAMETER, parameter, box = gtk_box_new (GTK_ORIENTATION_HORIZONTAL, 0);
COLUMN_STATE, state_string, gtk_container_add (GTK_CONTAINER (row), box);
COLUMN_GROUP, group,
-1); label = gtk_label_new (prefix);
g_hash_table_insert (sl->priv->iters, gtk_style_context_add_class (gtk_widget_get_style_context (label), "cell");
g_strconcat (prefix, ".", name, NULL), gtk_label_set_xalign (GTK_LABEL (label), 0);
gtk_tree_iter_copy (&iter)); gtk_size_group_add_widget (sl->priv->prefix, label);
gtk_container_add (GTK_CONTAINER (box), label);
label = gtk_label_new (name);
gtk_style_context_add_class (gtk_widget_get_style_context (label), "cell");
gtk_label_set_xalign (GTK_LABEL (label), 0);
gtk_size_group_add_widget (sl->priv->name, label);
gtk_container_add (GTK_CONTAINER (box), label);
label = gtk_label_new (enabled ? "+" : "-");
gtk_style_context_add_class (gtk_widget_get_style_context (label), "cell");
gtk_label_set_xalign (GTK_LABEL (label), 0);
gtk_size_group_add_widget (sl->priv->enabled, label);
gtk_container_add (GTK_CONTAINER (box), label);
g_object_set_data (G_OBJECT (row), "enabled", label);
label = gtk_label_new (parameter);
gtk_style_context_add_class (gtk_widget_get_style_context (label), "cell");
gtk_label_set_xalign (GTK_LABEL (label), 0);
gtk_size_group_add_widget (sl->priv->parameter, label);
gtk_container_add (GTK_CONTAINER (box), label);
label = gtk_label_new (state_string);
gtk_label_set_xalign (GTK_LABEL (label), 0);
gtk_style_context_add_class (gtk_widget_get_style_context (label), "cell");
gtk_size_group_add_widget (sl->priv->state, label);
gtk_container_add (GTK_CONTAINER (box), label);
g_object_set_data (G_OBJECT (row), "state", label);
editor = gtk_inspector_action_editor_new (group, prefix, name);
gtk_style_context_add_class (gtk_widget_get_style_context (editor), "cell");
gtk_container_add (GTK_CONTAINER (box), editor);
gtk_container_add (GTK_CONTAINER (sl->priv->list), row);
g_free (state_string); g_free (state_string);
} }
static GtkWidget *
find_row (GtkInspectorActions *sl,
const char *prefix,
const char *action_name)
{
GtkWidget *row = NULL;
GtkWidget *widget;
char *key = g_strconcat (prefix, ".", action_name, NULL);
for (widget = gtk_widget_get_first_child (sl->priv->list);
widget;
widget = gtk_widget_get_next_sibling (widget))
{
const char *rkey = g_object_get_data (G_OBJECT (widget), "key");
if (g_str_equal (key, rkey))
{
row = widget;
break;
}
}
g_free (key);
return row;
}
static void static void
action_added_cb (GActionGroup *group, action_added_cb (GActionGroup *group,
const gchar *action_name, const gchar *action_name,
@ -114,14 +182,12 @@ action_removed_cb (GActionGroup *group,
GtkInspectorActions *sl) GtkInspectorActions *sl)
{ {
const gchar *prefix; const gchar *prefix;
gchar *key; GtkWidget *row;
GtkTreeIter *iter;
prefix = g_hash_table_lookup (sl->priv->groups, group); prefix = g_hash_table_lookup (sl->priv->groups, group);
key = g_strconcat (prefix, ".", action_name, NULL); row = find_row (sl, prefix, action_name);
iter = g_hash_table_lookup (sl->priv->iters, key); if (row)
gtk_list_store_remove (sl->priv->model, iter); gtk_container_remove (GTK_CONTAINER (sl->priv->list), row);
g_hash_table_remove (sl->priv->iters, key);
g_free (key);
} }
static void static void
@ -131,15 +197,14 @@ action_enabled_changed_cb (GActionGroup *group,
GtkInspectorActions *sl) GtkInspectorActions *sl)
{ {
const gchar *prefix; const gchar *prefix;
gchar *key; GtkWidget *row;
GtkTreeIter *iter; GtkWidget *label;
prefix = g_hash_table_lookup (sl->priv->groups, group); prefix = g_hash_table_lookup (sl->priv->groups, group);
key = g_strconcat (prefix, ".", action_name, NULL);
iter = g_hash_table_lookup (sl->priv->iters, key); row = find_row (sl, prefix, action_name);
gtk_list_store_set (sl->priv->model, iter, label = GTK_WIDGET (g_object_get_data (G_OBJECT (row), "enabled"));
COLUMN_ENABLED, enabled, gtk_label_set_label (GTK_LABEL (label), enabled ? "+" : "-" );
-1);
g_free (key);
} }
static void static void
@ -149,21 +214,20 @@ action_state_changed_cb (GActionGroup *group,
GtkInspectorActions *sl) GtkInspectorActions *sl)
{ {
const gchar *prefix; const gchar *prefix;
gchar *key;
GtkTreeIter *iter;
gchar *state_string; gchar *state_string;
GtkWidget *row;
GtkWidget *label;
prefix = g_hash_table_lookup (sl->priv->groups, group); prefix = g_hash_table_lookup (sl->priv->groups, group);
key = g_strconcat (prefix, ".", action_name, NULL);
iter = g_hash_table_lookup (sl->priv->iters, key); row = find_row (sl, prefix, action_name);
if (state) if (state)
state_string = g_variant_print (state, FALSE); state_string = g_variant_print (state, FALSE);
else else
state_string = g_strdup (""); state_string = g_strdup ("");
gtk_list_store_set (sl->priv->model, iter, label = GTK_WIDGET (g_object_get_data (G_OBJECT (row), "state"));
COLUMN_STATE, state_string, gtk_label_set_label (GTK_LABEL (label), state_string);
-1);
g_free (state_string); g_free (state_string);
g_free (key);
} }
static void static void
@ -214,8 +278,6 @@ gtk_inspector_actions_set_object (GtkInspectorActions *sl,
g_object_set (page, "visible", FALSE, NULL); g_object_set (page, "visible", FALSE, NULL);
g_hash_table_foreach (sl->priv->groups, disconnect_group, sl); g_hash_table_foreach (sl->priv->groups, disconnect_group, sl);
g_hash_table_remove_all (sl->priv->groups); g_hash_table_remove_all (sl->priv->groups);
g_hash_table_remove_all (sl->priv->iters);
gtk_list_store_clear (sl->priv->model);
if (GTK_IS_APPLICATION (object)) if (GTK_IS_APPLICATION (object))
add_group (sl, page, G_ACTION_GROUP (object), "app"); add_group (sl, page, G_ACTION_GROUP (object), "app");
@ -238,53 +300,18 @@ gtk_inspector_actions_set_object (GtkInspectorActions *sl,
} }
} }
static void
row_activated (GtkTreeView *tv,
GtkTreePath *path,
GtkTreeViewColumn *col,
GtkInspectorActions *sl)
{
GtkTreeIter iter;
GdkRectangle rect;
GtkWidget *popover;
gchar *prefix;
gchar *name;
GActionGroup *group;
GtkWidget *editor;
gtk_tree_model_get_iter (GTK_TREE_MODEL (sl->priv->model), &iter, path);
gtk_tree_model_get (GTK_TREE_MODEL (sl->priv->model),
&iter,
COLUMN_PREFIX, &prefix,
COLUMN_NAME, &name,
COLUMN_GROUP, &group,
-1);
gtk_tree_model_get_iter (GTK_TREE_MODEL (sl->priv->model), &iter, path);
gtk_tree_view_get_cell_area (tv, path, col, &rect);
gtk_tree_view_convert_bin_window_to_widget_coords (tv, rect.x, rect.y, &rect.x, &rect.y);
popover = gtk_popover_new (GTK_WIDGET (tv));
gtk_popover_set_pointing_to (GTK_POPOVER (popover), &rect);
editor = gtk_inspector_action_editor_new (group, prefix, name);
gtk_container_add (GTK_CONTAINER (popover), editor);
gtk_popover_popup (GTK_POPOVER (popover));
g_signal_connect (popover, "hide", G_CALLBACK (gtk_widget_destroy), NULL);
g_free (name);
g_free (prefix);
}
static void static void
gtk_inspector_actions_class_init (GtkInspectorActionsClass *klass) gtk_inspector_actions_class_init (GtkInspectorActionsClass *klass)
{ {
GtkWidgetClass *widget_class = GTK_WIDGET_CLASS (klass); GtkWidgetClass *widget_class = GTK_WIDGET_CLASS (klass);
gtk_widget_class_set_template_from_resource (widget_class, "/org/gtk/libgtk/inspector/actions.ui"); gtk_widget_class_set_template_from_resource (widget_class, "/org/gtk/libgtk/inspector/actions.ui");
gtk_widget_class_bind_template_child_private (widget_class, GtkInspectorActions, model); gtk_widget_class_bind_template_child_private (widget_class, GtkInspectorActions, list);
gtk_widget_class_bind_template_callback (widget_class, row_activated); gtk_widget_class_bind_template_child_private (widget_class, GtkInspectorActions, prefix);
gtk_widget_class_bind_template_child_private (widget_class, GtkInspectorActions, name);
gtk_widget_class_bind_template_child_private (widget_class, GtkInspectorActions, enabled);
gtk_widget_class_bind_template_child_private (widget_class, GtkInspectorActions, parameter);
gtk_widget_class_bind_template_child_private (widget_class, GtkInspectorActions, state);
} }
// vim: set et sw=2 ts=2: // vim: set et sw=2 ts=2:

View File

@ -1,3 +1,4 @@
<?xml version="1.0" encoding="UTF-8"?>
<interface domain="gtk40"> <interface domain="gtk40">
<object class="GtkListStore" id="model"> <object class="GtkListStore" id="model">
<columns> <columns>
@ -11,84 +12,89 @@
</object> </object>
<template class="GtkInspectorActions" parent="GtkBox"> <template class="GtkInspectorActions" parent="GtkBox">
<property name="orientation">vertical</property> <property name="orientation">vertical</property>
<style>
<class name="view"/>
</style>
<child>
<object class="GtkBox">
<style>
<class name="header"/>
</style>
<child>
<object class="GtkLabel" id="prefix_heading">
<property name="label" translatable="yes">Prefix</property>
<property name="xalign">0</property>
</object>
</child>
<child>
<object class="GtkLabel" id="name_heading">
<property name="label" translatable="yes">Name</property>
<property name="xalign">0</property>
</object>
</child>
<child>
<object class="GtkLabel" id="enabled_heading">
<property name="label" translatable="yes">Enabled</property>
<property name="xalign">0</property>
</object>
</child>
<child>
<object class="GtkLabel" id="parameter_heading">
<property name="label" translatable="yes">Parameter Type</property>
<property name="xalign">0</property>
</object>
</child>
<child>
<object class="GtkLabel" id="state_heading">
<property name="label" translatable="yes">State</property>
<property name="xalign">0</property>
</object>
</child>
</object>
</child>
<child> <child>
<object class="GtkScrolledWindow"> <object class="GtkScrolledWindow">
<property name="expand">1</property> <property name="expand">1</property>
<property name="hscrollbar-policy">never</property> <property name="hscrollbar-policy">never</property>
<child> <child>
<object class="GtkTreeView"> <object class="GtkListBox" id="list">
<property name="model">model</property> <style>
<property name="enable-search">0</property> <class name="list"/>
<property name="activate-on-single-click">1</property> </style>
<signal name="row-activated" handler="row_activated"/> <property name="selection-mode">none</property>
<child>
<object class="GtkTreeViewColumn">
<property name="title" translatable="yes">Prefix</property>
<child>
<object class="GtkCellRendererText">
<property name="scale">0.8</property>
</object>
<attributes>
<attribute name="text">0</attribute>
</attributes>
</child>
</object>
</child>
<child>
<object class="GtkTreeViewColumn">
<property name="title" translatable="yes">Name</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">
<property name="title" translatable="yes">Enabled</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">
<property name="title" translatable="yes">Parameter Type</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">
<property name="title" translatable="yes">State</property>
<child>
<object class="GtkCellRendererText">
<property name="scale">0.8</property>
</object>
<attributes>
<attribute name="text">4</attribute>
</attributes>
</child>
</object>
</child>
</object> </object>
</child> </child>
</object> </object>
</child> </child>
</template> </template>
<object class="GtkSizeGroup" id="prefix">
<property name="mode">horizontal</property>
<widgets>
<widget name="prefix_heading"/>
</widgets>
</object>
<object class="GtkSizeGroup" id="name">
<property name="mode">horizontal</property>
<widgets>
<widget name="name_heading"/>
</widgets>
</object>
<object class="GtkSizeGroup" id="enabled">
<property name="mode">horizontal</property>
<widgets>
<widget name="enabled_heading"/>
</widgets>
</object>
<object class="GtkSizeGroup" id="parameter">
<property name="mode">horizontal</property>
<widgets>
<widget name="parameter_heading"/>
</widgets>
</object>
<object class="GtkSizeGroup" id="state">
<property name="mode">horizontal</property>
<widgets>
<widget name="state_heading"/>
</widgets>
</object>
</interface> </interface>