Commit fff6b358 authored by Matthias Clasen's avatar Matthias Clasen

inspector: Redo the controllers page

Use a column view, and only show the widgets own
controllers.
parent 1fd8d3b4
......@@ -32,19 +32,21 @@
#include "gtkmaplistmodel.h"
#include "gtkpropertylookuplistmodelprivate.h"
#include "gtkscrolledwindow.h"
#include "gtksizegroup.h"
#include "gtksortlistmodel.h"
#include "gtkstack.h"
#include "gtkwidgetprivate.h"
#include "window.h"
#include "gtksignallistitemfactory.h"
#include "gtkcolumnview.h"
#include "gtkcolumnviewcolumn.h"
#include "gtklistitem.h"
#include "gtknoselection.h"
struct _GtkInspectorControllers
{
GtkWidget parent_instance;
GtkWidget *listbox;
GtkPropertyLookupListModel *model;
GtkSizeGroup *sizegroup;
GtkWidget *view;
};
struct _GtkInspectorControllersClass
......@@ -55,117 +57,160 @@ struct _GtkInspectorControllersClass
G_DEFINE_TYPE (GtkInspectorControllers, gtk_inspector_controllers, GTK_TYPE_WIDGET)
static void
row_activated (GtkListBox *box,
GtkListBoxRow *row,
row_activated (GtkColumnView *view,
guint position,
GtkInspectorControllers *self)
{
GtkInspectorWindow *iw;
GListModel *model;
GObject *controller;
iw = GTK_INSPECTOR_WINDOW (gtk_widget_get_ancestor (GTK_WIDGET (self), GTK_TYPE_INSPECTOR_WINDOW));
controller = G_OBJECT (g_object_get_data (G_OBJECT (row), "controller"));
model = G_LIST_MODEL (gtk_column_view_get_model (view));
controller = g_list_model_get_item (model, position);
gtk_inspector_window_push_object (iw, controller, CHILD_KIND_CONTROLLER, 0);
g_object_unref (controller);
}
static void
gtk_inspector_controllers_init (GtkInspectorControllers *self)
setup_row (GtkSignalListItemFactory *factory,
GtkListItem *list_item,
gpointer data)
{
GtkWidget *sw, *box;
GtkWidget *label;
self->sizegroup = gtk_size_group_new (GTK_SIZE_GROUP_HORIZONTAL);
label = gtk_label_new ("");
gtk_label_set_xalign (GTK_LABEL (label), 0);
gtk_list_item_set_child (list_item, label);
}
sw = gtk_scrolled_window_new ();
static void
bind_type (GtkSignalListItemFactory *factory,
GtkListItem *list_item,
gpointer data)
{
GtkWidget *label;
GtkEventController *controller;
box = gtk_box_new (GTK_ORIENTATION_VERTICAL, 10);
g_object_set (box,
"margin-start", 60,
"margin-end", 60,
"margin-top", 60,
"margin-bottom", 30,
NULL);
gtk_scrolled_window_set_child (GTK_SCROLLED_WINDOW (sw), box);
gtk_widget_set_hexpand (box, TRUE);
gtk_widget_set_vexpand (box, TRUE);
self->listbox = gtk_list_box_new ();
gtk_widget_add_css_class (self->listbox, "frame");
gtk_widget_set_halign (self->listbox, GTK_ALIGN_CENTER);
g_signal_connect (self->listbox, "row-activated", G_CALLBACK (row_activated), self);
gtk_list_box_set_selection_mode (GTK_LIST_BOX (self->listbox), GTK_SELECTION_NONE);
gtk_box_append (GTK_BOX (box), self->listbox);
label = gtk_list_item_get_child (list_item);
controller = gtk_list_item_get_item (list_item);
gtk_widget_set_parent (sw, GTK_WIDGET (self));
gtk_label_set_label (GTK_LABEL (label), G_OBJECT_TYPE_NAME (controller));
}
static void
phase_changed_cb (GtkDropDown *dropdown,
GParamSpec *pspec,
GtkInspectorControllers *self)
bind_name (GtkSignalListItemFactory *factory,
GtkListItem *list_item,
gpointer data)
{
GtkWidget *row;
GtkPropagationPhase phase;
GtkWidget *label;
GtkEventController *controller;
phase = gtk_drop_down_get_selected (dropdown);
row = gtk_widget_get_ancestor (GTK_WIDGET (dropdown), GTK_TYPE_LIST_BOX_ROW);
controller = GTK_EVENT_CONTROLLER (g_object_get_data (G_OBJECT (row), "controller"));
gtk_event_controller_set_propagation_phase (controller, phase);
label = gtk_list_item_get_child (list_item);
controller = gtk_list_item_get_item (list_item);
gtk_label_set_label (GTK_LABEL (label), gtk_event_controller_get_name (controller));
}
static GtkWidget *
create_controller_widget (gpointer item,
gpointer user_data)
static void
bind_phase (GtkSignalListItemFactory *factory,
GtkListItem *list_item,
gpointer data)
{
GtkInspectorControllers *self = user_data;
GtkEventController *controller = item;
GtkWidget *row;
GtkWidget *box;
GtkWidget *label;
GtkWidget *dropdown;
const char *phases[5];
row = gtk_list_box_row_new ();
gtk_list_box_row_set_activatable (GTK_LIST_BOX_ROW (row), TRUE);
box = gtk_box_new (GTK_ORIENTATION_HORIZONTAL, 40);
gtk_list_box_row_set_child (GTK_LIST_BOX_ROW (row), box);
gtk_widget_set_margin_start (box, 10);
gtk_widget_set_margin_end (box, 10);
gtk_widget_set_margin_top (box, 10);
gtk_widget_set_margin_bottom (box, 10);
label = gtk_label_new (G_OBJECT_TYPE_NAME (controller));
g_object_set (label, "xalign", 0.0, NULL);
gtk_box_append (GTK_BOX (box), label);
gtk_size_group_add_widget (self->sizegroup, label);
gtk_widget_set_halign (label, GTK_ALIGN_START);
gtk_widget_set_valign (label, GTK_ALIGN_BASELINE);
phases[0] = C_("event phase", "None");
phases[1] = C_("event phase", "Capture");
phases[2] = C_("event phase", "Bubble");
phases[3] = C_("event phase", "Target");
phases[4] = NULL;
dropdown = gtk_drop_down_new_from_strings (phases);
gtk_drop_down_set_selected (GTK_DROP_DOWN (dropdown), gtk_event_controller_get_propagation_phase (controller));
gtk_box_append (GTK_BOX (box), dropdown);
gtk_widget_set_halign (label, GTK_ALIGN_END);
gtk_widget_set_valign (label, GTK_ALIGN_BASELINE);
g_object_set_data (G_OBJECT (row), "controller", controller);
g_signal_connect (dropdown, "notify::selected", G_CALLBACK (phase_changed_cb), self);
return row;
GtkEventController *controller;
const char *name;
label = gtk_list_item_get_child (list_item);
controller = gtk_list_item_get_item (list_item);
switch (gtk_event_controller_get_propagation_phase (controller))
{
case GTK_PHASE_NONE:
name = C_("event phase", "None");
break;
case GTK_PHASE_CAPTURE:
name = C_("event phase", "Capture");
break;
case GTK_PHASE_BUBBLE:
name = C_("event phase", "Bubble");
break;
case GTK_PHASE_TARGET:
name = C_("event phase", "Target");
break;
default:
g_assert_not_reached ();
}
gtk_label_set_label (GTK_LABEL (label), name);
}
static gpointer
map_to_controllers (gpointer widget,
gpointer unused)
static void
bind_limit (GtkSignalListItemFactory *factory,
GtkListItem *list_item,
gpointer data)
{
gpointer result = gtk_widget_observe_controllers (widget);
g_object_unref (widget);
return result;
GtkWidget *label;
GtkEventController *controller;
label = gtk_list_item_get_child (list_item);
controller = gtk_list_item_get_item (list_item);
if (gtk_event_controller_get_propagation_limit (controller) == GTK_LIMIT_SAME_NATIVE)
gtk_label_set_label (GTK_LABEL (label), C_("propagation limit", "Native"));
else
gtk_label_set_label (GTK_LABEL (label), "");
}
static void
gtk_inspector_controllers_init (GtkInspectorControllers *self)
{
GtkWidget *sw;
GtkListItemFactory *factory;
GtkColumnViewColumn *column;
sw = gtk_scrolled_window_new ();
self->view = gtk_column_view_new (NULL);
factory = gtk_signal_list_item_factory_new ();
g_signal_connect (factory, "setup", G_CALLBACK (setup_row), NULL);
g_signal_connect (factory, "bind", G_CALLBACK (bind_type), NULL);
column = gtk_column_view_column_new ("Type", factory);
gtk_column_view_append_column (GTK_COLUMN_VIEW (self->view), column);
g_object_unref (column);
factory = gtk_signal_list_item_factory_new ();
g_signal_connect (factory, "setup", G_CALLBACK (setup_row), NULL);
g_signal_connect (factory, "bind", G_CALLBACK (bind_name), NULL);
column = gtk_column_view_column_new ("Name", factory);
gtk_column_view_append_column (GTK_COLUMN_VIEW (self->view), column);
g_object_unref (column);
factory = gtk_signal_list_item_factory_new ();
g_signal_connect (factory, "setup", G_CALLBACK (setup_row), NULL);
g_signal_connect (factory, "bind", G_CALLBACK (bind_phase), NULL);
column = gtk_column_view_column_new ("Phase", factory);
gtk_column_view_append_column (GTK_COLUMN_VIEW (self->view), column);
g_object_unref (column);
factory = gtk_signal_list_item_factory_new ();
g_signal_connect (factory, "setup", G_CALLBACK (setup_row), NULL);
g_signal_connect (factory, "bind", G_CALLBACK (bind_limit), NULL);
column = gtk_column_view_column_new ("Limit", factory);
gtk_column_view_append_column (GTK_COLUMN_VIEW (self->view), column);
g_object_unref (column);
g_signal_connect (self->view, "activate", G_CALLBACK (row_activated), self);
gtk_scrolled_window_set_child (GTK_SCROLLED_WINDOW (sw), self->view);
gtk_widget_set_parent (sw, GTK_WIDGET (self));
}
static int
......@@ -222,10 +267,10 @@ gtk_inspector_controllers_set_object (GtkInspectorControllers *self,
{
GtkWidget *stack;
GtkStackPage *page;
GtkMapListModel *map_model;
GtkFlattenListModel *flatten_model;
GListModel *model;
GtkSortListModel *sort_model;
GtkSorter *sorter;
GtkNoSelection *no_selection;
stack = gtk_widget_get_parent (GTK_WIDGET (self));
page = gtk_stack_get_page (GTK_STACK (stack), GTK_WIDGET (self));
......@@ -238,23 +283,14 @@ gtk_inspector_controllers_set_object (GtkInspectorControllers *self,
g_object_set (page, "visible", TRUE, NULL);
self->model = gtk_property_lookup_list_model_new (GTK_TYPE_WIDGET, "parent");
gtk_property_lookup_list_model_set_object (self->model, object);
map_model = gtk_map_list_model_new (G_LIST_MODEL (self->model), map_to_controllers, NULL, NULL);
flatten_model = gtk_flatten_list_model_new (G_LIST_MODEL (map_model));
model = gtk_widget_observe_controllers (GTK_WIDGET (object));
sorter = GTK_SORTER (gtk_custom_sorter_new (compare_controllers, NULL, NULL));
sort_model = gtk_sort_list_model_new (G_LIST_MODEL (flatten_model), sorter);
sort_model = gtk_sort_list_model_new (model, sorter);
no_selection = gtk_no_selection_new (G_LIST_MODEL (sort_model));
gtk_list_box_bind_model (GTK_LIST_BOX (self->listbox),
G_LIST_MODEL (sort_model),
create_controller_widget,
self,
NULL);
gtk_column_view_set_model (GTK_COLUMN_VIEW (self->view), GTK_SELECTION_MODEL (no_selection));
g_object_unref (sort_model);
g_object_unref (no_selection);
}
static void
......@@ -264,8 +300,6 @@ gtk_inspector_controllers_dispose (GObject *object)
gtk_widget_unparent (gtk_widget_get_first_child (GTK_WIDGET (self)));
g_clear_object (&self->sizegroup);
G_OBJECT_CLASS (gtk_inspector_controllers_parent_class)->dispose (object);
}
......
Markdown is supported
0% or .
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment