From 2be675b538e1229ccd2d2771130a3bfe60deda6d Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Timm=20B=C3=A4der?= Date: Thu, 6 Apr 2017 19:17:29 +0200 Subject: [PATCH] Add GtkGizmo GtkGizmo is the easiest possible widget to implement. It does nothing except give its creator a way to control measure/size-allocate/snapshot, so it can be used in a variety of use cases. --- gtk/Makefile.am | 6 +- gtk/gtkgizmo.c | 157 ++++++++++++++++++++++++++++++++++++++++++ gtk/gtkgizmoprivate.h | 58 ++++++++++++++++ 3 files changed, 219 insertions(+), 2 deletions(-) create mode 100644 gtk/gtkgizmo.c create mode 100644 gtk/gtkgizmoprivate.h diff --git a/gtk/Makefile.am b/gtk/Makefile.am index 2b357e3d5d..f66e20b4c5 100644 --- a/gtk/Makefile.am +++ b/gtk/Makefile.am @@ -575,7 +575,8 @@ gtk_private_h_sources = \ gtkwin32themeprivate.h \ gtkwindowprivate.h \ gtktreemenu.h \ - gdkpixbufutilsprivate.h + gdkpixbufutilsprivate.h \ + gtkgizmoprivate.h # GTK+ C sources to build the library from gtk_base_c_sources = \ @@ -937,7 +938,8 @@ gtk_base_c_sources = \ gtkwindowgroup.c \ gtkwin32draw.c \ gtkwin32theme.c \ - gdkpixbufutils.c + gdkpixbufutils.c \ + gtkgizmo.c if USE_QUARTZ gtk_base_c_sources += \ diff --git a/gtk/gtkgizmo.c b/gtk/gtkgizmo.c new file mode 100644 index 0000000000..5c840127b0 --- /dev/null +++ b/gtk/gtkgizmo.c @@ -0,0 +1,157 @@ + +#include "gtkgizmoprivate.h" +#include "gtkwidgetprivate.h" +#include "gtkcsscustomgadgetprivate.h" + + +G_DEFINE_TYPE (GtkGizmo, gtk_gizmo, GTK_TYPE_WIDGET); + +static void +gtk_gizmo_measure (GtkWidget *widget, + GtkOrientation orientation, + int for_size, + int *minimum, + int *natural, + int *minimum_baseline, + int *natural_baseline) +{ + GtkGizmo *self = GTK_GIZMO (widget); + + gtk_css_gadget_get_preferred_size (self->gadget, + orientation, + for_size, + minimum, natural, + minimum_baseline, natural_baseline); +} + +static void +gtk_gizmo_size_allocate (GtkWidget *widget, + GtkAllocation *allocation) +{ + GtkGizmo *self = GTK_GIZMO (widget); + GtkAllocation clip; + + GTK_WIDGET_CLASS (gtk_gizmo_parent_class)->size_allocate (widget, allocation); + + gtk_css_gadget_allocate (self->gadget, + allocation, + gtk_widget_get_allocated_baseline (widget), + &clip); + + gtk_widget_set_clip (widget, &clip); +} + +static void +gtk_gizmo_snapshot (GtkWidget *widget, + GtkSnapshot *snapshot) +{ + GtkGizmo *self = GTK_GIZMO (widget); + + gtk_css_gadget_snapshot (self->gadget, snapshot); +} + +static void +gtk_gizmo_measure_contents (GtkCssGadget *gadget, + GtkOrientation orientation, + int for_size, + int *minimum, + int *natural, + int *minimum_baseline, + int *natural_baseline, + gpointer user_data) +{ + GtkGizmo *self = GTK_GIZMO (gtk_css_gadget_get_owner (gadget)); + + if (self->measure_func) + self->measure_func (self, orientation, for_size, + minimum, natural, + minimum_baseline, natural_baseline); +} + +static void +gtk_gizmo_allocate_contents (GtkCssGadget *gadget, + const GtkAllocation *allocation, + int baseline, + GtkAllocation *out_clip, + gpointer user_data) + +{ + GtkGizmo *self = GTK_GIZMO (gtk_css_gadget_get_owner (gadget)); + + if (self->allocate_func) + self->allocate_func (self, + allocation, + baseline, + out_clip); +} + +static gboolean +gtk_gizmo_snapshot_contents (GtkCssGadget *gadget, + GtkSnapshot *snapshot, + int x, + int y, + int width, + int height, + gpointer user_data) +{ + GtkGizmo *self = GTK_GIZMO (gtk_css_gadget_get_owner (gadget)); + + if (self->snapshot_func) + return self->snapshot_func (self, snapshot); + + return FALSE; +} + +static void +gtk_gizmo_finalize (GObject *obj) +{ + GtkGizmo *self = GTK_GIZMO (obj); + + g_clear_object (&self->gadget); + + G_OBJECT_CLASS (gtk_gizmo_parent_class)->finalize (obj); +} + +static void +gtk_gizmo_class_init (GtkGizmoClass *klass) +{ + GObjectClass *object_class = G_OBJECT_CLASS (klass); + GtkWidgetClass *widget_class = GTK_WIDGET_CLASS (klass); + + object_class->finalize = gtk_gizmo_finalize; + + widget_class->measure = gtk_gizmo_measure; + widget_class->size_allocate = gtk_gizmo_size_allocate; + widget_class->snapshot = gtk_gizmo_snapshot; +} + +static void +gtk_gizmo_init (GtkGizmo *self) +{ + gtk_widget_set_has_window (GTK_WIDGET (self), FALSE); + + self->gadget = gtk_css_custom_gadget_new_for_node (gtk_widget_get_css_node (GTK_WIDGET (self)), + GTK_WIDGET (self), + gtk_gizmo_measure_contents, + gtk_gizmo_allocate_contents, + gtk_gizmo_snapshot_contents, + NULL, + NULL); +} + +GtkWidget * +gtk_gizmo_new (const char *css_name, + GtkGizmoMeasureFunc measure_func, + GtkGizmoAllocateFunc allocate_func, + GtkGizmoSnapshotFunc snapshot_func) +{ + GtkGizmo *gizmo = GTK_GIZMO (g_object_new (GTK_TYPE_GIZMO, + "css-name", css_name, + NULL)); + + gizmo->measure_func = measure_func; + gizmo->allocate_func = allocate_func; + gizmo->snapshot_func = snapshot_func; + + return GTK_WIDGET (gizmo); +} diff --git a/gtk/gtkgizmoprivate.h b/gtk/gtkgizmoprivate.h new file mode 100644 index 0000000000..5fb78420c0 --- /dev/null +++ b/gtk/gtkgizmoprivate.h @@ -0,0 +1,58 @@ + +#ifndef __GTK_GIZMO_H__ +#define __GTK_GIZMO_H__ + +#include "gtkwidget.h" +#include "gtkcssgadgetprivate.h" +#include "gtkcsscustomgadgetprivate.h" + +#define GTK_TYPE_GIZMO (gtk_gizmo_get_type ()) +#define GTK_GIZMO(obj) (G_TYPE_CHECK_INSTANCE_CAST ((obj), GTK_TYPE_GIZMO, GtkGizmo)) +#define GTK_GIZMO_CLASS(klass) (G_TYPE_CHECK_CLASS_CAST ((klass), GTK_TYPE_GIZMO, GtkGizmoClass)) +#define GTK_IS_GIZMO(obj) (G_TYPE_CHECK_INSTANCE_TYPE ((obj), GTK_TYPE_GIZMO)) +#define GTK_IS_GIZMO_CLASS(klass) (G_TYPE_CHECK_CLASS_TYPE ((klass), GTK_TYPE_GIZMO)) +#define GTK_GIZMO_GET_CLASS(obj) (G_TYPE_INSTANCE_GET_CLASS ((obj), GTK_TYPE_GIZMO, GtkGizmoClass)) + +typedef struct _GtkGizmo GtkGizmo; +typedef struct _GtkGizmoClass GtkGizmoClass; + +typedef void (* GtkGizmoMeasureFunc) (GtkGizmo *gizmo, + GtkOrientation orientation, + int for_size, + int *minimum, + int *natural, + int *minimum_baseline, + int *natural_baseline); +typedef void (* GtkGizmoAllocateFunc) (GtkGizmo *gizmo, + const GtkAllocation *allocation, + int baseline, + GtkAllocation *out_clip); +typedef gboolean (* GtkGizmoSnapshotFunc) (GtkGizmo *gizmo, + GtkSnapshot *snapshot); + + +struct _GtkGizmo +{ + GtkWidget parent_instance; + + GtkCssGadget *gadget; + + GtkGizmoMeasureFunc measure_func; + GtkGizmoAllocateFunc allocate_func; + GtkGizmoSnapshotFunc snapshot_func; +}; + +struct _GtkGizmoClass +{ + GtkWidgetClass parent_class; +}; + +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); + + +#endif