[gtk/popover-attach: 1/2] Add a popover holder widget



commit 581ff10f467e3c832c42730b6fe179e9b5a8f583
Author: Matthias Clasen <mclasen redhat com>
Date:   Sun Feb 23 20:27:01 2020 -0500

    Add a popover holder widget
    
    This is a simple widget that can have a child, and
    also have a popover attached to it, and will manage
    the size allocation for it.

 gtk/gtk.h              |   1 +
 gtk/gtkpopoverholder.c | 172 +++++++++++++++++++++++++++++++++++++++++++++++++
 gtk/gtkpopoverholder.h |  67 +++++++++++++++++++
 gtk/meson.build        |   1 +
 4 files changed, 241 insertions(+)
---
diff --git a/gtk/gtk.h b/gtk/gtk.h
index 8ee2ba1b0b..e0c9d2fa48 100644
--- a/gtk/gtk.h
+++ b/gtk/gtk.h
@@ -174,6 +174,7 @@
 #include <gtk/gtkpasswordentry.h>
 #include <gtk/gtkpicture.h>
 #include <gtk/gtkpopover.h>
+#include <gtk/gtkpopoverholder.h>
 #include <gtk/gtkpopovermenu.h>
 #include <gtk/gtkpopovermenubar.h>
 #include <gtk/gtkprintcontext.h>
