inspector: Redo the object page switcher

The combobox for page switching was not very good.
Instead, do a sidebar that can be hidden.
This commit is contained in:
Matthias Clasen 2019-04-02 23:07:51 +00:00
parent 4d6acd5d76
commit 5371055495
7 changed files with 175 additions and 463 deletions

View File

@ -1,280 +0,0 @@
/*
* Copyright (c) 2016 Red Hat, Inc.
*
* This program is free software; you can redistribute it and/or modify
* it under the terms of the GNU Lesser General Public License as published by
* the Free Software Foundation; either version 2 of the License, or (at your
* option) any later version.
*
* This program is distributed in the hope that it will be useful, but
* WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY
* or FITNESS FOR A PARTICULAR PURPOSE. See the GNU Lesser General Public
* License for more details.
*
* You should have received a copy of the GNU Lesser General Public License
* along with this program; if not, write to the Free Software Foundation,
* Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA
*
*/
#include "config.h"
#include "gtkstackcombo.h"
#include "gtkbox.h"
#include "gtkstack.h"
#include "gtkcomboboxtext.h"
#include "gtkprivate.h"
#include "gtkintl.h"
struct _GtkStackCombo
{
GtkWidget parent_instance;
GtkComboBox *combo;
GtkStack *stack;
GBinding *binding;
};
struct _GtkStackComboClass {
GtkWidgetClass parent_class;
};
enum {
PROP_0,
PROP_STACK
};
G_DEFINE_TYPE (GtkStackCombo, gtk_stack_combo, GTK_TYPE_WIDGET)
static void
gtk_stack_combo_init (GtkStackCombo *self)
{
gtk_widget_set_has_surface (GTK_WIDGET (self), FALSE);
self->stack = NULL;
self->combo = GTK_COMBO_BOX (gtk_combo_box_text_new ());
gtk_widget_set_parent (GTK_WIDGET (self->combo), GTK_WIDGET (self));
}
static void gtk_stack_combo_set_stack (GtkStackCombo *self,
GtkStack *stack);
static void
rebuild_combo (GtkStackCombo *self)
{
gtk_stack_combo_set_stack (self, self->stack);
}
static void
on_child_visible_changed (GtkStackCombo *self)
{
rebuild_combo (self);
}
static void
add_child (GtkWidget *widget,
GtkStackCombo *self)
{
g_signal_handlers_disconnect_by_func (widget, G_CALLBACK (on_child_visible_changed), self);
g_signal_connect_swapped (widget, "notify::visible", G_CALLBACK (on_child_visible_changed), self);
if (gtk_widget_get_visible (widget))
{
char *name, *title;
g_object_get (gtk_stack_get_page (self->stack, widget),
"name", &name,
"title", &title,
NULL);
gtk_combo_box_text_append (GTK_COMBO_BOX_TEXT (self->combo), name, title);
g_free (name);
g_free (title);
}
}
static void
populate_combo (GtkStackCombo *self)
{
gtk_container_foreach (GTK_CONTAINER (self->stack), (GtkCallback)add_child, self);
}
static void
clear_combo (GtkStackCombo *self)
{
gtk_combo_box_text_remove_all (GTK_COMBO_BOX_TEXT (self->combo));
}
static void
on_stack_child_added (GtkContainer *container,
GtkWidget *widget,
GtkStackCombo *self)
{
rebuild_combo (self);
}
static void
on_stack_child_removed (GtkContainer *container,
GtkWidget *widget,
GtkStackCombo *self)
{
g_signal_handlers_disconnect_by_func (widget, G_CALLBACK (on_child_visible_changed), self);
rebuild_combo (self);
}
static void
disconnect_stack_signals (GtkStackCombo *self)
{
g_binding_unbind (self->binding);
self->binding = NULL;
g_signal_handlers_disconnect_by_func (self->stack, on_stack_child_added, self);
g_signal_handlers_disconnect_by_func (self->stack, on_stack_child_removed, self);
g_signal_handlers_disconnect_by_func (self->stack, disconnect_stack_signals, self);
}
static void
connect_stack_signals (GtkStackCombo *self)
{
g_signal_connect_after (self->stack, "add", G_CALLBACK (on_stack_child_added), self);
g_signal_connect_after (self->stack, "remove", G_CALLBACK (on_stack_child_removed), self);
g_signal_connect_swapped (self->stack, "destroy", G_CALLBACK (disconnect_stack_signals), self);
self->binding = g_object_bind_property (self->stack, "visible-child-name", self->combo, "active-id", G_BINDING_BIDIRECTIONAL | G_BINDING_SYNC_CREATE);
}
static void
gtk_stack_combo_set_stack (GtkStackCombo *self,
GtkStack *stack)
{
if (stack)
g_object_ref (stack);
if (self->stack)
{
disconnect_stack_signals (self);
clear_combo (self);
g_clear_object (&self->stack);
}
if (stack)
{
self->stack = stack;
populate_combo (self);
connect_stack_signals (self);
}
}
static void
gtk_stack_combo_get_property (GObject *object,
guint prop_id,
GValue *value,
GParamSpec *pspec)
{
GtkStackCombo *self = GTK_STACK_COMBO (object);
switch (prop_id)
{
case PROP_STACK:
g_value_set_object (value, self->stack);
break;
default:
G_OBJECT_WARN_INVALID_PROPERTY_ID (object, prop_id, pspec);
break;
}
}
static void
gtk_stack_combo_set_property (GObject *object,
guint prop_id,
const GValue *value,
GParamSpec *pspec)
{
GtkStackCombo *self = GTK_STACK_COMBO (object);
switch (prop_id)
{
case PROP_STACK:
if (self->stack != g_value_get_object (value))
{
gtk_stack_combo_set_stack (self, g_value_get_object (value));
g_object_notify (G_OBJECT (self), "stack");
}
break;
default:
G_OBJECT_WARN_INVALID_PROPERTY_ID (object, prop_id, pspec);
break;
}
}
static void
gtk_stack_combo_dispose (GObject *object)
{
GtkStackCombo *self = GTK_STACK_COMBO (object);
gtk_stack_combo_set_stack (self, NULL);
if (self->combo)
{
gtk_widget_unparent (GTK_WIDGET (self->combo));
self->combo = NULL;
}
G_OBJECT_CLASS (gtk_stack_combo_parent_class)->dispose (object);
}
static void
gtk_stack_combo_measure (GtkWidget *widget,
GtkOrientation orientation,
int for_size,
int *minimum,
int *natural,
int *minimum_baseline,
int *natural_baseline)
{
GtkStackCombo *self = GTK_STACK_COMBO (widget);
gtk_widget_measure (GTK_WIDGET (self->combo), orientation, for_size,
minimum, natural,
minimum_baseline, natural_baseline);
}
static void
gtk_stack_combo_size_allocate (GtkWidget *widget,
int width,
int height,
int baseline)
{
GtkStackCombo *self = GTK_STACK_COMBO (widget);
gtk_widget_size_allocate (GTK_WIDGET (self->combo),
&(GtkAllocation) {
0, 0,
width, height
}, baseline);
}
static void
gtk_stack_combo_class_init (GtkStackComboClass *class)
{
GObjectClass *object_class = G_OBJECT_CLASS (class);
GtkWidgetClass *widget_class = GTK_WIDGET_CLASS (class);
object_class->get_property = gtk_stack_combo_get_property;
object_class->set_property = gtk_stack_combo_set_property;
object_class->dispose = gtk_stack_combo_dispose;
widget_class->measure = gtk_stack_combo_measure;
widget_class->size_allocate = gtk_stack_combo_size_allocate;
g_object_class_install_property (object_class,
PROP_STACK,
g_param_spec_object ("stack",
P_("Stack"),
P_("Stack"),
GTK_TYPE_STACK,
GTK_PARAM_READWRITE |
G_PARAM_CONSTRUCT));
gtk_widget_class_set_css_name (widget_class, "stackcombo");
}

