inspector: redo property editing
Move away from cell editing, and use a popover instead. This makes it easier to e.g. use a color chooser - there's just not enough room in a cell for many things. Much of this code is adapted from tests/prop-editor.c.
This commit is contained in:
@ -32,10 +32,10 @@ libgtkinspector_la_SOURCES = \
|
||||
inspect-button.c \
|
||||
object-hierarchy.h \
|
||||
object-hierarchy.c \
|
||||
prop-editor.h \
|
||||
prop-editor.c \
|
||||
prop-list.h \
|
||||
prop-list.c \
|
||||
property-cell-renderer.h \
|
||||
property-cell-renderer.c \
|
||||
python-hooks.h \
|
||||
python-hooks.c \
|
||||
python-shell.h \
|
||||
|
||||
@ -29,7 +29,6 @@
|
||||
#include "data-list.h"
|
||||
#include "general.h"
|
||||
#include "object-hierarchy.h"
|
||||
#include "property-cell-renderer.h"
|
||||
#include "prop-list.h"
|
||||
#include "python-hooks.h"
|
||||
#include "python-shell.h"
|
||||
@ -56,7 +55,6 @@ gtk_inspector_init (void)
|
||||
g_type_ensure (GTK_TYPE_INSPECTOR_DATA_LIST);
|
||||
g_type_ensure (GTK_TYPE_INSPECTOR_GENERAL);
|
||||
g_type_ensure (GTK_TYPE_INSPECTOR_OBJECT_HIERARCHY);
|
||||
g_type_ensure (GTK_TYPE_INSPECTOR_PROPERTY_CELL_RENDERER);
|
||||
g_type_ensure (GTK_TYPE_INSPECTOR_PROP_LIST);
|
||||
g_type_ensure (GTK_TYPE_INSPECTOR_PYTHON_SHELL);
|
||||
g_type_ensure (GTK_TYPE_INSPECTOR_RESOURCE_LIST);
|
||||
|
||||
1199
gtk/inspector/prop-editor.c
Normal file
1199
gtk/inspector/prop-editor.c
Normal file
File diff suppressed because it is too large
Load Diff
63
gtk/inspector/prop-editor.h
Normal file
63
gtk/inspector/prop-editor.h
Normal file
@ -0,0 +1,63 @@
|
||||
/*
|
||||
* Copyright (c) 2014 Red Hat, Inc.
|
||||
*
|
||||
* This library 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 library 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 library. If not, see <http://www.gnu.org/licenses/>.
|
||||
*/
|
||||
|
||||
#ifndef _GTK_INSPECTOR_PROP_EDITOR_H_
|
||||
#define _GTK_INSPECTOR_PROP_EDITOR_H_
|
||||
|
||||
|
||||
#include <gtk/gtk.h>
|
||||
|
||||
|
||||
#define GTK_TYPE_INSPECTOR_PROP_EDITOR (gtk_inspector_prop_editor_get_type())
|
||||
#define GTK_INSPECTOR_PROP_EDITOR(obj) (G_TYPE_CHECK_INSTANCE_CAST((obj), GTK_TYPE_INSPECTOR_PROP_EDITOR, GtkInspectorPropEditor))
|
||||
#define GTK_INSPECTOR_PROP_EDITOR_CLASS(klass) (G_TYPE_CHECK_CLASS_CAST((klass), GTK_TYPE_INSPECTOR_PROP_EDITOR, GtkInspectorPropEditorClass))
|
||||
#define GTK_INSPECTOR_IS_PROP_EDITOR(obj) (G_TYPE_CHECK_INSTANCE_TYPE((obj), GTK_TYPE_INSPECTOR_PROP_EDITOR))
|
||||
#define GTK_INSPECTOR_IS_PROP_EDITOR_CLASS(klass) (G_TYPE_CHECK_CLASS_TYPE((klass), GTK_TYPE_INSPECTOR_PROP_EDITOR))
|
||||
#define GTK_INSPECTOR_PROP_EDITOR_GET_CLASS(obj) (G_TYPE_INSTANCE_GET_CLASS((obj), GTK_TYPE_INSPECTOR_PROP_EDITOR, GtkInspectorPropEditorClass))
|
||||
|
||||
typedef struct _GtkInspectorPropEditorPrivate GtkInspectorPropEditorPrivate;
|
||||
|
||||
typedef struct
|
||||
{
|
||||
GtkBox parent;
|
||||
GtkInspectorPropEditorPrivate *priv;
|
||||
} GtkInspectorPropEditor;
|
||||
|
||||
typedef struct
|
||||
{
|
||||
GtkBoxClass parent;
|
||||
|
||||
void (*show_object) (GtkInspectorPropEditor *editor, GObject *object, const gchar *name);
|
||||
} GtkInspectorPropEditorClass;
|
||||
|
||||
|
||||
G_BEGIN_DECLS
|
||||
|
||||
|
||||
GType gtk_inspector_prop_editor_get_type (void);
|
||||
GtkWidget *gtk_inspector_prop_editor_new (GObject *object,
|
||||
const gchar *name,
|
||||
gboolean is_child_property);
|
||||
|
||||
gboolean gtk_inspector_prop_editor_should_expand (GtkInspectorPropEditor *editor);
|
||||
|
||||
G_END_DECLS
|
||||
|
||||
|
||||
#endif // _GTK_INSPECTOR_PROP_EDITOR_H_
|
||||
|
||||
// vim: set et:
|
||||
@ -22,7 +22,8 @@
|
||||
*/
|
||||
|
||||
#include "prop-list.h"
|
||||
#include "property-cell-renderer.h"
|
||||
#include "prop-editor.h"
|
||||
#include "widget-tree.h"
|
||||
|
||||
|
||||
enum
|
||||
@ -49,8 +50,7 @@ struct _GtkInspectorPropListPrivate
|
||||
GtkListStore *model;
|
||||
GHashTable *prop_iters;
|
||||
gulong notify_handler_id;
|
||||
GtkWidget *widget_tree;
|
||||
GtkCellRenderer *value_renderer;
|
||||
GtkInspectorWidgetTree *widget_tree;
|
||||
gboolean child_properties;
|
||||
GtkTreeViewColumn *attribute_column;
|
||||
GtkWidget *tree;
|
||||
@ -108,14 +108,10 @@ set_property (GObject *object,
|
||||
{
|
||||
case PROP_WIDGET_TREE:
|
||||
pl->priv->widget_tree = g_value_get_object (value);
|
||||
g_object_set_data (G_OBJECT (pl->priv->value_renderer), "gtk-inspector-widget-tree", pl->priv->widget_tree);
|
||||
break;
|
||||
|
||||
case PROP_CHILD_PROPERTIES:
|
||||
pl->priv->child_properties = g_value_get_boolean (value);
|
||||
g_object_set (pl->priv->value_renderer,
|
||||
"is-child-property", pl->priv->child_properties,
|
||||
NULL);
|
||||
break;
|
||||
|
||||
default:
|
||||
@ -124,6 +120,68 @@ set_property (GObject *object,
|
||||
}
|
||||
}
|
||||
|
||||
static void
|
||||
show_object (GtkInspectorPropEditor *editor,
|
||||
GObject *object,
|
||||
const gchar *name,
|
||||
GtkInspectorPropList *pl)
|
||||
{
|
||||
GtkTreeIter iter;
|
||||
GtkWidget *popover;
|
||||
|
||||
popover = gtk_widget_get_ancestor (GTK_WIDGET (editor), GTK_TYPE_POPOVER);
|
||||
gtk_widget_hide (popover);
|
||||
|
||||
if (gtk_inspector_widget_tree_find_object (pl->priv->widget_tree, object, &iter))
|
||||
{
|
||||
gtk_inspector_widget_tree_select_object (pl->priv->widget_tree, object);
|
||||
}
|
||||
else if (gtk_inspector_widget_tree_find_object (pl->priv->widget_tree, pl->priv->object, &iter))
|
||||
{
|
||||
gtk_inspector_widget_tree_append_object (pl->priv->widget_tree, object, &iter, name);
|
||||
gtk_inspector_widget_tree_select_object (pl->priv->widget_tree, object);
|
||||
}
|
||||
else
|
||||
{
|
||||
g_warning ("GtkInspector: couldn't find the widget in the tree");
|
||||
}
|
||||
}
|
||||
|
||||
static void
|
||||
row_activated (GtkTreeView *tv,
|
||||
GtkTreePath *path,
|
||||
GtkTreeViewColumn *col,
|
||||
GtkInspectorPropList *pl)
|
||||
{
|
||||
GtkTreeIter iter;
|
||||
GdkRectangle rect;
|
||||
gchar *name;
|
||||
GtkWidget *editor;
|
||||
GtkWidget *popover;
|
||||
|
||||
gtk_tree_model_get_iter (GTK_TREE_MODEL (pl->priv->model), &iter, path);
|
||||
gtk_tree_model_get (GTK_TREE_MODEL (pl->priv->model), &iter, COLUMN_NAME, &name, -1);
|
||||
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_prop_editor_new (pl->priv->object, name, pl->priv->child_properties);
|
||||
gtk_widget_show (editor);
|
||||
|
||||
gtk_container_add (GTK_CONTAINER (popover), editor);
|
||||
|
||||
if (gtk_inspector_prop_editor_should_expand (GTK_INSPECTOR_PROP_EDITOR (editor)))
|
||||
gtk_widget_set_vexpand (popover, TRUE);
|
||||
|
||||
g_signal_connect (editor, "show-object", G_CALLBACK (show_object), pl);
|
||||
|
||||
gtk_widget_show (popover);
|
||||
|
||||
g_free (name);
|
||||
}
|
||||
|
||||
static void
|
||||
gtk_inspector_prop_list_class_init (GtkInspectorPropListClass *klass)
|
||||
{
|
||||
@ -142,9 +200,9 @@ gtk_inspector_prop_list_class_init (GtkInspectorPropListClass *klass)
|
||||
|
||||
gtk_widget_class_set_template_from_resource (widget_class, "/org/gtk/inspector/prop-list.ui");
|
||||
gtk_widget_class_bind_template_child_private (widget_class, GtkInspectorPropList, model);
|
||||
gtk_widget_class_bind_template_child_private (widget_class, GtkInspectorPropList, value_renderer);
|
||||
gtk_widget_class_bind_template_child_private (widget_class, GtkInspectorPropList, attribute_column);
|
||||
gtk_widget_class_bind_template_child_private (widget_class, GtkInspectorPropList, tree);
|
||||
gtk_widget_class_bind_template_callback (widget_class, row_activated);
|
||||
}
|
||||
|
||||
static void
|
||||
|
||||
@ -26,6 +26,8 @@
|
||||
<property name="visible">True</property>
|
||||
<property name="model">model</property>
|
||||
<property name="tooltip-column">4</property>
|
||||
<property name="activate-on-single-click">True</property>
|
||||
<signal name="row-activated" handler="row_activated"/>
|
||||
<child>
|
||||
<object class="GtkTreeViewColumn">
|
||||
<property name="title" translatable="yes">Property</property>
|
||||
@ -47,16 +49,14 @@
|
||||
<property name="title" translatable="yes">Value</property>
|
||||
<property name="resizable">True</property>
|
||||
<child>
|
||||
<object class="GtkInspectorPropertyCellRenderer" id="value_renderer">
|
||||
<object class="GtkCellRendererText">
|
||||
<property name="scale">0.8</property>
|
||||
<property name="editable">True</property>
|
||||
<property name="editable">False</property>
|
||||
<property name="width-chars">20</property>
|
||||
<property name="ellipsize">end</property>
|
||||
</object>
|
||||
<attributes>
|
||||
<attribute name="text">1</attribute>
|
||||
<attribute name="object">3</attribute>
|
||||
<attribute name="name">0</attribute>
|
||||
<attribute name="sensitive">5</attribute>
|
||||
</attributes>
|
||||
</child>
|
||||
|
||||
@ -1,460 +0,0 @@
|
||||
/*
|
||||
* Copyright (c) 2008-2009 Christian Hammond
|
||||
* Copyright (c) 2008-2009 David Trowbridge
|
||||
*
|
||||
* Permission is hereby granted, free of charge, to any person obtaining a
|
||||
* copy of this software and associated documentation files (the "Software"),
|
||||
* to deal in the Software without restriction, including without limitation
|
||||
* the rights to use, copy, modify, merge, publish, distribute, sublicense,
|
||||
* and/or sell copies of the Software, and to permit persons to whom the
|
||||
* Software is furnished to do so, subject to the following conditions:
|
||||
*
|
||||
* The above copyright notice and this permission notice shall be included
|
||||
* in all copies or substantial portions of the Software.
|
||||
*
|
||||
* THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
|
||||
* IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
|
||||
* FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
|
||||
* AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
|
||||
* LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
|
||||
* OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN
|
||||
* THE SOFTWARE.
|
||||
*/
|
||||
|
||||
#include "property-cell-renderer.h"
|
||||
#include "widget-tree.h"
|
||||
|
||||
struct _GtkInspectorPropertyCellRendererPrivate
|
||||
{
|
||||
GObject *object;
|
||||
char *name;
|
||||
gboolean is_child_property;
|
||||
};
|
||||
|
||||
enum
|
||||
{
|
||||
PROP_0,
|
||||
PROP_OBJECT,
|
||||
PROP_NAME,
|
||||
PROP_IS_CHILD_PROPERTY
|
||||
};
|
||||
|
||||
G_DEFINE_TYPE_WITH_PRIVATE (GtkInspectorPropertyCellRenderer, gtk_inspector_property_cell_renderer, GTK_TYPE_CELL_RENDERER_TEXT);
|
||||
|
||||
static void
|
||||
gtk_inspector_property_cell_renderer_init(GtkInspectorPropertyCellRenderer *renderer)
|
||||
{
|
||||
renderer->priv = gtk_inspector_property_cell_renderer_get_instance_private (renderer);
|
||||
}
|
||||
|
||||
static void
|
||||
get_property (GObject *object,
|
||||
guint param_id,
|
||||
GValue *value,
|
||||
GParamSpec *pspec)
|
||||
{
|
||||
GtkInspectorPropertyCellRenderer *r = GTK_INSPECTOR_PROPERTY_CELL_RENDERER (object);
|
||||
|
||||
switch (param_id)
|
||||
{
|
||||
case PROP_OBJECT:
|
||||
g_value_set_object(value, r->priv->object);
|
||||
break;
|
||||
|
||||
case PROP_NAME:
|
||||
g_value_set_string(value, r->priv->name);
|
||||
break;
|
||||
|
||||
case PROP_IS_CHILD_PROPERTY:
|
||||
g_value_set_boolean (value, r->priv->is_child_property);
|
||||
break;
|
||||
|
||||
default:
|
||||
G_OBJECT_WARN_INVALID_PROPERTY_ID(object, param_id, pspec);
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
static void
|
||||
set_property (GObject *object,
|
||||
guint param_id,
|
||||
const GValue *value,
|
||||
GParamSpec *pspec)
|
||||
{
|
||||
GtkInspectorPropertyCellRenderer *r = GTK_INSPECTOR_PROPERTY_CELL_RENDERER (object);
|
||||
|
||||
switch (param_id)
|
||||
{
|
||||
case PROP_OBJECT:
|
||||
r->priv->object = g_value_get_object (value);
|
||||
break;
|
||||
|
||||
case PROP_NAME:
|
||||
g_free (r->priv->name);
|
||||
r->priv->name = g_value_dup_string (value);
|
||||
break;
|
||||
|
||||
case PROP_IS_CHILD_PROPERTY:
|
||||
r->priv->is_child_property = g_value_get_boolean (value);
|
||||
g_object_notify (object, "is-child-property");
|
||||
break;
|
||||
|
||||
default:
|
||||
G_OBJECT_WARN_INVALID_PROPERTY_ID(object, param_id, pspec);
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
static GParamSpec *
|
||||
find_property (GtkCellRenderer *renderer)
|
||||
{
|
||||
GtkInspectorPropertyCellRenderer *r = GTK_INSPECTOR_PROPERTY_CELL_RENDERER (renderer);
|
||||
|
||||
if (r->priv->is_child_property)
|
||||
{
|
||||
GtkWidget *parent;
|
||||
|
||||
parent = gtk_widget_get_parent (GTK_WIDGET (r->priv->object));
|
||||
|
||||
return gtk_container_class_find_child_property (G_OBJECT_GET_CLASS (parent), r->priv->name);
|
||||
}
|
||||
|
||||
return g_object_class_find_property (G_OBJECT_GET_CLASS (r->priv->object), r->priv->name);
|
||||
}
|
||||
|
||||
static void
|
||||
get_value (GtkCellRenderer *renderer,
|
||||
GValue *gvalue)
|
||||
{
|
||||
GtkInspectorPropertyCellRenderer *r = GTK_INSPECTOR_PROPERTY_CELL_RENDERER (renderer);
|
||||
|
||||
if (r->priv->is_child_property)
|
||||
{
|
||||
GtkWidget *widget;
|
||||
GtkWidget *parent;
|
||||
|
||||
widget = GTK_WIDGET (r->priv->object);
|
||||
parent = gtk_widget_get_parent (widget);
|
||||
|
||||
gtk_container_child_get_property (GTK_CONTAINER (parent), widget, r->priv->name, gvalue);
|
||||
}
|
||||
else
|
||||
g_object_get_property (r->priv->object, r->priv->name, gvalue);
|
||||
}
|
||||
|
||||
static void
|
||||
set_value (GtkCellRenderer *renderer,
|
||||
GValue *gvalue)
|
||||
{
|
||||
GtkInspectorPropertyCellRenderer *r = GTK_INSPECTOR_PROPERTY_CELL_RENDERER (renderer);
|
||||
|
||||
if (r->priv->is_child_property)
|
||||
{
|
||||
GtkWidget *widget;
|
||||
GtkWidget *parent;
|
||||
|
||||
widget = GTK_WIDGET (r->priv->object);
|
||||
parent = gtk_widget_get_parent (widget);
|
||||
|
||||
gtk_container_child_set_property (GTK_CONTAINER (parent), widget, r->priv->name, gvalue);
|
||||
}
|
||||
else
|
||||
g_object_set_property (r->priv->object, r->priv->name, gvalue);
|
||||
}
|
||||
|
||||
static void
|
||||
stop_editing (GtkCellEditable *editable,
|
||||
GtkCellRenderer *renderer)
|
||||
{
|
||||
GValue gvalue = {0};
|
||||
GParamSpec *prop;
|
||||
|
||||
prop = find_property (renderer);
|
||||
g_value_init(&gvalue, prop->value_type);
|
||||
|
||||
if (GTK_IS_ENTRY(editable))
|
||||
{
|
||||
gboolean canceled;
|
||||
|
||||
g_object_get (editable, "editing-canceled", &canceled, NULL);
|
||||
gtk_cell_renderer_stop_editing (renderer, canceled);
|
||||
|
||||
if (canceled)
|
||||
return;
|
||||
|
||||
if (GTK_IS_SPIN_BUTTON(editable))
|
||||
{
|
||||
gdouble value = g_ascii_strtod (gtk_entry_get_text (GTK_ENTRY (editable)), NULL);
|
||||
|
||||
if (G_IS_PARAM_SPEC_INT (prop))
|
||||
g_value_set_int (&gvalue, (gint)value);
|
||||
else if G_IS_PARAM_SPEC_UINT (prop)
|
||||
g_value_set_uint (&gvalue, (guint)value);
|
||||
else if G_IS_PARAM_SPEC_INT64 (prop)
|
||||
g_value_set_int64 (&gvalue, (gint64)value);
|
||||
else if G_IS_PARAM_SPEC_UINT64 (prop)
|
||||
g_value_set_uint64 (&gvalue, (guint64)value);
|
||||
else if G_IS_PARAM_SPEC_LONG (prop)
|
||||
g_value_set_long (&gvalue, (glong)value);
|
||||
else if G_IS_PARAM_SPEC_ULONG (prop)
|
||||
g_value_set_ulong (&gvalue, (gulong)value);
|
||||
else if G_IS_PARAM_SPEC_DOUBLE (prop)
|
||||
g_value_set_double (&gvalue, (gdouble)value);
|
||||
else
|
||||
return;
|
||||
}
|
||||
else
|
||||
{
|
||||
g_value_set_string (&gvalue, gtk_entry_get_text (GTK_ENTRY (editable)));
|
||||
}
|
||||
}
|
||||
else if (GTK_IS_COMBO_BOX (editable))
|
||||
{
|
||||
/* We have no way of getting the canceled state for a GtkComboBox */
|
||||
gtk_cell_renderer_stop_editing (renderer, FALSE);
|
||||
|
||||
if (G_IS_PARAM_SPEC_BOOLEAN (prop))
|
||||
{
|
||||
g_value_set_boolean (&gvalue, gtk_combo_box_get_active (GTK_COMBO_BOX (editable)) == 1);
|
||||
}
|
||||
else if (G_IS_PARAM_SPEC_ENUM (prop))
|
||||
{
|
||||
gchar *enum_name = gtk_combo_box_text_get_active_text (GTK_COMBO_BOX_TEXT (editable));
|
||||
GEnumClass *enum_class;
|
||||
GEnumValue *enum_value;
|
||||
|
||||
if (enum_name == NULL)
|
||||
return;
|
||||
|
||||
enum_class = G_PARAM_SPEC_ENUM (prop)->enum_class;
|
||||
enum_value = g_enum_get_value_by_name (enum_class, enum_name);
|
||||
g_value_set_enum (&gvalue, enum_value->value);
|
||||
|
||||
g_free (enum_name);
|
||||
}
|
||||
}
|
||||
|
||||
set_value (renderer, &gvalue);
|
||||
g_value_unset (&gvalue);
|
||||
}
|
||||
|
||||
static GtkCellEditable *
|
||||
start_editing (GtkCellRenderer *renderer,
|
||||
GdkEvent *event,
|
||||
GtkWidget *widget,
|
||||
const gchar *path,
|
||||
const GdkRectangle *background_area,
|
||||
const GdkRectangle *cell_area,
|
||||
GtkCellRendererState flags)
|
||||
{
|
||||
PangoFontDescription *font_desc;
|
||||
GtkCellEditable *editable = NULL;
|
||||
GValue gvalue = {0};
|
||||
GParamSpec *prop;
|
||||
GtkInspectorPropertyCellRenderer *r = GTK_INSPECTOR_PROPERTY_CELL_RENDERER (renderer);
|
||||
|
||||
prop = find_property (renderer);
|
||||
|
||||
g_value_init (&gvalue, prop->value_type);
|
||||
|
||||
get_value (renderer, &gvalue);
|
||||
|
||||
if (G_VALUE_HOLDS_OBJECT (&gvalue))
|
||||
{
|
||||
GtkInspectorWidgetTree *widget_tree = g_object_get_data (G_OBJECT (renderer), "gtk-inspector-widget-tree");
|
||||
GObject *prop_object = g_value_get_object (&gvalue);
|
||||
GtkTreeIter iter;
|
||||
|
||||
if (prop_object)
|
||||
{
|
||||
/* First check if the value is already in the tree (happens with 'parent' for instance) */
|
||||
if (gtk_inspector_widget_tree_find_object (widget_tree, prop_object, &iter))
|
||||
{
|
||||
gtk_inspector_widget_tree_select_object (widget_tree, prop_object);
|
||||
}
|
||||
else if (gtk_inspector_widget_tree_find_object (widget_tree, r->priv->object, &iter))
|
||||
{
|
||||
gtk_inspector_widget_tree_append_object (widget_tree, prop_object, &iter, prop->name);
|
||||
gtk_inspector_widget_tree_select_object (widget_tree, prop_object);
|
||||
}
|
||||
else
|
||||
{
|
||||
g_warning ("GtkInspector: couldn't find the widget in the tree");
|
||||
}
|
||||
}
|
||||
g_value_unset (&gvalue);
|
||||
return NULL;
|
||||
}
|
||||
else
|
||||
{
|
||||
if (!(prop->flags & G_PARAM_WRITABLE))
|
||||
return NULL;
|
||||
|
||||
if (G_VALUE_HOLDS_ENUM (&gvalue) || G_VALUE_HOLDS_BOOLEAN (&gvalue))
|
||||
{
|
||||
GtkWidget *combobox;
|
||||
GList *renderers;
|
||||
|
||||
combobox = gtk_combo_box_text_new ();
|
||||
gtk_widget_show (combobox);
|
||||
g_object_set (G_OBJECT (combobox), "has-frame", FALSE, NULL);
|
||||
|
||||
if (G_VALUE_HOLDS_BOOLEAN (&gvalue))
|
||||
{
|
||||
gtk_combo_box_text_append_text (GTK_COMBO_BOX_TEXT (combobox), "FALSE");
|
||||
gtk_combo_box_text_append_text (GTK_COMBO_BOX_TEXT (combobox), "TRUE");
|
||||
|
||||
gtk_combo_box_set_active (GTK_COMBO_BOX (combobox), g_value_get_boolean (&gvalue) ? 1 : 0);
|
||||
}
|
||||
else if (G_VALUE_HOLDS_ENUM(&gvalue))
|
||||
{
|
||||
gint value = g_value_get_enum (&gvalue);
|
||||
GEnumClass *enum_class = G_PARAM_SPEC_ENUM (prop)->enum_class;
|
||||
guint i;
|
||||
|
||||
for (i = 0; i < enum_class->n_values; i++)
|
||||
{
|
||||
GEnumValue *enum_value = &enum_class->values[i];
|
||||
|
||||
gtk_combo_box_text_append_text (GTK_COMBO_BOX_TEXT (combobox),
|
||||
enum_value->value_name);
|
||||
|
||||
if (enum_value->value == value)
|
||||
gtk_combo_box_set_active(GTK_COMBO_BOX(combobox), i);
|
||||
}
|
||||
}
|
||||
|
||||
renderers = gtk_cell_layout_get_cells (GTK_CELL_LAYOUT (combobox));
|
||||
g_object_set (G_OBJECT (renderers->data), "scale", 0.8, NULL);
|
||||
g_list_free (renderers);
|
||||
|
||||
editable = GTK_CELL_EDITABLE (combobox);
|
||||
}
|
||||
else if (G_VALUE_HOLDS_STRING (&gvalue))
|
||||
{
|
||||
GtkWidget *entry;
|
||||
|
||||
entry = gtk_entry_new ();
|
||||
gtk_widget_show (entry);
|
||||
gtk_entry_set_text (GTK_ENTRY (entry), g_value_get_string (&gvalue));
|
||||
|
||||
editable = GTK_CELL_EDITABLE (entry);
|
||||
}
|
||||
else if (G_VALUE_HOLDS_INT (&gvalue) ||
|
||||
G_VALUE_HOLDS_UINT (&gvalue) ||
|
||||
G_VALUE_HOLDS_INT64 (&gvalue) ||
|
||||
G_VALUE_HOLDS_UINT64 (&gvalue) ||
|
||||
G_VALUE_HOLDS_LONG (&gvalue) ||
|
||||
G_VALUE_HOLDS_ULONG (&gvalue) ||
|
||||
G_VALUE_HOLDS_DOUBLE (&gvalue))
|
||||
{
|
||||
gdouble min, max, value;
|
||||
GtkWidget *spinbutton;
|
||||
guint digits = 0;
|
||||
|
||||
if (G_VALUE_HOLDS_INT (&gvalue))
|
||||
{
|
||||
GParamSpecInt *paramspec = G_PARAM_SPEC_INT (prop);
|
||||
min = paramspec->minimum;
|
||||
max = paramspec->maximum;
|
||||
value = g_value_get_int (&gvalue);
|
||||
}
|
||||
else if (G_VALUE_HOLDS_UINT (&gvalue))
|
||||
{
|
||||
GParamSpecUInt *paramspec = G_PARAM_SPEC_UINT (prop);
|
||||
min = paramspec->minimum;
|
||||
max = paramspec->maximum;
|
||||
value = g_value_get_uint (&gvalue);
|
||||
}
|
||||
else if (G_VALUE_HOLDS_INT64 (&gvalue))
|
||||
{
|
||||
GParamSpecInt64 *paramspec = G_PARAM_SPEC_INT64 (prop);
|
||||
min = paramspec->minimum;
|
||||
max = paramspec->maximum;
|
||||
value = g_value_get_int64 (&gvalue);
|
||||
}
|
||||
else if (G_VALUE_HOLDS_UINT64 (&gvalue))
|
||||
{
|
||||
GParamSpecUInt64 *paramspec = G_PARAM_SPEC_UINT64 (prop);
|
||||
min = paramspec->minimum;
|
||||
max = paramspec->maximum;
|
||||
value = g_value_get_uint64 (&gvalue);
|
||||
}
|
||||
else if (G_VALUE_HOLDS_LONG (&gvalue))
|
||||
{
|
||||
GParamSpecLong *paramspec = G_PARAM_SPEC_LONG (prop);
|
||||
min = paramspec->minimum;
|
||||
max = paramspec->maximum;
|
||||
value = g_value_get_long (&gvalue);
|
||||
}
|
||||
else if (G_VALUE_HOLDS_ULONG (&gvalue))
|
||||
{
|
||||
GParamSpecULong *paramspec = G_PARAM_SPEC_ULONG (prop);
|
||||
min = paramspec->minimum;
|
||||
max = paramspec->maximum;
|
||||
value = g_value_get_ulong (&gvalue);
|
||||
}
|
||||
else if (G_VALUE_HOLDS_DOUBLE (&gvalue))
|
||||
{
|
||||
GParamSpecDouble *paramspec = G_PARAM_SPEC_DOUBLE (prop);
|
||||
min = paramspec->minimum;
|
||||
max = paramspec->maximum;
|
||||
value = g_value_get_double (&gvalue);
|
||||
digits = 2;
|
||||
}
|
||||
else
|
||||
{
|
||||
/* Shouldn't really be able to happen. */
|
||||
return NULL;
|
||||
}
|
||||
|
||||
spinbutton = gtk_spin_button_new_with_range (min, max, 1);
|
||||
gtk_widget_show (spinbutton);
|
||||
gtk_spin_button_set_value (GTK_SPIN_BUTTON (spinbutton), value);
|
||||
gtk_spin_button_set_digits (GTK_SPIN_BUTTON (spinbutton), digits);
|
||||
|
||||
editable = GTK_CELL_EDITABLE(spinbutton);
|
||||
}
|
||||
}
|
||||
|
||||
g_value_unset (&gvalue);
|
||||
|
||||
if (!editable)
|
||||
return NULL;
|
||||
|
||||
font_desc = pango_font_description_new ();
|
||||
pango_font_description_set_size (font_desc, 8 * PANGO_SCALE);
|
||||
gtk_widget_override_font (GTK_WIDGET (editable), font_desc);
|
||||
pango_font_description_free (font_desc);
|
||||
|
||||
g_signal_connect (editable, "editing-done", G_CALLBACK (stop_editing), renderer);
|
||||
|
||||
return editable;
|
||||
}
|
||||
|
||||
static void
|
||||
gtk_inspector_property_cell_renderer_class_init (GtkInspectorPropertyCellRendererClass *klass)
|
||||
{
|
||||
GObjectClass *object_class = G_OBJECT_CLASS (klass);
|
||||
GtkCellRendererClass *cell_class = GTK_CELL_RENDERER_CLASS (klass);
|
||||
|
||||
object_class->get_property = get_property;
|
||||
object_class->set_property = set_property;
|
||||
|
||||
cell_class->start_editing = start_editing;
|
||||
|
||||
g_object_class_install_property (object_class, PROP_OBJECT,
|
||||
g_param_spec_object ("object", "Object", "The object owning the property",
|
||||
G_TYPE_OBJECT, G_PARAM_READWRITE));
|
||||
|
||||
g_object_class_install_property (object_class, PROP_NAME,
|
||||
g_param_spec_string ("name", "Name", "The property name",
|
||||
NULL, G_PARAM_READWRITE));
|
||||
|
||||
g_object_class_install_property (object_class, PROP_IS_CHILD_PROPERTY,
|
||||
g_param_spec_boolean ("is-child-property", "Child property", "Child property",
|
||||
FALSE, G_PARAM_READWRITE));
|
||||
}
|
||||
|
||||
|
||||
// vim: set et ts=2:
|
||||
@ -1,62 +0,0 @@
|
||||
/*
|
||||
* Copyright (c) 2008-2009 Christian Hammond
|
||||
* Copyright (c) 2008-2009 David Trowbridge
|
||||
*
|
||||
* Permission is hereby granted, free of charge, to any person obtaining a
|
||||
* copy of this software and associated documentation files (the "Software"),
|
||||
* to deal in the Software without restriction, including without limitation
|
||||
* the rights to use, copy, modify, merge, publish, distribute, sublicense,
|
||||
* and/or sell copies of the Software, and to permit persons to whom the
|
||||
* Software is furnished to do so, subject to the following conditions:
|
||||
*
|
||||
* The above copyright notice and this permission notice shall be included
|
||||
* in all copies or substantial portions of the Software.
|
||||
*
|
||||
* THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
|
||||
* IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
|
||||
* FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
|
||||
* AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
|
||||
* LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
|
||||
* OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN
|
||||
* THE SOFTWARE.
|
||||
*/
|
||||
#ifndef _GTK_INSPECTOR_PROPERTY_CELL_RENDERER_H_
|
||||
#define _GTK_INSPECTOR_PROPERTY_CELL_RENDERER_H_
|
||||
|
||||
|
||||
#include <gtk/gtk.h>
|
||||
|
||||
|
||||
#define GTK_TYPE_INSPECTOR_PROPERTY_CELL_RENDERER (gtk_inspector_property_cell_renderer_get_type())
|
||||
#define GTK_INSPECTOR_PROPERTY_CELL_RENDERER(obj) (G_TYPE_CHECK_INSTANCE_CAST((obj), GTK_TYPE_INSPECTOR_PROPERTY_CELL_RENDERER, GtkInspectorPropertyCellRenderer))
|
||||
#define GTK_INSPECTOR_PROPERTY_CELL_RENDERER_CLASS(klass) (G_TYPE_CHECK_CLASS_CAST((klass), GTK_TYPE_INSPECTOR_PROPERTY_CELL_RENDERER, GtkInspectorPropertyCellRendererClass))
|
||||
#define GTK_INSPECTOR_IS_PROPERTY_CELL_RENDERER(obj) (G_TYPE_CHECK_INSTANCE_TYPE((obj), GTK_TYPE_INSPECTOR_PROPERTY_CELL_RENDERER))
|
||||
#define GTK_INSPECTOR_IS_PROPERTY_CELL_RENDERER_CLASS(klass) (G_TYPE_CHECK_CLASS_TYPE((klass), GTK_TYPE_INSPECTOR_PROPERTY_CELL_RENDERER))
|
||||
#define GTK_INSPECTOR_PROPERTY_CELL_RENDERER_GET_CLASS(obj) (G_TYPE_INSTANCE_GET_CLASS((obj), GTK_TYPE_INSPECTOR_PROPERTY_CELL_RENDERER, GtkInspectorPropertyCellRendererClass))
|
||||
|
||||
typedef struct _GtkInspectorPropertyCellRendererPrivate GtkInspectorPropertyCellRendererPrivate;
|
||||
|
||||
typedef struct
|
||||
{
|
||||
GtkCellRendererText parent;
|
||||
GtkInspectorPropertyCellRendererPrivate *priv;
|
||||
} GtkInspectorPropertyCellRenderer;
|
||||
|
||||
typedef struct
|
||||
{
|
||||
GtkCellRendererTextClass parent;
|
||||
} GtkInspectorPropertyCellRendererClass;
|
||||
|
||||
|
||||
G_BEGIN_DECLS
|
||||
|
||||
|
||||
GType gtk_inspector_property_cell_renderer_get_type (void);
|
||||
|
||||
|
||||
G_END_DECLS
|
||||
|
||||
|
||||
#endif // _GTK_INSPECTOR_PROPERTY_CELL_RENDERER_H_
|
||||
|
||||
// vim: set et sw=2 ts=2:
|
||||
@ -27,7 +27,6 @@
|
||||
#include <stdlib.h>
|
||||
#include "window.h"
|
||||
#include "prop-list.h"
|
||||
#include "property-cell-renderer.h"
|
||||
#include "classes-list.h"
|
||||
#include "css-editor.h"
|
||||
#include "object-hierarchy.h"
|
||||
|
||||
Reference in New Issue
Block a user