[gtk/present-toplevel: 5/54] Introduce GdkPopup
- From: Matthias Clasen <matthiasc src gnome org>
- To: commits-list gnome org
- Cc:
- Subject: [gtk/present-toplevel: 5/54] Introduce GdkPopup
- Date: Sun, 1 Mar 2020 19:34:07 +0000 (UTC)
commit 25d19298c90fa1a4765fa84a0558c069fb855d5c
Author: Matthias Clasen <mclasen redhat com>
Date: Sat Feb 29 09:17:02 2020 -0500
Introduce GdkPopup
This is a new interface for popup surfaces.
gdk/gdk.h | 1 +
gdk/gdkpopup.c | 211 ++++++++++++++++++++++++++++++++++++++++++++++++++
gdk/gdkpopup.h | 62 +++++++++++++++
gdk/gdkpopupprivate.h | 29 +++++++
gdk/meson.build | 4 +-
5 files changed, 306 insertions(+), 1 deletion(-)
---
diff --git a/gdk/gdk.h b/gdk/gdk.h
index bba82173f3..b466fe391a 100644
--- a/gdk/gdk.h
+++ b/gdk/gdk.h
@@ -68,6 +68,7 @@
#include <gdk/gdktypes.h>
#include <gdk/gdkvulkancontext.h>
#include <gdk/gdksurface.h>
+#include <gdk/gdkpopup.h>
#include <gdk/gdk-autocleanup.h>
diff --git a/gdk/gdkpopup.c b/gdk/gdkpopup.c
new file mode 100644
index 0000000000..8960ae8214
--- /dev/null
+++ b/gdk/gdkpopup.c
@@ -0,0 +1,211 @@
+/*
+ * Copyright © 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.1 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/>.
+ *
+ * Authors: Matthias Clasen <mclasen redhat com>
+ */
+
+#include "config.h"
+
+#include "gdkpopupprivate.h"
+
+/**
+ * SECTION:gdkpopup
+ * @Short_description: Interface for popup surfaces
+ * @Title: Popups
+ *
+ * A #GdkPopup is a surface that is attached to another surface,
+ * and is positioned relative to it.
+ */
+
+
+G_DEFINE_INTERFACE (GdkPopup, gdk_popup, GDK_TYPE_SURFACE)
+
+static gboolean
+gdk_popup_default_present (GdkPopup *popup,
+ int width,
+ int height,
+ GdkPopupLayout *layout)
+{
+ return FALSE;
+}
+
+static GdkGravity
+gdk_popup_default_get_surface_anchor (GdkPopup *popup)
+{
+ return GDK_GRAVITY_STATIC;
+}
+
+static GdkGravity
+gdk_popup_default_get_rect_anchor (GdkPopup *popup)
+{
+ return GDK_GRAVITY_STATIC;
+}
+
+static GdkSurface *
+gdk_popup_default_get_parent (GdkPopup *popup)
+{
+ return NULL;
+}
+
+static void
+gdk_popup_default_get_position (GdkPopup *popup,
+ int *x,
+ int *y)
+{
+ *x = 0;
+ *y = 0;
+}
+
+static gboolean
+gdk_popup_default_get_autohide (GdkPopup *popup)
+{
+ return FALSE;
+}
+
+static void
+gdk_popup_default_init (GdkPopupInterface *iface)
+{
+ iface->present = gdk_popup_default_present;
+ iface->get_surface_anchor = gdk_popup_default_get_surface_anchor;
+ iface->get_rect_anchor = gdk_popup_default_get_rect_anchor;
+ iface->get_parent = gdk_popup_default_get_parent;
+ iface->get_position = gdk_popup_default_get_position;
+ iface->get_autohide = gdk_popup_default_get_autohide;
+}
+
+/**
+ * gdk_popup_present:
+ * @popup: the #GdkPopup to show
+ * @width: the unconstrained popup width to layout
+ * @height: the unconstrained popup height to layout
+ * @layout: the #GdkPopupLayout object used to layout
+ *
+ * Present @popup after having processed the #GdkPopupLayout rules.
+ * If the popup was previously now showing, it will be showed,
+ * otherwise it will change position according to @layout.
+ *
+ * After calling this function, the result of the layout can be queried
+ * using gdk_popup_get_position(), gdk_surface_get_width(),
+ * gdk_surface_get_height(), gdk_popup_get_rect_anchor() and
+ * gdk_popup_get_surface_anchor().
+ *
+ * Presenting may have fail, for example if it was immediately
+ * hidden if the @popup was set to autohide.
+ *
+ * Returns: %FALSE if it failed to be presented, otherwise %TRUE.
+ */
+gboolean
+gdk_popup_present (GdkPopup *popup,
+ int width,
+ int height,
+ GdkPopupLayout *layout)
+{
+ g_return_val_if_fail (GDK_IS_POPUP (popup), FALSE);
+ g_return_val_if_fail (width > 0, FALSE);
+ g_return_val_if_fail (height > 0, FALSE);
+ g_return_val_if_fail (layout != NULL, FALSE);
+
+ return GDK_POPUP_GET_IFACE (popup)->present (popup, width, height, layout);
+}
+
+/**
+ * gdk_popup_get_surface_anchor:
+ * @popup: a #GdkPopup
+ *
+ * Gets the current popup surface anchor.
+ *
+ * The value returned may change after calling gdk_popup_present(),
+ * or after the "popup-layout-changed" is emitted.
+ *
+ * Returns: the current surface anchor value of @popup
+ */
+GdkGravity
+gdk_popup_get_surface_anchor (GdkPopup *popup)
+{
+ g_return_val_if_fail (GDK_IS_POPUP (popup), GDK_GRAVITY_STATIC);
+
+ return GDK_POPUP_GET_IFACE (popup)->get_surface_anchor (popup);
+}
+
+/**
+ * gdk_popup_get_rect_anchor:
+ * @popup: a #GdkPopup
+ *
+ * Gets the current popup rectangle anchor.
+ *
+ * The value returned may change after calling gdk_popup_present(),
+ * or after the "popup-layout-changed" is emitted.
+ *
+ * Returns: the current rectangle anchor value of @popup
+ */
+GdkGravity
+gdk_popup_get_rect_anchor (GdkPopup *popup)
+{
+ g_return_val_if_fail (GDK_IS_POPUP (popup), GDK_GRAVITY_STATIC);
+
+ return GDK_POPUP_GET_IFACE (popup)->get_rect_anchor (popup);
+}
+
+/**
+ * gdk_popup_get_parent:
+ * @popup: a #GdkPopup
+ *
+ * Returns the parent surface of a popup.
+ *
+ * Returns: (transfer none): the parent @popup
+ */
+GdkSurface *
+gdk_popup_get_parent (GdkPopup *popup)
+{
+ g_return_val_if_fail (GDK_IS_POPUP (popup), NULL);
+
+ return GDK_POPUP_GET_IFACE (popup)->get_parent (popup);
+}
+
+/**
+ * gdk_popup_get_position:
+ * @popup: a #GdkPopup
+ * @x: (out): X coordinate of popup
+ * @y: (out): Y coordinate of popup
+ *
+ * Obtains the position of the popup relative to its parent.
+ */
+void
+gdk_popup_get_position (GdkPopup *popup,
+ int *x,
+ int *y)
+{
+ g_return_if_fail (GDK_IS_POPUP (popup));
+
+ GDK_POPUP_GET_IFACE (popup)->get_position (popup, x, y);
+}
+
+/**
+ * gdk_popup_get_autohide:
+ * @popup: a #GdkPopup
+ *
+ * Returns whether this popup is set to hide on outside clicks.
+ *
+ * Returns: %TRUE if @popup will autohide
+ */
+gboolean
+gdk_popup_get_autohide (GdkPopup *popup)
+{
+ g_return_val_if_fail (GDK_IS_POPUP (popup), FALSE);
+
+ return GDK_POPUP_GET_IFACE (popup)->get_autohide (popup);
+}
+
diff --git a/gdk/gdkpopup.h b/gdk/gdkpopup.h
new file mode 100644
index 0000000000..a94be145a5
--- /dev/null
+++ b/gdk/gdkpopup.h
@@ -0,0 +1,62 @@
+/*
+ * Copyright © 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.1 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/>.
+ *
+ * Authors: Matthias Clasen <mclasen redhat com>
+ */
+
+#ifndef __GDK_POPUP_H__
+#define __GDK_POPUP_H__
+
+#if !defined (__GDK_H_INSIDE__) && !defined (GTK_COMPILATION)
+#error "Only <gdk/gdk.h> can be included directly."
+#endif
+
+#include <gdk/gdksurface.h>
+#include <gdk/gdkpopuplayout.h>
+
+G_BEGIN_DECLS
+
+#define GDK_TYPE_POPUP (gdk_popup_get_type ())
+
+GDK_AVAILABLE_IN_ALL
+G_DECLARE_INTERFACE (GdkPopup, gdk_popup, GDK, POPUP, GdkSurface)
+
+GDK_AVAILABLE_IN_ALL
+gboolean gdk_popup_present (GdkPopup *popup,
+ int width,
+ int height,
+ GdkPopupLayout *layout);
+
+GDK_AVAILABLE_IN_ALL
+GdkGravity gdk_popup_get_surface_anchor (GdkPopup *popup);
+
+GDK_AVAILABLE_IN_ALL
+GdkGravity gdk_popup_get_rect_anchor (GdkPopup *popup);
+
+GDK_AVAILABLE_IN_ALL
+GdkSurface * gdk_popup_get_parent (GdkPopup *popup);
+
+GDK_AVAILABLE_IN_ALL
+void gdk_popup_get_position (GdkPopup *popup,
+ int *x,
+ int *y);
+
+GDK_AVAILABLE_IN_ALL
+gboolean gdk_popup_get_autohide (GdkPopup *popup);
+
+G_END_DECLS
+
+#endif /* __GDK_POPUP_H__ */
diff --git a/gdk/gdkpopupprivate.h b/gdk/gdkpopupprivate.h
new file mode 100644
index 0000000000..6b7466a64e
--- /dev/null
+++ b/gdk/gdkpopupprivate.h
@@ -0,0 +1,29 @@
+#ifndef __GDK_POPUP_PRIVATE_H__
+#define __GDK_POPUP_PRIVATE_H__
+
+#include "gdkpopup.h"
+
+G_BEGIN_DECLS
+
+
+struct _GdkPopupInterface
+{
+ GTypeInterface g_iface;
+
+ gboolean (* present) (GdkPopup *popup,
+ int width,
+ int height,
+ GdkPopupLayout *layout);
+
+ GdkGravity (* get_surface_anchor) (GdkPopup *popup);
+ GdkGravity (* get_rect_anchor) (GdkPopup *popup);
+ GdkSurface * (* get_parent) (GdkPopup *popup);
+ void (* get_position) (GdkPopup *popup,
+ int *x,
+ int *y);
+ gboolean (* get_autohide) (GdkPopup *popup);
+};
+
+G_END_DECLS
+
+#endif /* __GDK_POPUP_PRIVATE_H__ */
diff --git a/gdk/meson.build b/gdk/meson.build
index 1df3b60e74..71d8393f92 100644
--- a/gdk/meson.build
+++ b/gdk/meson.build
@@ -44,7 +44,8 @@ gdk_public_sources = files([
'gdkvulkancontext.c',
'gdksurface.c',
'gdkpopuplayout.c',
- 'gdkprofiler.c'
+ 'gdkprofiler.c',
+ 'gdkpopup.c',
])
gdk_public_headers = files([
@@ -89,6 +90,7 @@ gdk_public_headers = files([
'gdkvulkancontext.h',
'gdksurface.h',
'gdkpopuplayout.h',
+ 'gdkpopup.h',
])
install_headers(gdk_public_headers, subdir: 'gtk-4.0/gdk/')
[
Date Prev][
Date Next] [
Thread Prev][
Thread Next]
[
Thread Index]
[
Date Index]
[
Author Index]