Compare commits

...

2 Commits

Author SHA1 Message Date
Matthias Clasen
0ead40efa3 gtk-demo: Fix the popover demo
Use GtkPopoverHolder here to fix things up.
2020-02-23 20:27:35 -05:00
Matthias Clasen
581ff10f46 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.
2020-02-23 20:27:01 -05:00
5 changed files with 255 additions and 7 deletions

View File

@@ -100,6 +100,7 @@ day_selected_cb (GtkCalendar *calendar,
GdkEvent *event;
gdouble x, y;
GtkWidget *widget;
GtkPopoverHolder *holder = GTK_POPOVER_HOLDER (user_data);
event = gtk_get_current_event ();
@@ -114,7 +115,7 @@ day_selected_cb (GtkCalendar *calendar,
&rect.x, &rect.y);
rect.width = rect.height = 1;
popover = create_popover (GTK_WIDGET (calendar),
popover = create_popover (GTK_WIDGET (holder),
gtk_entry_new (),
GTK_POS_BOTTOM);
gtk_popover_set_pointing_to (GTK_POPOVER (popover), &rect);
@@ -129,6 +130,8 @@ do_popover (GtkWidget *do_widget)
{
static GtkWidget *window = NULL;
GtkWidget *popover, *box, *widget;
GtkWidget *entry;
GtkWidget *calendar;
if (!window)
{
@@ -150,11 +153,13 @@ do_popover (GtkWidget *do_widget)
G_CALLBACK (toggle_changed_cb), popover);
gtk_container_add (GTK_CONTAINER (box), widget);
widget = gtk_entry_new ();
entry = gtk_entry_new ();
widget = gtk_popover_holder_new ();
gtk_popover_holder_set_child (GTK_POPOVER_HOLDER (widget), entry);
popover = create_complex_popover (widget, GTK_POS_TOP);
gtk_entry_set_icon_from_icon_name (GTK_ENTRY (widget),
gtk_entry_set_icon_from_icon_name (GTK_ENTRY (entry),
GTK_ENTRY_ICON_PRIMARY, "edit-find");
gtk_entry_set_icon_from_icon_name (GTK_ENTRY (widget),
gtk_entry_set_icon_from_icon_name (GTK_ENTRY (entry),
GTK_ENTRY_ICON_SECONDARY, "edit-clear");
g_signal_connect (widget, "icon-press",
@@ -163,9 +168,11 @@ do_popover (GtkWidget *do_widget)
G_CALLBACK (entry_size_allocate_cb), popover);
gtk_container_add (GTK_CONTAINER (box), widget);
widget = gtk_calendar_new ();
g_signal_connect (widget, "day-selected",
G_CALLBACK (day_selected_cb), NULL);
calendar = gtk_calendar_new ();
widget = gtk_popover_holder_new ();
gtk_popover_holder_set_child (GTK_POPOVER_HOLDER (widget), calendar);
g_signal_connect (calendar, "day-selected",
G_CALLBACK (day_selected_cb), widget);
gtk_container_add (GTK_CONTAINER (box), widget);
}

View File

@@ -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>

172
gtk/gtkpopoverholder.c Normal file
View File

@@ -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));
}
}

67
gtk/gtkpopoverholder.h Normal file
View File

@@ -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__ */

View File

@@ -298,6 +298,7 @@ gtk_public_sources = files([
'gtkpasswordentry.c',
'gtkpicture.c',
'gtkpopover.c',
'gtkpopoverholder.c',
'gtkpopovermenu.c',
'gtkpopovermenubar.c',
'gtkprintcontext.c',