diff --git a/gtk/inspector/Makefile.am b/gtk/inspector/Makefile.am index faa5670842..42b3c325fb 100644 --- a/gtk/inspector/Makefile.am +++ b/gtk/inspector/Makefile.am @@ -27,6 +27,8 @@ libgtkinspector_la_SOURCES = \ data-list.c \ general.h \ general.c \ + gestures.h \ + gestures.c \ init.h \ init.c \ inspect-button.c \ diff --git a/gtk/inspector/gestures.c b/gtk/inspector/gestures.c new file mode 100644 index 0000000000..b2cca152a6 --- /dev/null +++ b/gtk/inspector/gestures.c @@ -0,0 +1,262 @@ +/* + * 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 . + */ + +#include "config.h" +#include +#include "gestures.h" +#include "gtkwidgetprivate.h" +#include "widget-tree.h" + + +enum +{ + PROP_0, + PROP_WIDGET_TREE +}; + +struct _GtkInspectorGesturesPrivate +{ + GtkSizeGroup *sizegroup; + GObject *object; + GtkWidget *widget_tree; +}; + +G_DEFINE_TYPE_WITH_PRIVATE (GtkInspectorGestures, gtk_inspector_gestures, GTK_TYPE_BOX) + +static void +gtk_inspector_gestures_init (GtkInspectorGestures *sl) +{ + sl->priv = gtk_inspector_gestures_get_instance_private (sl); + sl->priv->sizegroup = gtk_size_group_new (GTK_SIZE_GROUP_HORIZONTAL); + g_object_set (sl, + "orientation", GTK_ORIENTATION_VERTICAL, + "margin", 60, + "spacing", 10, + NULL); +} + +static void +clear_all (GtkInspectorGestures *sl) +{ + GList *children, *l; + GtkWidget *child; + + children = gtk_container_get_children (GTK_CONTAINER (sl)); + for (l = children; l; l = l->next) + { + child = l->data; + gtk_container_remove (GTK_CONTAINER (sl), child); + } + g_list_free (children); +} + +static void +phase_changed_cb (GtkComboBox *combo, GtkInspectorGestures *sl) +{ + GtkWidget *row; + GtkPropagationPhase phase; + GtkGesture *gesture; + + phase = gtk_combo_box_get_active (combo); + row = gtk_widget_get_ancestor (GTK_WIDGET (combo), GTK_TYPE_LIST_BOX_ROW); + gesture = GTK_GESTURE (g_object_get_data (G_OBJECT (row), "gesture")); + gtk_gesture_attach (gesture, phase); +} + +static void +row_activated (GtkListBox *box, + GtkListBoxRow *row, + GtkInspectorGestures *sl) +{ + GObject *gesture; + + gesture = G_OBJECT (g_object_get_data (G_OBJECT (row), "gesture")); + gtk_inspector_widget_tree_select_object (GTK_INSPECTOR_WIDGET_TREE (sl->priv->widget_tree), + gesture); +} + +static void +add_gesture (GtkInspectorGestures *sl, + GObject *object, + GtkWidget *listbox, + GtkGesture *gesture, + GtkPropagationPhase phase) +{ + GtkWidget *row; + GtkWidget *box; + GtkWidget *label; + GtkWidget *combo; + + row = gtk_list_box_row_new (); + gtk_container_add (GTK_CONTAINER (listbox), row); + gtk_widget_show (row); + box = gtk_box_new (GTK_ORIENTATION_HORIZONTAL, 40); + gtk_container_add (GTK_CONTAINER (row), box); + g_object_set (box, "margin", 10, NULL); + gtk_widget_show (box); + label = gtk_label_new (g_type_name_from_instance ((GTypeInstance*)gesture)); + g_object_set (label, "xalign", 0.0, NULL); + gtk_container_add (GTK_CONTAINER (box), label); + gtk_size_group_add_widget (sl->priv->sizegroup, label); + gtk_widget_show (label); + gtk_widget_set_halign (label, GTK_ALIGN_START); + gtk_widget_set_valign (label, GTK_ALIGN_BASELINE); + + combo = gtk_combo_box_text_new (); + gtk_combo_box_text_insert_text (GTK_COMBO_BOX_TEXT (combo), GTK_PHASE_NONE, _("None")); + gtk_combo_box_text_insert_text (GTK_COMBO_BOX_TEXT (combo), GTK_PHASE_CAPTURE, _("Capture")); + gtk_combo_box_text_insert_text (GTK_COMBO_BOX_TEXT (combo), GTK_PHASE_BUBBLE, _("Bubble")); + gtk_combo_box_text_insert_text (GTK_COMBO_BOX_TEXT (combo), GTK_PHASE_TARGET, _("Target")); + gtk_combo_box_set_active (GTK_COMBO_BOX (combo), phase); + gtk_container_add (GTK_CONTAINER (box), combo); + gtk_widget_show (combo); + gtk_widget_set_halign (label, GTK_ALIGN_END); + gtk_widget_set_valign (label, GTK_ALIGN_BASELINE); + + g_object_set_data (G_OBJECT (row), "gesture", gesture); + g_signal_connect (combo, "changed", G_CALLBACK (phase_changed_cb), sl); +} + +static void +add_gesture_group (GtkInspectorGestures *sl, + GObject *object, + GtkGesture *gesture, + GHashTable *hash) +{ + GtkWidget *frame; + GtkWidget *listbox; + GList *list, *l; + GtkGesture *g; + GtkPropagationPhase phase; + + frame = gtk_frame_new (NULL); + gtk_widget_show (frame); + gtk_widget_set_halign (frame, GTK_ALIGN_CENTER); + + listbox = gtk_list_box_new (); + g_signal_connect (listbox, "row-activated", G_CALLBACK (row_activated), sl); + gtk_container_add (GTK_CONTAINER (frame), listbox); + gtk_widget_show (listbox); + gtk_list_box_set_selection_mode (GTK_LIST_BOX (listbox), GTK_SELECTION_NONE); + + list = gtk_gesture_get_group (gesture); + for (l = list; l; l = l->next) + { + g = l->data; + phase = GPOINTER_TO_INT (g_hash_table_lookup (hash, g)); + add_gesture (sl, object, listbox, g, phase); + g_hash_table_remove (hash, g); + } + g_list_free (list); + + gtk_container_add (GTK_CONTAINER (sl), frame); +} + +void +gtk_inspector_gestures_set_object (GtkInspectorGestures *sl, + GObject *object) +{ + clear_all (sl); + + if (GTK_IS_WIDGET (object)) + { + GHashTable *hash; + GHashTableIter iter; + GList *list, *l; + gint phase; + + hash = g_hash_table_new (g_direct_hash, g_direct_equal); + for (phase = GTK_PHASE_NONE; phase <= GTK_PHASE_TARGET; phase++) + { + list = _gtk_widget_list_controllers (GTK_WIDGET (object), phase); + for (l = list; l; l = l->next) + g_hash_table_insert (hash, l->data, GINT_TO_POINTER (phase)); + g_list_free (list); + } + + while (g_hash_table_size (hash) > 0) + { + gpointer key, value; + GtkGesture *gesture; + g_hash_table_iter_init (&iter, hash); + g_hash_table_iter_next (&iter, &key, &value); + gesture = key; + add_gesture_group (sl, object, gesture, hash); + } + + g_hash_table_unref (hash); + + gtk_widget_show (GTK_WIDGET (sl)); + } + else + gtk_widget_hide (GTK_WIDGET (sl)); +} + +static void +get_property (GObject *object, + guint param_id, + GValue *value, + GParamSpec *pspec) +{ + GtkInspectorGestures *sl = GTK_INSPECTOR_GESTURES (object); + + switch (param_id) + { + case PROP_WIDGET_TREE: + g_value_take_object (value, sl->priv->widget_tree); + 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) +{ + GtkInspectorGestures *sl = GTK_INSPECTOR_GESTURES (object); + + switch (param_id) + { + case PROP_WIDGET_TREE: + sl->priv->widget_tree = g_value_get_object (value); + break; + + default: + G_OBJECT_WARN_INVALID_PROPERTY_ID (object, param_id, pspec); + break; + } +} + +static void +gtk_inspector_gestures_class_init (GtkInspectorGesturesClass *klass) +{ + GObjectClass *object_class = G_OBJECT_CLASS (klass); + + object_class->get_property = get_property; + object_class->set_property = set_property; + + g_object_class_install_property (object_class, PROP_WIDGET_TREE, + g_param_spec_object ("widget-tree", "Widget Tree", "Widget tree", + GTK_TYPE_WIDGET, G_PARAM_READWRITE | G_PARAM_CONSTRUCT_ONLY)); +} + +// vim: set et sw=2 ts=2: diff --git a/gtk/inspector/gestures.h b/gtk/inspector/gestures.h new file mode 100644 index 0000000000..e4f8dcbba3 --- /dev/null +++ b/gtk/inspector/gestures.h @@ -0,0 +1,54 @@ +/* + * 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 . + */ + +#ifndef _GTK_INSPECTOR_GESTURES_H_ +#define _GTK_INSPECTOR_GESTURES_H_ + +#include + +#define GTK_TYPE_INSPECTOR_GESTURES (gtk_inspector_gestures_get_type()) +#define GTK_INSPECTOR_GESTURES(obj) (G_TYPE_CHECK_INSTANCE_CAST((obj), GTK_TYPE_INSPECTOR_GESTURES, GtkInspectorGestures)) +#define GTK_INSPECTOR_GESTURES_CLASS(klass) (G_TYPE_CHECK_CLASS_CAST((klass), GTK_TYPE_INSPECTOR_GESTURES, GtkInspectorGesturesClass)) +#define GTK_INSPECTOR_IS_GESTURES(obj) (G_TYPE_CHECK_INSTANCE_TYPE((obj), GTK_TYPE_INSPECTOR_GESTURES)) +#define GTK_INSPECTOR_IS_GESTURES_CLASS(klass) (G_TYPE_CHECK_CLASS_TYPE((klass), GTK_TYPE_INSPECTOR_GESTURES)) +#define GTK_INSPECTOR_GESTURES_GET_CLASS(obj) (G_TYPE_INSTANCE_GET_CLASS((obj), GTK_TYPE_INSPECTOR_GESTURES, GtkInspectorGesturesClass)) + + +typedef struct _GtkInspectorGesturesPrivate GtkInspectorGesturesPrivate; + +typedef struct _GtkInspectorGestures +{ + GtkBox parent; + GtkInspectorGesturesPrivate *priv; +} GtkInspectorGestures; + +typedef struct _GtkInspectorGesturesClass +{ + GtkBoxClass parent; +} GtkInspectorGesturesClass; + +G_BEGIN_DECLS + +GType gtk_inspector_gestures_get_type (void); +void gtk_inspector_gestures_set_object (GtkInspectorGestures *sl, + GObject *object); + +G_END_DECLS + +#endif // _GTK_INSPECTOR_GESTURES_H_ + +// vim: set et sw=2 ts=2: diff --git a/gtk/inspector/init.c b/gtk/inspector/init.c index 35b63f8462..08952aab3d 100644 --- a/gtk/inspector/init.c +++ b/gtk/inspector/init.c @@ -28,6 +28,7 @@ #include "css-editor.h" #include "data-list.h" #include "general.h" +#include "gestures.h" #include "object-hierarchy.h" #include "prop-list.h" #include "python-hooks.h" @@ -55,6 +56,7 @@ gtk_inspector_init (void) g_type_ensure (GTK_TYPE_INSPECTOR_CSS_EDITOR); g_type_ensure (GTK_TYPE_INSPECTOR_DATA_LIST); g_type_ensure (GTK_TYPE_INSPECTOR_GENERAL); + g_type_ensure (GTK_TYPE_INSPECTOR_GESTURES); g_type_ensure (GTK_TYPE_INSPECTOR_OBJECT_HIERARCHY); g_type_ensure (GTK_TYPE_INSPECTOR_PROP_LIST); g_type_ensure (GTK_TYPE_INSPECTOR_PYTHON_SHELL); diff --git a/gtk/inspector/window.c b/gtk/inspector/window.c index 25290ef472..72d1aad308 100644 --- a/gtk/inspector/window.c +++ b/gtk/inspector/window.c @@ -36,6 +36,7 @@ #include "button-path.h" #include "size-groups.h" #include "data-list.h" +#include "gestures.h" #include "signals-list.h" #include "actions.h" @@ -74,6 +75,8 @@ on_widget_tree_selection_changed (GtkInspectorWidgetTree *wt, gtk_inspector_size_groups_set_object (GTK_INSPECTOR_SIZE_GROUPS (iw->size_groups), selected); gtk_inspector_data_list_set_object (GTK_INSPECTOR_DATA_LIST (iw->data_list), selected); gtk_inspector_actions_set_object (GTK_INSPECTOR_ACTIONS (iw->actions), selected); + gtk_inspector_gestures_set_object (GTK_INSPECTOR_GESTURES (iw->gestures), selected); + if (GTK_IS_WIDGET (selected)) gtk_inspector_flash_widget (iw, GTK_WIDGET (selected)); } @@ -173,6 +176,7 @@ gtk_inspector_window_class_init (GtkInspectorWindowClass *klass) gtk_widget_class_bind_template_child (widget_class, GtkInspectorWindow, size_groups); gtk_widget_class_bind_template_child (widget_class, GtkInspectorWindow, data_list); gtk_widget_class_bind_template_child (widget_class, GtkInspectorWindow, actions); + gtk_widget_class_bind_template_child (widget_class, GtkInspectorWindow, gestures); gtk_widget_class_bind_template_callback (widget_class, on_inspect); gtk_widget_class_bind_template_callback (widget_class, on_widget_tree_selection_changed); diff --git a/gtk/inspector/window.h b/gtk/inspector/window.h index 1349f9590e..d32542c384 100644 --- a/gtk/inspector/window.h +++ b/gtk/inspector/window.h @@ -53,6 +53,7 @@ typedef struct GtkWidget *size_groups; GtkWidget *data_list; GtkWidget *actions; + GtkWidget *gestures; GtkWidget *widget_popup; diff --git a/gtk/inspector/window.ui b/gtk/inspector/window.ui index 4ee58ec9a2..01feaff630 100644 --- a/gtk/inspector/window.ui +++ b/gtk/inspector/window.ui @@ -239,6 +239,17 @@ Actions + + + widget_tree + + + + + True + Gestures + + True diff --git a/po/POTFILES.in b/po/POTFILES.in index 6c61ccc569..65d4a49136 100644 --- a/po/POTFILES.in +++ b/po/POTFILES.in @@ -276,6 +276,7 @@ gtk/inspector/css-editor.c gtk/inspector/css-editor.ui.h gtk/inspector/data-list.ui.h gtk/inspector/general.ui.h +gtk/inspector/gestures.c gtk/inspector/inspect-button.c gtk/inspector/object-hierarchy.ui.h gtk/inspector/prop-editor.c