gizmo: Allow passing changing focus behavior

We need this in popovers. Maybe it could be done better
by defining one-off custom widgets.
This commit is contained in:
Matthias Clasen 2020-04-08 07:34:38 -04:00
parent 97ff1b83dc
commit 46ff9f891a
11 changed files with 82 additions and 37 deletions

View File

@ -59,6 +59,29 @@ gtk_gizmo_contains (GtkWidget *widget,
return GTK_WIDGET_CLASS (gtk_gizmo_parent_class)->contains (widget, x, y);
}
static gboolean
gtk_gizmo_focus (GtkWidget *widget,
GtkDirectionType direction)
{
GtkGizmo *self = GTK_GIZMO (widget);
if (self->focus_func)
return self->focus_func (self, direction);
return FALSE;
}
static gboolean
gtk_gizmo_grab_focus (GtkWidget *widget)
{
GtkGizmo *self = GTK_GIZMO (widget);
if (self->grab_focus_func)
return self->grab_focus_func (self);
return FALSE;
}
static void
gtk_gizmo_finalize (GObject *object)
{
@ -90,6 +113,8 @@ gtk_gizmo_class_init (GtkGizmoClass *klass)
widget_class->size_allocate = gtk_gizmo_size_allocate;
widget_class->snapshot = gtk_gizmo_snapshot;
widget_class->contains = gtk_gizmo_contains;
widget_class->grab_focus = gtk_gizmo_grab_focus;
widget_class->focus = gtk_gizmo_focus;
}
static void
@ -98,11 +123,13 @@ gtk_gizmo_init (GtkGizmo *self)
}
GtkWidget *
gtk_gizmo_new (const char *css_name,
GtkGizmoMeasureFunc measure_func,
GtkGizmoAllocateFunc allocate_func,
GtkGizmoSnapshotFunc snapshot_func,
GtkGizmoContainsFunc contains_func)
gtk_gizmo_new (const char *css_name,
GtkGizmoMeasureFunc measure_func,
GtkGizmoAllocateFunc allocate_func,
GtkGizmoSnapshotFunc snapshot_func,
GtkGizmoContainsFunc contains_func,
GtkGizmoFocusFunc focus_func,
GtkGizmoGrabFocusFunc grab_focus_func)
{
GtkGizmo *gizmo = GTK_GIZMO (g_object_new (GTK_TYPE_GIZMO,
"css-name", css_name,
@ -112,6 +139,8 @@ gtk_gizmo_new (const char *css_name,
gizmo->allocate_func = allocate_func;
gizmo->snapshot_func = snapshot_func;
gizmo->contains_func = contains_func;
gizmo->focus_func = focus_func;
gizmo->grab_focus_func = grab_focus_func;
return GTK_WIDGET (gizmo);
}

View File

@ -30,15 +30,20 @@ typedef void (* GtkGizmoSnapshotFunc) (GtkGizmo *gizmo,
typedef gboolean (* GtkGizmoContainsFunc) (GtkGizmo *gizmo,
double x,
double y);
typedef gboolean (* GtkGizmoFocusFunc) (GtkGizmo *gizmo,
GtkDirectionType direction);
typedef gboolean (* GtkGizmoGrabFocusFunc)(GtkGizmo *gizmo);
struct _GtkGizmo
{
GtkWidget parent_instance;
GtkGizmoMeasureFunc measure_func;
GtkGizmoAllocateFunc allocate_func;
GtkGizmoSnapshotFunc snapshot_func;
GtkGizmoContainsFunc contains_func;
GtkGizmoMeasureFunc measure_func;
GtkGizmoAllocateFunc allocate_func;
GtkGizmoSnapshotFunc snapshot_func;
GtkGizmoContainsFunc contains_func;
GtkGizmoFocusFunc focus_func;
GtkGizmoGrabFocusFunc grab_focus_func;
};
struct _GtkGizmoClass
@ -48,11 +53,13 @@ struct _GtkGizmoClass
GType gtk_gizmo_get_type (void) G_GNUC_CONST;
GtkWidget *gtk_gizmo_new (const char *css_name,
GtkGizmoMeasureFunc measure_func,
GtkGizmoAllocateFunc allocate_func,
GtkGizmoSnapshotFunc snapshot_func,
GtkGizmoContainsFunc contains_func);
GtkWidget *gtk_gizmo_new (const char *css_name,
GtkGizmoMeasureFunc measure_func,
GtkGizmoAllocateFunc allocate_func,
GtkGizmoSnapshotFunc snapshot_func,
GtkGizmoContainsFunc contains_func,
GtkGizmoFocusFunc focus_func,
GtkGizmoGrabFocusFunc grab_focus_func);
#endif

View File

@ -545,7 +545,7 @@ update_block_nodes (GtkLevelBar *self)
self->block_widget = g_renew (GtkWidget*, self->block_widget, n_blocks);
for (i = self->n_blocks; i < n_blocks; i++)
{
self->block_widget[i] = gtk_gizmo_new ("block", NULL, NULL, NULL, NULL);
self->block_widget[i] = gtk_gizmo_new ("block", NULL, NULL, NULL, NULL, NULL, NULL);
gtk_widget_insert_before (self->block_widget[i], GTK_WIDGET (self->trough_widget), NULL);
}
self->n_blocks = n_blocks;
@ -1022,7 +1022,8 @@ gtk_level_bar_init (GtkLevelBar *self)
gtk_level_bar_measure_trough,
gtk_level_bar_allocate_trough,
gtk_level_bar_render_trough,
NULL);
NULL,
NULL, NULL);
gtk_widget_set_parent (self->trough_widget, GTK_WIDGET (self));
gtk_level_bar_ensure_offset (self, GTK_LEVEL_BAR_OFFSET_LOW, 0.25);

View File

@ -1412,17 +1412,19 @@ gtk_notebook_init (GtkNotebook *notebook)
notebook->has_scrolled = FALSE;
notebook->header_widget = g_object_new (GTK_TYPE_BOX,
"css-name", "header",
NULL);
"css-name", "header",
NULL);
gtk_widget_add_css_class (notebook->header_widget, GTK_STYLE_CLASS_TOP);
gtk_widget_hide (notebook->header_widget);
gtk_widget_set_parent (notebook->header_widget, GTK_WIDGET (notebook));
notebook->tabs_widget = gtk_gizmo_new ("tabs",
gtk_notebook_measure_tabs,
gtk_notebook_allocate_tabs,
gtk_notebook_snapshot_tabs,
NULL);
gtk_notebook_measure_tabs,
gtk_notebook_allocate_tabs,
gtk_notebook_snapshot_tabs,
NULL,
(GtkGizmoFocusFunc)gtk_widget_focus_self,
(GtkGizmoGrabFocusFunc)gtk_widget_grab_focus_self);
gtk_widget_set_hexpand (notebook->tabs_widget, TRUE);
gtk_container_add (GTK_CONTAINER (notebook->header_widget), notebook->tabs_widget);
@ -3981,7 +3983,7 @@ gtk_notebook_insert_notebook_page (GtkNotebook *notebook,
else
sibling = notebook->arrow_widget[ARROW_RIGHT_AFTER];
page->tab_widget = gtk_gizmo_new ("tab", measure_tab, allocate_tab, NULL, NULL);
page->tab_widget = gtk_gizmo_new ("tab", measure_tab, allocate_tab, NULL, NULL, NULL, NULL);
g_object_set_data (G_OBJECT (page->tab_widget), "notebook", notebook);
gtk_widget_insert_before (page->tab_widget, notebook->tabs_widget, sibling);
controller = gtk_drop_controller_motion_new ();

View File

@ -1390,7 +1390,7 @@ gtk_paned_init (GtkPaned *paned)
gtk_widget_add_controller (GTK_WIDGET (paned), GTK_EVENT_CONTROLLER (gesture));
priv->drag_gesture = gesture;
priv->handle_widget = gtk_gizmo_new ("separator", NULL, NULL, gtk_paned_render_handle, gtk_paned_handle_contains);
priv->handle_widget = gtk_gizmo_new ("separator", NULL, NULL, gtk_paned_render_handle, gtk_paned_handle_contains, NULL, NULL);
gtk_widget_set_parent (priv->handle_widget, GTK_WIDGET (paned));
gtk_widget_set_cursor_from_name (priv->handle_widget, "col-resize");
}