View File

@ -1,46 +0,0 @@
/*
* Copyright (c) 2016 Red Hat, Inc.
*
* This program is free software; you can redistribute it and/or modify
* it under the terms of the GNU Lesser General Public License as published by
* the Free Software Foundation; either version 2 of the License, or (at your
* option) any later version.
*
* This program is distributed in the hope that it will be useful, but
* WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY
* or FITNESS FOR A PARTICULAR PURPOSE. See the GNU Lesser General Public
* License for more details.
*
* You should have received a copy of the GNU Lesser General Public License
* along with this program; if not, write to the Free Software Foundation,
* Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA
*
*/
#ifndef __GTK_STACK_COMBO_H__
#define __GTK_STACK_COMBO_H__
#if !defined (__GTK_H_INSIDE__) && !defined (GTK_COMPILATION)
#error "Only <gtk/gtk.h> can be included directly."
#endif
#include <gtk/gtkcombobox.h>
#include <gtk/gtkstack.h>
G_BEGIN_DECLS
#define GTK_TYPE_STACK_COMBO (gtk_stack_combo_get_type ())
#define GTK_STACK_COMBO(obj) (G_TYPE_CHECK_INSTANCE_CAST ((obj), GTK_TYPE_STACK_COMBO, GtkStackCombo))
#define GTK_STACK_COMBO_CLASS(klass) (G_TYPE_CHECK_CLASS_CAST ((klass), GTK_TYPE_STACK_COMBO, GtkStackComboClass))
#define GTK_IS_STACK_COMBO(obj) (G_TYPE_CHECK_INSTANCE_TYPE ((obj), GTK_TYPE_STACK_COMBO))
#define GTK_IS_STACK_COMBO_CLASS(klass) (G_TYPE_CHECK_CLASS_TYPE ((klass), GTK_TYPE_STACK_COMBO))
#define GTK_STACK_COMBO_GET_CLASS(obj) (G_TYPE_INSTANCE_GET_CLASS ((obj), GTK_TYPE_STACK_COMBO, GtkStackComboClass))
typedef struct _GtkStackCombo GtkStackCombo;
typedef struct _GtkStackComboClass GtkStackComboClass;
GType gtk_stack_combo_get_type (void) G_GNUC_CONST;
G_END_DECLS
#endif /* __GTK_STACK_COMBO_H__ */