diff --git a/gtk/gtkpopoverholder.c b/gtk/gtkpopoverholder.c
new file mode 100644
index 0000000000..7a7cb5f3a4
--- /dev/null
+++ b/gtk/gtkpopoverholder.c
@@ -0,0 +1,172 @@
+/* GTK - The GIMP Toolkit
+ * Copyright (C) 2020 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/>.
+ */
+
+#include "config.h"
+#include "gtkwidgetprivate.h"
+#include "gtkpopoverholder.h"
+#include "gtknative.h"
+
+
+struct _GtkPopoverHolder
+{
+  GtkWidget parent_instance;
+  GtkWidget *child;
+  GtkPopover *popover;
+};
+
+struct _GtkPopoverHolderClass
+{
+  GtkWidgetClass parent_class;
+};
+
+G_DEFINE_TYPE (GtkPopoverHolder, gtk_popover_holder, GTK_TYPE_WIDGET)
+
+static void
+gtk_popover_holder_size_allocate (GtkWidget *widget,
+                                  int        width,
+                                  int        height,
+                                  int        baseline)
+{
+  GtkPopoverHolder *self = GTK_POPOVER_HOLDER (widget);
+
+  if (self->child && _gtk_widget_get_visible (self->child))
+    gtk_widget_size_allocate (self->child,
+                              &(GtkAllocation) {
+                                0, 0,
+                                width, height
+                              }, baseline);
+
+  if (self->popover)
+    gtk_native_check_resize (GTK_NATIVE (self->popover));
+}
+
+static void
+gtk_popover_holder_measure (GtkWidget      *widget,
+                            GtkOrientation  orientation,
+                            int             for_size,
+                            int            *minimum,
+                            int            *natural,
+                            int            *minimum_baseline,
+                            int            *natural_baseline)
+{
+  GtkPopoverHolder *self = GTK_POPOVER_HOLDER (widget);
+
+  if (self->child != NULL && _gtk_widget_get_visible (self->child))
+    gtk_widget_measure (self->child,
+                        orientation,
+                        for_size,
+                        minimum, natural,
+                        minimum_baseline, natural_baseline);
+  else
+    {
+      *minimum = 0;
+      *natural = 0;
+    }
+}
+
+static void
+gtk_popover_holder_dispose (GObject *object)
+{
+  GtkPopoverHolder *self = GTK_POPOVER_HOLDER (object);
+
+  g_clear_pointer (&self->child, gtk_widget_unparent);
+  if (self->popover)
+    {
+      gtk_popover_set_relative_to (self->popover, NULL);
+      self->popover = NULL;
+    }
+
+  G_OBJECT_CLASS (gtk_popover_holder_parent_class)->dispose (object);
+}
+
+static void
+gtk_popover_holder_class_init (GtkPopoverHolderClass *class)
+{
+  GObjectClass *object_class = G_OBJECT_CLASS (class);
+  GtkWidgetClass *widget_class = GTK_WIDGET_CLASS (class);
+
+  object_class->dispose = gtk_popover_holder_dispose;
+
+  widget_class->measure = gtk_popover_holder_measure;
+  widget_class->size_allocate = gtk_popover_holder_size_allocate;
+}
+
+static void
+gtk_popover_holder_init (GtkPopoverHolder *self)
+{
+}
+
+GtkWidget *
+gtk_popover_holder_new (void)
+{
+  return g_object_new (GTK_TYPE_POPOVER_HOLDER, NULL);
+}
+
+GtkWidget *
+gtk_popover_holder_get_child (GtkPopoverHolder *self)
+{
+  g_return_val_if_fail (GTK_IS_POPOVER_HOLDER (self), NULL);
+
+  return self->child;
+}
+
+void
+gtk_popover_holder_set_child (GtkPopoverHolder *self,
+                              GtkWidget        *child)
+{
+  g_return_if_fail (GTK_IS_POPOVER_HOLDER (self));
+  g_return_if_fail (GTK_IS_WIDGET (child));
+
+  if (self->child)
+    gtk_widget_unparent (self->child);
+
+  self->child = child;
+
+  if (self->child)
+    gtk_widget_set_parent (self->child, GTK_WIDGET (self));
+}
+
+GtkPopover *
+gtk_popover_holder_get_popover (GtkPopoverHolder *self)
+{
+  g_return_val_if_fail (GTK_IS_POPOVER_HOLDER (self), NULL);
+
+  return self->popover;
+}
+
+void
+gtk_popover_holder_set_popover (GtkPopoverHolder *self,
+                                GtkPopover       *popover)
+{
+  g_return_if_fail (GTK_IS_POPOVER_HOLDER (self));
+  g_return_if_fail (GTK_IS_POPOVER (popover));
+
+  if (self->popover)
+    {
+      if (gtk_widget_get_visible (GTK_WIDGET (self->popover)))
+        gtk_widget_hide (GTK_WIDGET (self->popover));
+
+      gtk_popover_set_relative_to (self->popover, NULL);
+    }
+
+  self->popover = popover;
+
+  if (self->popover)
+    {
+      gtk_popover_set_relative_to (self->popover, GTK_WIDGET (self));
+    }
+}
diff --git a/gtk/gtkpopoverholder.h b/gtk/gtkpopoverholder.h
new file mode 100644
index 0000000000..62e4f943c5
--- /dev/null
+++ b/gtk/gtkpopoverholder.h
@@ -0,0 +1,67 @@
+/* GTK - The GIMP Toolkit
+ * Copyright (C) 2020 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_POPOVER_HOLDER_H__
+#define __GTK_POPOVER_HOLDER_H__
+
+
+#if !defined (__GTK_H_INSIDE__) && !defined (GTK_COMPILATION)
+#error "Only <gtk/gtk.h> can be included directly."
+#endif
+
+#include <gtk/gtkwidget.h>
+#include <gtk/gtkpopover.h>
+
+G_BEGIN_DECLS
+
+#define GTK_TYPE_POPOVER_HOLDER                  (gtk_popover_holder_get_type ())
+#define GTK_POPOVER_HOLDER(obj)                  (G_TYPE_CHECK_INSTANCE_CAST ((obj), 
GTK_TYPE_POPOVER_HOLDER, GtkPopoverHolder))
+#define GTK_POPOVER_HOLDER_CLASS(klass)          (G_TYPE_CHECK_CLASS_CAST ((klass), GTK_TYPE_POPOVER_HOLDER, 
GtkPopoverHolderClass))
+#define GTK_IS_POPOVER_HOLDER(obj)               (G_TYPE_CHECK_INSTANCE_TYPE ((obj), 
GTK_TYPE_POPOVER_HOLDER))
+#define GTK_IS_POPOVER_HOLDER_CLASS(klass)       (G_TYPE_CHECK_CLASS_TYPE ((klass), GTK_TYPE_POPOVER_HOLDER))
+#define GTK_POPOVER_HOLDER_GET_CLASS(obj)        (G_TYPE_INSTANCE_GET_CLASS ((obj), GTK_TYPE_POPOVER_HOLDER, 
GtkPopoverHolderClass))
+
+
+typedef struct _GtkPopoverHolder              GtkPopoverHolder;
+typedef struct _GtkPopoverHolderClass         GtkPopoverHolderClass;
+
+
+GDK_AVAILABLE_IN_ALL
+GType           gtk_popover_holder_get_type     (void) G_GNUC_CONST;
+
+GDK_AVAILABLE_IN_ALL
+GtkWidget *     gtk_popover_holder_new          (void);
+
+GDK_AVAILABLE_IN_ALL
+GtkWidget *     gtk_popover_holder_get_child    (GtkPopoverHolder *self);
+
+GDK_AVAILABLE_IN_ALL
+void            gtk_popover_holder_set_child    (GtkPopoverHolder *self,
+                                                 GtkWidget        *widget);
+
+GDK_AVAILABLE_IN_ALL
+GtkPopover *    gtk_popover_holder_get_popover  (GtkPopoverHolder *self);
+
+GDK_AVAILABLE_IN_ALL
+void            gtk_popover_holder_set_popover  (GtkPopoverHolder *self,
+                                                 GtkPopover       *popover);
+
+G_DEFINE_AUTOPTR_CLEANUP_FUNC(GtkPopoverHolder, g_object_unref)
+
+G_END_DECLS
+
+#endif /* __GTK_POPOVER_HOLDER_H__ */
diff --git a/gtk/meson.build b/gtk/meson.build
index ca72c02101..ee6647328e 100644
--- a/gtk/meson.build
+++ b/gtk/meson.build
@@ -298,6 +298,7 @@ gtk_public_sources = files([
   'gtkpasswordentry.c',
   'gtkpicture.c',
   'gtkpopover.c',
+  'gtkpopoverholder.c',
   'gtkpopovermenu.c',
   'gtkpopovermenubar.c',
   'gtkprintcontext.c',


[Date Prev][Date Next]   [Thread Prev][Thread Next]   [Thread Index] [Date Index] [Author Index]