diff options
Diffstat (limited to 'gdk')
-rw-r--r-- | gdk/gdk.h | 1 | ||||
-rw-r--r-- | gdk/gdkpopup.c | 250 | ||||
-rw-r--r-- | gdk/gdkpopup.h | 63 | ||||
-rw-r--r-- | gdk/gdkpopupprivate.h | 35 | ||||
-rw-r--r-- | gdk/meson.build | 4 |
5 files changed, 352 insertions, 1 deletions
@@ -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..3e5adbcc45 --- /dev/null +++ b/gdk/gdkpopup.c @@ -0,0 +1,250 @@ +/* + * 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 "gdkintl.h" +#include "gdkpopupprivate.h" +#include "gdk-private.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 int +gdk_popup_default_get_position_x (GdkPopup *popup) +{ + return 0; +} + +static int +gdk_popup_default_get_position_y (GdkPopup *popup) +{ + return 0; +} + +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_position_x = gdk_popup_default_get_position_x; + iface->get_position_y = gdk_popup_default_get_position_y; + + g_object_interface_install_property (iface, + g_param_spec_object ("parent", + P_("Parent"), + P_("The parent surface"), + GDK_TYPE_SURFACE, + G_PARAM_READWRITE | G_PARAM_CONSTRUCT_ONLY | G_PARAM_STATIC_STRINGS)); + g_object_interface_install_property (iface, + g_param_spec_boolean ("autohide", + P_("Autohide"), + P_("The parent surface"), + FALSE, + G_PARAM_READWRITE | G_PARAM_CONSTRUCT_ONLY | G_PARAM_STATIC_STRINGS)); +} + +/** + * 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 surface + */ +GdkSurface * +gdk_popup_get_parent (GdkPopup *popup) +{ + GdkSurface *surface; + + g_return_val_if_fail (GDK_IS_POPUP (popup), NULL); + + g_object_get (popup, "parent", &surface, NULL); + + if (surface) + g_object_unref (surface); + + return surface; +} + +/** + * gdk_popup_get_position_x: + * @popup: a #GdkPopup + * + * Obtains the position of the popup relative to its parent. + * + * Returns: the X coordinate of @popup position + */ +int +gdk_popup_get_position_x (GdkPopup *popup) +{ + g_return_val_if_fail (GDK_IS_POPUP (popup), 0); + + return GDK_POPUP_GET_IFACE (popup)->get_position_x (popup); +} + +/** + * gdk_popup_get_position_y: + * @popup: a #GdkPopup + * + * Obtains the position of the popup relative to its parent. + * + * Returns: the Y coordinate of @popup position + */ +int +gdk_popup_get_position_y (GdkPopup *popup) +{ + g_return_val_if_fail (GDK_IS_POPUP (popup), 0); + + return GDK_POPUP_GET_IFACE (popup)->get_position_y (popup); +} + +/** + * 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) +{ + gboolean autohide; + + g_return_val_if_fail (GDK_IS_POPUP (popup), FALSE); + + g_object_get (popup, "autohide", &autohide, NULL); + + return autohide; +} + +guint +gdk_popup_install_properties (GObjectClass *object_class, + guint first_prop) +{ + g_object_class_override_property (object_class, first_prop + GDK_POPUP_PROP_PARENT, "parent"); + g_object_class_override_property (object_class, first_prop + GDK_POPUP_PROP_AUTOHIDE, "autohide"); + + return GDK_POPUP_NUM_PROPERTIES; +} diff --git a/gdk/gdkpopup.h b/gdk/gdkpopup.h new file mode 100644 index 0000000000..079ef5a851 --- /dev/null +++ b/gdk/gdkpopup.h @@ -0,0 +1,63 @@ +/* + * 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/gdkpopuplayout.h> +#include <gdk/gdksurface.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 +int gdk_popup_get_position_x (GdkPopup *popup); + +GDK_AVAILABLE_IN_ALL +int gdk_popup_get_position_y (GdkPopup *popup); + +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..2d9c18e7c8 --- /dev/null +++ b/gdk/gdkpopupprivate.h @@ -0,0 +1,35 @@ +#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); + int (* get_position_x) (GdkPopup *popup); + int (* get_position_y) (GdkPopup *popup); +}; + +typedef enum +{ + GDK_POPUP_PROP_PARENT, + GDK_POPUP_PROP_AUTOHIDE, + GDK_POPUP_NUM_PROPERTIES +} GdkPopupProperties; + +guint gdk_popup_install_properties (GObjectClass *object_class, + guint first_prop); + +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/') |