View File

@ -44,7 +44,6 @@
#include "statistics.h"
#include "visual.h"
#include "window.h"
#include "gtkstackcombo.h"
#include "gtkmagnifierprivate.h"
@ -78,7 +77,6 @@ gtk_inspector_init (void)
g_type_ensure (GTK_TYPE_INSPECTOR_STATISTICS);
g_type_ensure (GTK_TYPE_INSPECTOR_VISUAL);
g_type_ensure (GTK_TYPE_INSPECTOR_WINDOW);
g_type_ensure (GTK_TYPE_STACK_COMBO);
if (extension_point == NULL)
{

View File

@ -9,7 +9,6 @@ inspector_sources = files(
'fpsoverlay.c',
'general.c',
'graphdata.c',
'gtkstackcombo.c',
'gtktreemodelcssnode.c',
'highlightoverlay.c',
'init.c',

View File

@ -52,6 +52,7 @@
#include "gtkstack.h"
#include "gtktreeviewcolumn.h"
#include "gtkwindowgroup.h"
#include "gtkrevealer.h"
G_DEFINE_TYPE (GtkInspectorWindow, gtk_inspector_window, GTK_TYPE_WINDOW)
@ -267,6 +268,22 @@ object_details_changed (GtkWidget *combo,
gtk_stack_set_visible_child_name (GTK_STACK (iw->object_center_stack), "title");
}
static void
toggle_sidebar (GtkWidget *button,
GtkInspectorWindow *iw)
{
if (gtk_revealer_get_child_revealed (GTK_REVEALER (iw->sidebar_revealer)))
{
gtk_revealer_set_reveal_child (GTK_REVEALER (iw->sidebar_revealer), FALSE);
gtk_button_set_icon_name (GTK_BUTTON (button), "go-next-symbolic");
}
else
{
gtk_revealer_set_reveal_child (GTK_REVEALER (iw->sidebar_revealer), TRUE);
gtk_button_set_icon_name (GTK_BUTTON (button), "go-previous-symbolic");
}
}
static void
gtk_inspector_window_realize (GtkWidget *widget)
{
@ -322,6 +339,7 @@ gtk_inspector_window_class_init (GtkInspectorWindowClass *klass)
gtk_widget_class_bind_template_child (widget_class, GtkInspectorWindow, misc_info);
gtk_widget_class_bind_template_child (widget_class, GtkInspectorWindow, controllers);
gtk_widget_class_bind_template_child (widget_class, GtkInspectorWindow, magnifier);
gtk_widget_class_bind_template_child (widget_class, GtkInspectorWindow, sidebar_revealer);
gtk_widget_class_bind_template_callback (widget_class, gtk_inspector_on_inspect);
gtk_widget_class_bind_template_callback (widget_class, on_object_activated);
@ -330,6 +348,7 @@ gtk_inspector_window_class_init (GtkInspectorWindowClass *klass)
gtk_widget_class_bind_template_callback (widget_class, close_object_details);
gtk_widget_class_bind_template_callback (widget_class, object_details_changed);
gtk_widget_class_bind_template_callback (widget_class, notify_node);
gtk_widget_class_bind_template_callback (widget_class, toggle_sidebar);
}
static GdkDisplay *

View File

@ -71,6 +71,7 @@ typedef struct
GtkWidget *misc_info;
GtkWidget *controllers;
GtkWidget *magnifier;
GtkWidget *sidebar_revealer;
GtkWidget *selected_widget;

View File

@ -1,3 +1,4 @@
<?xml version="1.0" encoding="UTF-8"?>
<interface domain="gtk40">
<object class="GtkAdjustment" id="magnification_adjustment">
<property name="lower">1.0</property>
@ -207,43 +208,89 @@
<property name="name">object-details</property>
<property name="child">
<object class="GtkBox">
<property name="orientation">vertical</property>
<child>
<object class="GtkCenterBox">
<child type="start">
<object class="GtkBox">
<property name="spacing">10</property>
<child>
<object class="GtkStackCombo" id="stackcombo">
<property name="margin">6</property>
<property name="stack">object_details</property>
<object class="GtkRevealer" id="sidebar_revealer">
<property name="transition-type">slide-right</property>
<property name="reveal-child">1</property>
<child>
<object class="GtkStackSidebar">
<property name="stack">object_details</property>
</object>
</child>
</object>
</child>
<child>
<object class="GtkBox">
<property name="orientation">vertical</property>
<child>
<object class="GtkCenterBox">
<child type="start">
<object class="GtkBox">
<property name="spacing">10</property>
<child>
<object class="GtkButton">
<property name="icon-name">go-previous-symbolic</property>
<property name="tooltip-text" translatable="yes">Toggle Sidebar</property>
<property name="relief">none</property>
<property name="margin-start">6</property>
<property name="halign">center</property>
<property name="valign">center</property>
<signal name="clicked" handler="toggle_sidebar"/>
</object>
</child>
<child>
<object class="GtkStack" id="object_start_stack">
<child>
<object class="GtkStackPage">
<property name="name">empty</property>
<property name="child">
<object class="GtkBox"/>
</property>
</object>
</child>
<child>
<object class="GtkStackPage">
<property name="name">magnifier</property>
<property name="child">
<object class="GtkScale">
<property name="width-request">150</property>
<property name="draw-value">0</property>
<property name="adjustment">magnification_adjustment</property>
<marks>
<mark value="1.0" position="bottom"/>
<mark value="2.0" position="bottom"/>
<mark value="3.0" position="bottom"/>
<mark value="4.0" position="bottom"/>
<mark value="5.0" position="bottom"/>
</marks>
</object>
</property>
</object>
</child>
</object>
</child>
</object>
</child>
<child>
<object class="GtkStack" id="object_start_stack">
<child type="center">
<object class="GtkStack" id="object_center_stack">
<property name="transition-type">crossfade</property>
<property name="hexpand">1</property>
<property name="halign">center</property>
<child>
<object class="GtkStackPage">
<property name="name">empty</property>
<property name="name">title</property>
<property name="child">
<object class="GtkBox"/>
<object class="GtkLabel" id="object_title"/>
</property>
</object>
</child>
<child>
<object class="GtkStackPage">
<property name="name">magnifier</property>
<property name="name">prop-search</property>
<property name="child">
<object class="GtkScale">
<property name="width-request">150</property>
<property name="draw-value">0</property>
<property name="adjustment">magnification_adjustment</property>
<marks>
<mark value="1.0" position="bottom"/>
<mark value="2.0" position="bottom"/>
<mark value="3.0" position="bottom"/>
<mark value="4.0" position="bottom"/>
<mark value="5.0" position="bottom"/>
</marks>
<object class="GtkSearchEntry" id="prop_search_entry">
<property name="margin">6</property>
<property name="max-width-chars">40</property>
</object>
</property>
</object>
@ -252,127 +299,101 @@
</child>
</object>
</child>
<child type="center">
<object class="GtkStack" id="object_center_stack">
<property name="transition-type">crossfade</property>
<property name="hexpand">1</property>
<property name="halign">center</property>
<child>
<object class="GtkStack" id="object_details">
<signal name="notify::visible-child" handler="object_details_changed"/>
<child>
<object class="GtkStackPage">
<property name="name">title</property>
<property name="name">misc</property>
<property name="title" translatable="yes">Miscellaneous</property>
<property name="child">
<object class="GtkLabel" id="object_title"/>
</property>
</object>
</child>
<child>
<object class="GtkStackPage">
<property name="name">prop-search</property>
<property name="child">
<object class="GtkSearchEntry" id="prop_search_entry">
<property name="margin">6</property>
<property name="max-width-chars">40</property>
<object class="GtkInspectorMiscInfo" id="misc_info">
<property name="object-tree">object_tree</property>
</object>
</property>
</object>
</child>
</object>
</child>
</object>
</child>
<child>
<object class="GtkStack" id="object_details">
<signal name="notify::visible-child" handler="object_details_changed"/>
<child>
<object class="GtkStackPage">
<property name="name">misc</property>
<property name="title" translatable="yes">Miscellaneous</property>
<property name="child">
<object class="GtkInspectorMiscInfo" id="misc_info">
<property name="object-tree">object_tree</property>
<child>
<object class="GtkStackPage">
<property name="name">properties</property>
<property name="title" translatable="yes">Properties</property>
<property name="child">
<object class="GtkInspectorPropList" id="prop_list">
<property name="object-tree">object_tree</property>
<property name="search-entry">prop_search_entry</property>
</object>
</property>
</object>
</property>
</object>
</child>
<child>
<object class="GtkStackPage">
<property name="name">properties</property>
<property name="title" translatable="yes">Properties</property>
<property name="child">
<object class="GtkInspectorPropList" id="prop_list">
<property name="object-tree">object_tree</property>
<property name="search-entry">prop_search_entry</property>
</child>
<child>
<object class="GtkStackPage">
<property name="name">css-nodes</property>
<property name="title" translatable="yes">CSS Nodes</property>
<property name="child">
<object class="GtkInspectorCssNodeTree" id="widget_css_node_tree">
<signal name="notify::node" handler="notify_node"/>
</object>
</property>
</object>
</property>
</object>
</child>
<child>
<object class="GtkStackPage">
<property name="name">css-nodes</property>
<property name="title" translatable="yes">CSS Nodes</property>
<property name="child">
<object class="GtkInspectorCssNodeTree" id="widget_css_node_tree">
<signal name="notify::node" handler="notify_node"/>
</child>
<child>
<object class="GtkStackPage">
<property name="name">size-groups</property>
<property name="title" translatable="yes">Size Groups</property>
<property name="child">
<object class="GtkInspectorSizeGroups" id="size_groups"/>
</property>
</object>
</property>
</object>
</child>
<child>
<object class="GtkStackPage">
<property name="name">size-groups</property>
<property name="title" translatable="yes">Size Groups</property>
<property name="child">
<object class="GtkInspectorSizeGroups" id="size_groups"/>
</property>
</object>
</child>
<child>
<object class="GtkStackPage">
<property name="name">data</property>
<property name="title" translatable="yes">Data</property>
<property name="child">
<object class="GtkInspectorDataList" id="data_list"/>
</property>
</object>
</child>
<child>
<object class="GtkStackPage">
<property name="name">actions</property>
<property name="title" translatable="yes">Actions</property>
<property name="child">
<object class="GtkInspectorActions" id="actions"/>
</property>
</object>
</child>
<child>
<object class="GtkStackPage">
<property name="name">menu</property>
<property name="title" translatable="yes">Menu</property>
<property name="child">
<object class="GtkInspectorMenu" id="menu"/>
</property>
</object>
</child>
<child>
<object class="GtkStackPage">
<property name="name">controllers</property>
<property name="title" translatable="yes">Controllers</property>
<property name="child">
<object class="GtkInspectorControllers" id="controllers">
<property name="object-tree">object_tree</property>
</child>
<child>
<object class="GtkStackPage">
<property name="name">data</property>
<property name="title" translatable="yes">Data</property>
<property name="child">
<object class="GtkInspectorDataList" id="data_list"/>
</property>
</object>
</property>
</object>
</child>
<child>
<object class="GtkStackPage">
<property name="name">magnifier</property>
<property name="title" translatable="yes">Magnifier</property>
<property name="child">
<object class="GtkInspectorMagnifier" id="magnifier">
<property name="adjustment">magnification_adjustment</property>
</child>
<child>
<object class="GtkStackPage">
<property name="name">actions</property>
<property name="title" translatable="yes">Actions</property>
<property name="child">
<object class="GtkInspectorActions" id="actions"/>
</property>
</object>
</property>
</child>
<child>
<object class="GtkStackPage">
<property name="name">menu</property>
<property name="title" translatable="yes">Menu</property>
<property name="child">
<object class="GtkInspectorMenu" id="menu"/>
</property>
</object>
</child>
<child>
<object class="GtkStackPage">
<property name="name">controllers</property>
<property name="title" translatable="yes">Controllers</property>
<property name="child">
<object class="GtkInspectorControllers" id="controllers">
<property name="object-tree">object_tree</property>
</object>
</property>
</object>
</child>
<child>
<object class="GtkStackPage">
<property name="name">magnifier</property>
<property name="title" translatable="yes">Magnifier</property>
<property name="child">
<object class="GtkInspectorMagnifier" id="magnifier">
<property name="adjustment">magnification_adjustment</property>
</object>
</property>
</object>
</child>
</object>
</child>
</object>