forked from AuroraMiddleware/gtk
inspector: Redo the CSS node page
Showing two lists in a paned was a bit awkward, and space was getting too limited. Go back to showing just the node list at first, and make the CSS properties available via a stack. At the same time, add a right-click context menu to the node list to make the name and class editing more easily available.
This commit is contained in:
parent
6f1c945010
commit
326f4739ca
@ -41,6 +41,8 @@
|
||||
#include "gtktreeview.h"
|
||||
#include "gtktreeselection.h"
|
||||
#include "gtktypebuiltins.h"
|
||||
#include "gtkmodelbutton.h"
|
||||
#include "gtkstack.h"
|
||||
|
||||
enum {
|
||||
COLUMN_NODE_NAME,
|
||||
@ -63,6 +65,10 @@ enum
|
||||
struct _GtkInspectorCssNodeTreePrivate
|
||||
{
|
||||
GtkWidget *node_tree;
|
||||
GtkWidget *stack;
|
||||
GtkWidget *node_list_button;
|
||||
GtkWidget *prop_list_button;
|
||||
GtkWidget *css_node_info;
|
||||
GtkTreeModel *node_model;
|
||||
GtkTreeViewColumn *node_name_column;
|
||||
GtkTreeViewColumn *node_id_column;
|
||||
@ -77,37 +83,23 @@ struct _GtkInspectorCssNodeTreePrivate
|
||||
|
||||
G_DEFINE_TYPE_WITH_PRIVATE (GtkInspectorCssNodeTree, gtk_inspector_css_node_tree, GTK_TYPE_BOX)
|
||||
|
||||
static void
|
||||
row_activated (GtkTreeView *tv,
|
||||
GtkTreePath *path,
|
||||
GtkTreeViewColumn *col,
|
||||
GtkInspectorCssNodeTree *cnt)
|
||||
{
|
||||
GtkTreeIter iter;
|
||||
GdkRectangle rect;
|
||||
GtkWidget *editor;
|
||||
GtkWidget *popover;
|
||||
typedef struct {
|
||||
GtkCssNode *node;
|
||||
const gchar *prop_name;
|
||||
GdkRectangle rect;
|
||||
GtkInspectorCssNodeTree *cnt;
|
||||
} NodePropEditor;
|
||||
|
||||
if (col == cnt->priv->node_name_column)
|
||||
prop_name = "name";
|
||||
else if (col == cnt->priv->node_id_column)
|
||||
prop_name = "id";
|
||||
else if (col == cnt->priv->node_classes_column)
|
||||
prop_name = "classes";
|
||||
else
|
||||
return;
|
||||
static void
|
||||
show_node_prop_editor (NodePropEditor *npe)
|
||||
{
|
||||
GtkWidget *popover;
|
||||
GtkWidget *editor;
|
||||
|
||||
gtk_tree_model_get_iter (cnt->priv->node_model, &iter, path);
|
||||
node = gtk_tree_model_css_node_get_node_from_iter (GTK_TREE_MODEL_CSS_NODE (cnt->priv->node_model), &iter);
|
||||
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 (npe->cnt->priv->node_tree));
|
||||
gtk_popover_set_pointing_to (GTK_POPOVER (popover), &npe->rect);
|
||||
|
||||
popover = gtk_popover_new (GTK_WIDGET (tv));
|
||||
gtk_popover_set_pointing_to (GTK_POPOVER (popover), &rect);
|
||||
|
||||
editor = gtk_inspector_prop_editor_new (G_OBJECT (node), prop_name, FALSE);
|
||||
editor = gtk_inspector_prop_editor_new (G_OBJECT (npe->node), npe->prop_name, FALSE);
|
||||
gtk_widget_show (editor);
|
||||
|
||||
gtk_container_add (GTK_CONTAINER (popover), editor);
|
||||
@ -120,12 +112,169 @@ row_activated (GtkTreeView *tv,
|
||||
g_signal_connect (popover, "unmap", G_CALLBACK (gtk_widget_destroy), NULL);
|
||||
}
|
||||
|
||||
static void populate_properties (GtkInspectorCssNodeTree *cnt);
|
||||
static void
|
||||
row_activated (GtkTreeView *tv,
|
||||
GtkTreePath *path,
|
||||
GtkTreeViewColumn *col,
|
||||
GtkInspectorCssNodeTree *cnt)
|
||||
{
|
||||
GtkTreeIter iter;
|
||||
NodePropEditor npe;
|
||||
|
||||
npe.cnt = cnt;
|
||||
|
||||
if (col == cnt->priv->node_name_column)
|
||||
npe.prop_name = "name";
|
||||
else if (col == cnt->priv->node_id_column)
|
||||
npe.prop_name = "id";
|
||||
else if (col == cnt->priv->node_classes_column)
|
||||
npe.prop_name = "classes";
|
||||
else
|
||||
return;
|
||||
|
||||
gtk_tree_model_get_iter (cnt->priv->node_model, &iter, path);
|
||||
npe.node = gtk_tree_model_css_node_get_node_from_iter (GTK_TREE_MODEL_CSS_NODE (cnt->priv->node_model), &iter);
|
||||
gtk_tree_view_get_cell_area (tv, path, col, &npe.rect);
|
||||
gtk_tree_view_convert_bin_window_to_widget_coords (tv, npe.rect.x, npe.rect.y, &npe.rect.x, &npe.rect.y);
|
||||
|
||||
show_node_prop_editor (&npe);
|
||||
}
|
||||
|
||||
static void
|
||||
switch_to_node_list (GtkInspectorCssNodeTree *cnt)
|
||||
{
|
||||
gtk_stack_set_visible_child_name (GTK_STACK (cnt->priv->stack), "node-list");
|
||||
gtk_widget_show (cnt->priv->prop_list_button);
|
||||
gtk_widget_hide (cnt->priv->node_list_button);
|
||||
}
|
||||
|
||||
static void
|
||||
switch_to_prop_list (GtkInspectorCssNodeTree *cnt)
|
||||
{
|
||||
gtk_stack_set_visible_child_name (GTK_STACK (cnt->priv->stack), "prop-list");
|
||||
gtk_widget_show (cnt->priv->node_list_button);
|
||||
gtk_widget_hide (cnt->priv->prop_list_button);
|
||||
}
|
||||
|
||||
static void
|
||||
show_node_popover (GtkInspectorCssNodeTree *cnt,
|
||||
gdouble x,
|
||||
gdouble y)
|
||||
{
|
||||
GtkTreeSelection *selection;
|
||||
GdkRectangle rect;
|
||||
GtkWidget *popover;
|
||||
GtkWidget *box;
|
||||
GtkWidget *button;
|
||||
GtkTreeIter iter;
|
||||
GtkTreePath *path;
|
||||
NodePropEditor *npe;
|
||||
GtkCssNode *node;
|
||||
|
||||
selection = gtk_tree_view_get_selection (GTK_TREE_VIEW (cnt->priv->node_tree));
|
||||
if (!gtk_tree_selection_get_selected (selection, NULL, &iter))
|
||||
return;
|
||||
|
||||
path = gtk_tree_model_get_path (cnt->priv->node_model, &iter);
|
||||
gtk_tree_view_get_cell_area (GTK_TREE_VIEW (cnt->priv->node_tree), path, NULL, &rect);
|
||||
gtk_tree_view_convert_bin_window_to_widget_coords (GTK_TREE_VIEW (cnt->priv->node_tree),
|
||||
rect.x, rect.y, &rect.x, &rect.y);
|
||||
|
||||
rect.x = CLAMP (x - 20, 0, gtk_widget_get_allocated_width (cnt->priv->node_tree) - 40);
|
||||
rect.width = 40;
|
||||
|
||||
node = gtk_tree_model_css_node_get_node_from_iter (GTK_TREE_MODEL_CSS_NODE (cnt->priv->node_model), &iter);
|
||||
|
||||
npe = g_new0 (NodePropEditor, 1);
|
||||
npe->node = node;
|
||||
npe->prop_name = "name";
|
||||
npe->rect = rect;
|
||||
npe->cnt = cnt;
|
||||
|
||||
popover = gtk_popover_new (GTK_WIDGET (cnt->priv->node_tree));
|
||||
|
||||
gtk_popover_set_pointing_to (GTK_POPOVER (popover), &rect);
|
||||
box = g_object_new (GTK_TYPE_BOX,
|
||||
"orientation", GTK_ORIENTATION_VERTICAL,
|
||||
"visible", TRUE,
|
||||
"margin", 10,
|
||||
NULL);
|
||||
gtk_container_add (GTK_CONTAINER (popover), box);
|
||||
button = g_object_new (GTK_TYPE_MODEL_BUTTON,
|
||||
"visible", TRUE,
|
||||
"text", _("Change name"),
|
||||
NULL);
|
||||
g_signal_connect_swapped (button, "clicked", G_CALLBACK (show_node_prop_editor), npe);
|
||||
g_object_set_data_full (G_OBJECT (popover), "prop-name", npe, g_free);
|
||||
|
||||
gtk_container_add (GTK_CONTAINER (box), button);
|
||||
|
||||
npe = g_new0 (NodePropEditor, 1);
|
||||
npe->node = node;
|
||||
npe->prop_name = "classes";
|
||||
npe->rect = rect;
|
||||
npe->cnt = cnt;
|
||||
|
||||
button = g_object_new (GTK_TYPE_MODEL_BUTTON,
|
||||
"visible", TRUE,
|
||||
"text", _("Change classes"),
|
||||
NULL);
|
||||
g_signal_connect_swapped (button, "clicked", G_CALLBACK (show_node_prop_editor), npe);
|
||||
g_object_set_data_full (G_OBJECT (popover), "prop-classes", npe, g_free);
|
||||
|
||||
gtk_container_add (GTK_CONTAINER (box), button);
|
||||
|
||||
button = g_object_new (GTK_TYPE_MODEL_BUTTON,
|
||||
"visible", TRUE,
|
||||
"text", _("CSS properties"),
|
||||
NULL);
|
||||
g_signal_connect_swapped (button, "clicked", G_CALLBACK (switch_to_prop_list), cnt);
|
||||
gtk_container_add (GTK_CONTAINER (box), button);
|
||||
|
||||
gtk_tree_path_free (path);
|
||||
|
||||
gtk_widget_show (popover);
|
||||
|
||||
g_signal_connect (popover, "unmap", G_CALLBACK (gtk_widget_destroy), NULL);
|
||||
}
|
||||
|
||||
static gboolean
|
||||
button_pressed (GtkWidget *widget,
|
||||
GdkEventButton *event,
|
||||
GtkInspectorCssNodeTree *cnt)
|
||||
{
|
||||
static gboolean in_press = FALSE;
|
||||
|
||||
if (in_press)
|
||||
return FALSE;
|
||||
|
||||
if (!gdk_event_triggers_context_menu ((GdkEvent *)event))
|
||||
return FALSE;
|
||||
|
||||
in_press = TRUE;
|
||||
gtk_widget_event (cnt->priv->node_tree, (GdkEvent *) event);
|
||||
in_press = FALSE;
|
||||
|
||||
show_node_popover (cnt, event->x, event->y);
|
||||
|
||||
return TRUE;
|
||||
}
|
||||
|
||||
static void
|
||||
gtk_inspector_css_node_tree_set_node (GtkInspectorCssNodeTree *cnt,
|
||||
GtkCssNode *node);
|
||||
|
||||
static void
|
||||
selection_changed (GtkTreeSelection *selection, GtkInspectorCssNodeTree *cnt)
|
||||
{
|
||||
populate_properties (cnt);
|
||||
GtkTreeIter iter;
|
||||
GtkCssNode *node;
|
||||
|
||||
if (!gtk_tree_selection_get_selected (selection, NULL, &iter))
|
||||
return;
|
||||
|
||||
node = gtk_tree_model_css_node_get_node_from_iter (GTK_TREE_MODEL_CSS_NODE (cnt->priv->node_model), &iter);
|
||||
gtk_inspector_css_node_tree_set_node (cnt, node);
|
||||
}
|
||||
|
||||
static void
|
||||
@ -189,9 +338,16 @@ gtk_inspector_css_node_tree_class_init (GtkInspectorCssNodeTreeClass *klass)
|
||||
gtk_widget_class_bind_template_child_private (widget_class, GtkInspectorCssNodeTree, prop_name_column);
|
||||
gtk_widget_class_bind_template_child_private (widget_class, GtkInspectorCssNodeTree, prop_model);
|
||||
gtk_widget_class_bind_template_child_private (widget_class, GtkInspectorCssNodeTree, prop_name_column);
|
||||
gtk_widget_class_bind_template_child_private (widget_class, GtkInspectorCssNodeTree, stack);
|
||||
gtk_widget_class_bind_template_child_private (widget_class, GtkInspectorCssNodeTree, prop_list_button);
|
||||
gtk_widget_class_bind_template_child_private (widget_class, GtkInspectorCssNodeTree, node_list_button);
|
||||
gtk_widget_class_bind_template_child_private (widget_class, GtkInspectorCssNodeTree, css_node_info);
|
||||
|
||||
gtk_widget_class_bind_template_callback (widget_class, row_activated);
|
||||
gtk_widget_class_bind_template_callback (widget_class, selection_changed);
|
||||
gtk_widget_class_bind_template_callback (widget_class, button_pressed);
|
||||
gtk_widget_class_bind_template_callback (widget_class, switch_to_node_list);
|
||||
gtk_widget_class_bind_template_callback (widget_class, switch_to_prop_list);
|
||||
}
|
||||
|
||||
static int
|
||||
@ -351,10 +507,14 @@ gtk_inspector_css_node_tree_set_object (GtkInspectorCssNodeTree *cnt,
|
||||
|
||||
if (!GTK_IS_WIDGET (object))
|
||||
{
|
||||
gtk_tree_model_css_node_set_root_node (GTK_TREE_MODEL_CSS_NODE (priv->node_model), NULL);
|
||||
gtk_widget_hide (GTK_WIDGET (cnt));
|
||||
return;
|
||||
}
|
||||
|
||||
gtk_widget_show (GTK_WIDGET (cnt));
|
||||
|
||||
switch_to_node_list (cnt);
|
||||
|
||||
root = node = gtk_widget_get_css_node (GTK_WIDGET (object));
|
||||
while (gtk_css_node_get_parent (root))
|
||||
root = gtk_css_node_get_parent (root);
|
||||
@ -426,6 +586,11 @@ gtk_inspector_css_node_tree_set_node (GtkInspectorCssNodeTree *cnt,
|
||||
GtkCssNode *node)
|
||||
{
|
||||
GtkInspectorCssNodeTreePrivate *priv = cnt->priv;
|
||||
GString *s;
|
||||
GType type;
|
||||
const gchar *name;
|
||||
gchar **strv;
|
||||
gint i;
|
||||
|
||||
if (priv->node == node)
|
||||
return;
|
||||
@ -443,22 +608,37 @@ gtk_inspector_css_node_tree_set_node (GtkInspectorCssNodeTree *cnt,
|
||||
priv->node = node;
|
||||
|
||||
g_signal_connect (node, "style-changed", G_CALLBACK (gtk_inspector_css_node_tree_update_style), cnt);
|
||||
}
|
||||
|
||||
static void
|
||||
populate_properties (GtkInspectorCssNodeTree *cnt)
|
||||
{
|
||||
GtkInspectorCssNodeTreePrivate *priv = cnt->priv;
|
||||
GtkTreeSelection *selection;
|
||||
GtkTreeIter titer;
|
||||
GtkCssNode *node;
|
||||
s = g_string_new ("");
|
||||
type = gtk_css_node_get_widget_type (node);
|
||||
if (type != G_TYPE_NONE && type != G_TYPE_INVALID)
|
||||
g_string_append (s, g_type_name (type));
|
||||
|
||||
selection = gtk_tree_view_get_selection (GTK_TREE_VIEW (priv->node_tree));
|
||||
if (!gtk_tree_selection_get_selected (selection, NULL, &titer))
|
||||
return;
|
||||
name = gtk_css_node_get_name (node);
|
||||
if (name)
|
||||
{
|
||||
if (s->len > 0)
|
||||
g_string_append (s, " — ");
|
||||
g_string_append (s, name);
|
||||
}
|
||||
|
||||
node = gtk_tree_model_css_node_get_node_from_iter (GTK_TREE_MODEL_CSS_NODE (priv->node_model), &titer);
|
||||
gtk_inspector_css_node_tree_set_node (cnt, node);
|
||||
strv = gtk_css_node_get_classes (node);
|
||||
if (strv[0] != NULL)
|
||||
{
|
||||
strv_sort (strv);
|
||||
if (s->len > 0)
|
||||
g_string_append (s, " — ");
|
||||
for (i = 0; strv[i]; i++)
|
||||
{
|
||||
if (i > 0)
|
||||
g_string_append (s, " ");
|
||||
g_string_append (s, strv[i]);
|
||||
}
|
||||
g_strfreev (strv);
|
||||
}
|
||||
|
||||
gtk_label_set_label (GTK_LABEL (cnt->priv->css_node_info), s->str);
|
||||
g_string_free (s, TRUE);
|
||||
}
|
||||
|
||||
// vim: set et sw=2 ts=2:
|
||||
|
@ -12,17 +12,65 @@
|
||||
<template class="GtkInspectorCssNodeTree" parent="GtkBox">
|
||||
<property name="orientation">vertical</property>
|
||||
<child>
|
||||
<object class="GtkBox">
|
||||
<property name="visible">1</property>
|
||||
<property name="margin-start">6</property>
|
||||
<property name="margin-end">6</property>
|
||||
<child type="center">
|
||||
<object class="GtkLabel" id="object_title">
|
||||
<property name="visible">1</property>
|
||||
<property name="valign">center</property>
|
||||
<property name="margin-top">12</property>
|
||||
<property name="margin-bottom">12</property>
|
||||
<property name="margin">12</property>
|
||||
</object>
|
||||
</child>
|
||||
<child>
|
||||
<object class="GtkPaned">
|
||||
<object class="GtkButton" id="node_list_button">
|
||||
<property name="valign">center</property>
|
||||
<property name="no-show-all">1</property>
|
||||
<property name="relief">none</property>
|
||||
<property name="tooltip-text" translatable="yes">Show all CSS nodes</property>
|
||||
<signal name="clicked" handler="switch_to_node_list" swapped="1"/>
|
||||
<child>
|
||||
<object class="GtkImage">
|
||||
<property name="visible">1</property>
|
||||
<property name="orientation">vertical</property>
|
||||
<property name="icon-name">pan-start-symbolic</property>
|
||||
<property name="icon-size">1</property>
|
||||
</object>
|
||||
</child>
|
||||
<style>
|
||||
<class name="image-button"/>
|
||||
</style>
|
||||
</object>
|
||||
</child>
|
||||
<child>
|
||||
<object class="GtkButton" id="prop_list_button">
|
||||
<property name="visible">1</property>
|
||||
<property name="valign">center</property>
|
||||
<property name="no-show-all">1</property>
|
||||
<property name="relief">none</property>
|
||||
<property name="tooltip-text" translatable="yes">Show CSS properties</property>
|
||||
<signal name="clicked" handler="switch_to_prop_list" swapped="1"/>
|
||||
<child>
|
||||
<object class="GtkImage">
|
||||
<property name="visible">1</property>
|
||||
<property name="icon-name">pan-end-symbolic</property>
|
||||
<property name="icon-size">1</property>
|
||||
</object>
|
||||
</child>
|
||||
<style>
|
||||
<class name="image-button"/>
|
||||
</style>
|
||||
</object>
|
||||
<packing>
|
||||
<property name="pack-type">end</property>
|
||||
</packing>
|
||||
</child>
|
||||
</object>
|
||||
</child>
|
||||
<child>
|
||||
<object class="GtkStack" id="stack">
|
||||
<property name="visible">1</property>
|
||||
<property name="transition-type">slide-left-right</property>
|
||||
<child>
|
||||
<object class="GtkScrolledWindow">
|
||||
<property name="visible">1</property>
|
||||
@ -34,9 +82,9 @@
|
||||
<property name="search-column">0</property>
|
||||
<property name="enable-search">0</property>
|
||||
<signal name="row-activated" handler="row_activated"/>
|
||||
<signal name="button-press-event" handler="button_pressed"/>
|
||||
<child internal-child="selection">
|
||||
<object class="GtkTreeSelection">
|
||||
<property name="mode">single</property>
|
||||
<signal name="changed" handler="selection_changed"/>
|
||||
</object>
|
||||
</child>
|
||||
@ -108,6 +156,31 @@
|
||||
</object>
|
||||
</child>
|
||||
</object>
|
||||
<packing>
|
||||
<property name="name">node-list</property>
|
||||
</packing>
|
||||
</child>
|
||||
<child>
|
||||
<object class="GtkBox">
|
||||
<property name="visible">1</property>
|
||||
<property name="orientation">vertical</property>
|
||||
<child>
|
||||
<object class="GtkBox">
|
||||
<property name="visible">1</property>
|
||||
<property name="orientation">horizontal</property>
|
||||
<property name="margin">12</property>
|
||||
<child>
|
||||
<object class="GtkLabel">
|
||||
<property name="visible">1</property>
|
||||
<property name="label" translatable="yes">Node:</property>
|
||||
</object>
|
||||
</child>
|
||||
<child type="center">
|
||||
<object class="GtkLabel" id="css_node_info">
|
||||
<property name="visible">1</property>
|
||||
</object>
|
||||
</child>
|
||||
</object>
|
||||
</child>
|
||||
<child>
|
||||
<object class="GtkScrolledWindow">
|
||||
@ -122,7 +195,7 @@
|
||||
<property name="enable-search">0</property>
|
||||
<child>
|
||||
<object class="GtkTreeViewColumn" id="prop_name_column">
|
||||
<property name="title" translatable="yes">Property</property>
|
||||
<property name="title" translatable="yes">CSS Property</property>
|
||||
<property name="resizable">1</property>
|
||||
<property name="sort-column-id">0</property>
|
||||
<child>
|
||||
@ -172,6 +245,11 @@
|
||||
</object>
|
||||
</child>
|
||||
</object>
|
||||
<packing>
|
||||
<property name="name">prop-list</property>
|
||||
</packing>
|
||||
</child>
|
||||
</object>
|
||||
</child>
|
||||
</template>
|
||||
</interface>
|
||||
|
Loading…
Reference in New Issue
Block a user