View File

@ -847,7 +847,9 @@ gtk_popover_init (GtkPopover *popover)
G_CALLBACK (node_style_changed_cb), popover, 0);
g_object_unref (priv->arrow_node);
priv->contents_widget = gtk_gizmo_new ("contents", NULL, NULL, NULL, NULL);
priv->contents_widget = gtk_gizmo_new ("contents", NULL, NULL, NULL, NULL,
(GtkGizmoFocusFunc)gtk_widget_focus_child,
(GtkGizmoGrabFocusFunc)gtk_widget_grab_focus_child);
gtk_widget_set_layout_manager (priv->contents_widget, gtk_bin_layout_new ());
gtk_widget_set_parent (priv->contents_widget, GTK_WIDGET (popover));

View File

@ -459,10 +459,11 @@ gtk_progress_bar_init (GtkProgressBar *pbar)
NULL,
allocate_trough,
NULL,
NULL);
NULL,
NULL, NULL);
gtk_widget_set_parent (priv->trough_widget, GTK_WIDGET (pbar));
priv->progress_widget = gtk_gizmo_new ("progress", NULL, NULL, NULL, NULL);
priv->progress_widget = gtk_gizmo_new ("progress", NULL, NULL, NULL, NULL, NULL, NULL);
gtk_widget_set_parent (priv->progress_widget, priv->trough_widget);
/* horizontal is default */

View File

@ -548,11 +548,12 @@ gtk_range_init (GtkRange *range)
gtk_range_measure_trough,
gtk_range_allocate_trough,
gtk_range_render_trough,
NULL);
NULL,
NULL, NULL);
gtk_widget_set_parent (priv->trough_widget, GTK_WIDGET (range));
priv->slider_widget = gtk_gizmo_new ("slider", NULL, NULL, NULL, NULL);
priv->slider_widget = gtk_gizmo_new ("slider", NULL, NULL, NULL, NULL, NULL, NULL);
gtk_widget_set_parent (priv->slider_widget, priv->trough_widget);
/* Note: Order is important here.
@ -1115,7 +1116,7 @@ gtk_range_set_show_fill_level (GtkRange *range,
if (show_fill_level)
{
priv->fill_widget = gtk_gizmo_new ("fill", NULL, NULL, NULL, NULL);
priv->fill_widget = gtk_gizmo_new ("fill", NULL, NULL, NULL, NULL, NULL, NULL);
gtk_widget_insert_after (priv->fill_widget, priv->trough_widget, NULL);
update_fill_position (range);
}
@ -2757,7 +2758,7 @@ _gtk_range_set_has_origin (GtkRange *range,
if (has_origin)
{
priv->highlight_widget = gtk_gizmo_new ("highlight", NULL, NULL, NULL, NULL);
priv->highlight_widget = gtk_gizmo_new ("highlight", NULL, NULL, NULL, NULL, NULL, NULL);
gtk_widget_insert_before (priv->highlight_widget, priv->trough_widget, priv->slider_widget);
update_highlight_position (range);

View File

@ -1715,7 +1715,8 @@ gtk_scale_add_mark (GtkScale *scale,
gtk_scale_measure_marks,
gtk_scale_allocate_marks,
NULL,
NULL);
NULL,
NULL, NULL);
gtk_widget_insert_after (priv->top_marks_widget,
GTK_WIDGET (scale),
@ -1734,7 +1735,8 @@ gtk_scale_add_mark (GtkScale *scale,
gtk_scale_measure_marks,
gtk_scale_allocate_marks,
NULL,
NULL);
NULL,
NULL, NULL);
gtk_widget_insert_before (priv->bottom_marks_widget,
GTK_WIDGET (scale),
@ -1746,10 +1748,10 @@ gtk_scale_add_mark (GtkScale *scale,
marks_widget = priv->bottom_marks_widget;
}
mark->widget = gtk_gizmo_new ("mark", gtk_scale_measure_mark, gtk_scale_allocate_mark, NULL, NULL);
mark->widget = gtk_gizmo_new ("mark", gtk_scale_measure_mark, gtk_scale_allocate_mark, NULL, NULL, NULL, NULL);
g_object_set_data (G_OBJECT (mark->widget), "mark", mark);
mark->indicator_widget = gtk_gizmo_new ("indicator", NULL, NULL, NULL, NULL);
mark->indicator_widget = gtk_gizmo_new ("indicator", NULL, NULL, NULL, NULL, NULL, NULL);
gtk_widget_set_parent (mark->indicator_widget, mark->widget);
if (mark->markup && *mark->markup)
{

View File

@ -656,7 +656,7 @@ gtk_switch_init (GtkSwitch *self)
self->off_image = gtk_image_new_from_icon_name ("switch-off-symbolic");
gtk_widget_set_parent (self->off_image, GTK_WIDGET (self));
self->slider = gtk_gizmo_new ("slider", NULL, NULL, NULL, NULL);
self->slider = gtk_gizmo_new ("slider", NULL, NULL, NULL, NULL, NULL, NULL);
gtk_widget_set_parent (self->slider, GTK_WIDGET (self));
}

View File

@ -666,7 +666,7 @@ gtk_tree_popover_create_item (GtkTreePopover *popover,
gtk_cell_view_set_displayed_row (GTK_CELL_VIEW (view), path);
gtk_widget_set_hexpand (view, TRUE);
item = gtk_gizmo_new ("modelbutton", NULL, NULL, NULL, NULL);
item = gtk_gizmo_new ("modelbutton", NULL, NULL, NULL, NULL, NULL, NULL);
gtk_widget_set_layout_manager (item, gtk_box_layout_new (GTK_ORIENTATION_HORIZONTAL));
gtk_widget_add_css_class (item, "flat");