Quelle gdkpopuplayout.c
Sprache: C
/* GDK - The GIMP Drawing Kit
* Copyright ( C ) 2020 Red Hat
*
* 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 "gdkpopuplayout.h"
#include "gdkrectangle.h"
#include "gdksurface.h"
/**
* GdkPopupLayout :
*
* Contains information that is necessary position a [ iface @ Gdk . Popup ]
* relative to its parent .
*
* The positioning requires a negotiation with the windowing system ,
* since it depends on external constraints , such as the position of
* the parent surface , and the screen dimensions .
*
* The basic ingredients are a rectangle on the parent surface ,
* and the anchor on both that rectangle and the popup . The anchors
* specify a side or corner to place next to each other .
*
* ! [ Popup anchors ] ( popup - anchors . png )
*
* For cases where placing the anchors next to each other would make
* the popup extend offscreen , the layout includes some hints for how
* to resolve this problem . The hints may suggest to flip the anchor
* position to the other side , or to ' slide ' the popup along a side ,
* or to resize it .
*
* ! [ Flipping popups ] ( popup - flip . png )
*
* ! [ Sliding popups ] ( popup - slide . png )
*
* These hints may be combined .
*
* Ultimatively , it is up to the windowing system to determine the position
* and size of the popup . You can learn about the result by calling
* [ method @ Gdk . Popup . get_position_x ] , [ method @ Gdk . Popup . get_position_y ] ,
* [ method @ Gdk . Popup . get_rect_anchor ] and [ method @ Gdk . Popup . get_surface_anchor ]
* after the popup has been presented . This can be used to adjust the rendering .
* For example , [ GtkPopover ] ( . . / gtk4 / class . Popover . html ) changes its arrow position
* accordingly . But you have to be careful avoid changing the size of the popover ,
* or it has to be presented again .
*/
struct _GdkPopupLayout
{
/* < private >*/
grefcount ref_count;
GdkRectangle anchor_rect;
GdkGravity rect_anchor;
GdkGravity surface_anchor;
GdkAnchorHints anchor_hints;
int dx;
int dy;
int shadow_left;
int shadow_right;
int shadow_top;
int shadow_bottom;
};
G_DEFINE_BOXED_TYPE (GdkPopupLayout, gdk_popup_layout,
gdk_popup_layout_ref,
gdk_popup_layout_unref)
/**
* gdk_popup_layout_new : ( constructor )
* @ anchor_rect : ( not nullable ) : the anchor rectangle to align @ surface with
* @ rect_anchor : the point on @ anchor_rect to align with @ surface ' s anchor point
* @ surface_anchor : the point on @ surface to align with @ rect ' s anchor point
*
* Create a popup layout description .
*
* Used together with [ method @ Gdk . Popup . present ] to describe how a popup
* surface should be placed and behave on - screen .
*
* @ anchor_rect is relative to the top - left corner of the surface ' s parent .
* @ rect_anchor and @ surface_anchor determine anchor points on @ anchor_rect
* and surface to pin together .
*
* The position of @ anchor_rect ' s anchor point can optionally be offset using
* [ method @ Gdk . PopupLayout . set_offset ] , which is equivalent to offsetting the
* position of surface .
*
* Returns : ( transfer full ) : newly created instance of ` GdkPopupLayout `
*/
GdkPopupLayout *
gdk_popup_layout_new (const GdkRectangle *anchor_rect,
GdkGravity rect_anchor,
GdkGravity surface_anchor)
{
GdkPopupLayout *layout;
layout = g_new0 (GdkPopupLayout, 1 );
g_ref_count_init (&layout->ref_count);
layout->anchor_rect = *anchor_rect;
layout->rect_anchor = rect_anchor;
layout->surface_anchor = surface_anchor;
return layout;
}
/**
* gdk_popup_layout_ref :
* @ layout : a popup layout
*
* Increases the reference count of @ value .
*
* Returns : the same @ layout
*/
GdkPopupLayout *
gdk_popup_layout_ref (GdkPopupLayout *layout)
{
g_ref_count_inc (&layout->ref_count);
return layout;
}
/**
* gdk_popup_layout_unref :
* @ layout : a popup layout
*
* Decreases the reference count of @ value .
*/
void
gdk_popup_layout_unref (GdkPopupLayout *layout)
{
if (g_ref_count_dec (&layout->ref_count))
g_free (layout);
}
/**
* gdk_popup_layout_copy :
* @ layout : a popup layout
*
* Makes a copy of @ layout .
*
* Returns : ( transfer full ) : a copy of @ layout .
*/
GdkPopupLayout *
gdk_popup_layout_copy (GdkPopupLayout *layout)
{
GdkPopupLayout *new_layout;
new_layout = g_new0 (GdkPopupLayout, 1 );
g_ref_count_init (&new_layout->ref_count);
new_layout->anchor_rect = layout->anchor_rect;
new_layout->rect_anchor = layout->rect_anchor;
new_layout->surface_anchor = layout->surface_anchor;
new_layout->anchor_hints = layout->anchor_hints;
new_layout->dx = layout->dx;
new_layout->dy = layout->dy;
new_layout->shadow_left = layout->shadow_left;
new_layout->shadow_right = layout->shadow_right;
new_layout->shadow_top = layout->shadow_top;
new_layout->shadow_bottom = layout->shadow_bottom;
return new_layout;
}
/**
* gdk_popup_layout_equal :
* @ layout : a popup layout
* @ other : another popup layout
*
* Check whether @ layout and @ other has identical layout properties .
*
* Returns : true if @ layout and @ other have identical layout properties ,
* otherwise false .
*/
gboolean
gdk_popup_layout_equal (GdkPopupLayout *layout,
GdkPopupLayout *other)
{
g_return_val_if_fail (layout, FALSE );
g_return_val_if_fail (other, FALSE );
return (gdk_rectangle_equal (&layout->anchor_rect, &other->anchor_rect) &&
layout->rect_anchor == other->rect_anchor &&
layout->surface_anchor == other->surface_anchor &&
layout->anchor_hints == other->anchor_hints &&
layout->dx == other->dx &&
layout->dy == other->dy &&
layout->shadow_left == other->shadow_left &&
layout->shadow_right == other->shadow_right &&
layout->shadow_top == other->shadow_top &&
layout->shadow_bottom == other->shadow_bottom);
}
/**
* gdk_popup_layout_set_anchor_rect :
* @ layout : a popup layout
* @ anchor_rect : the new anchor rectangle
*
* Set the anchor rectangle .
*/
void
gdk_popup_layout_set_anchor_rect (GdkPopupLayout *layout,
const GdkRectangle *anchor_rect)
{
layout->anchor_rect = *anchor_rect;
}
/**
* gdk_popup_layout_get_anchor_rect :
* @ layout : a popup layout
*
* Get the anchor rectangle .
*
* Returns : The anchor rectangle
*/
const GdkRectangle *
gdk_popup_layout_get_anchor_rect (GdkPopupLayout *layout)
{
return &layout->anchor_rect;
}
/**
* gdk_popup_layout_set_rect_anchor :
* @ layout : a popup layout
* @ anchor : the new rect anchor
*
* Set the anchor on the anchor rectangle .
*/
void
gdk_popup_layout_set_rect_anchor (GdkPopupLayout *layout,
GdkGravity anchor)
{
layout->rect_anchor = anchor;
}
/**
* gdk_popup_layout_get_rect_anchor :
* @ layout : a popup layout
*
* Returns the anchor position on the anchor rectangle .
*
* Returns : the anchor on the anchor rectangle .
*/
GdkGravity
gdk_popup_layout_get_rect_anchor (GdkPopupLayout *layout)
{
return layout->rect_anchor;
}
/**
* gdk_popup_layout_set_surface_anchor :
* @ layout : a popup layout
* @ anchor : the new popup surface anchor
*
* Set the anchor on the popup surface .
*/
void
gdk_popup_layout_set_surface_anchor (GdkPopupLayout *layout,
GdkGravity anchor)
{
layout->surface_anchor = anchor;
}
/**
* gdk_popup_layout_get_surface_anchor :
* @ layout : a popup layout
*
* Returns the anchor position on the popup surface .
*
* Returns : the anchor on the popup surface .
*/
GdkGravity
gdk_popup_layout_get_surface_anchor (GdkPopupLayout *layout)
{
return layout->surface_anchor;
}
/**
* gdk_popup_layout_set_anchor_hints :
* @ layout : a popup layout
* @ anchor_hints : the new anchor hints
*
* Set new anchor hints .
*
* The set @ anchor_hints determines how @ surface will be moved
* if the anchor points cause it to move off - screen . For example ,
* ` GDK_ANCHOR_FLIP_X ` will replace ` GDK_GRAVITY_NORTH_WEST ` with
* ` GDK_GRAVITY_NORTH_EAST ` and vice versa if @ surface extends
* beyond the left or right edges of the monitor .
*/
void
gdk_popup_layout_set_anchor_hints (GdkPopupLayout *layout,
GdkAnchorHints anchor_hints)
{
layout->anchor_hints = anchor_hints;
}
/**
* gdk_popup_layout_get_anchor_hints :
* @ layout : a popup layout
*
* Get the anchor hints .
*
* Returns : the anchor hints
*/
GdkAnchorHints
gdk_popup_layout_get_anchor_hints (GdkPopupLayout *layout)
{
return layout->anchor_hints;
}
/**
* gdk_popup_layout_set_offset :
* @ layout : a popup layout
* @ dx : x delta to offset the anchor rectangle with
* @ dy : y delta to offset the anchor rectangle with
*
* Offset the position of the anchor rectangle with the given delta .
*/
void
gdk_popup_layout_set_offset (GdkPopupLayout *layout,
int dx,
int dy)
{
layout->dx = dx;
layout->dy = dy;
}
/**
* gdk_popup_layout_get_offset :
* @ layout : a popup layout
* @ dx : ( out ) : return location for the delta X coordinate
* @ dy : ( out ) : return location for the delta Y coordinate
*
* Retrieves the offset for the anchor rectangle .
*/
void
gdk_popup_layout_get_offset (GdkPopupLayout *layout,
int *dx,
int *dy)
{
if (dx)
*dx = layout->dx;
if (dy)
*dy = layout->dy;
}
/**
* gdk_popup_layout_set_shadow_width :
* @ layout : a popup layout
* @ left : width of the left part of the shadow
* @ right : width of the right part of the shadow
* @ top : height of the top part of the shadow
* @ bottom : height of the bottom part of the shadow
*
* Sets the shadow width of the popup .
*
* The shadow width corresponds to the part of the computed
* surface size that would consist of the shadow margin
* surrounding the window , would there be any .
*
* Since : 4 . 2
*/
void
gdk_popup_layout_set_shadow_width (GdkPopupLayout *layout,
int left,
int right,
int top,
int bottom)
{
layout->shadow_left = left;
layout->shadow_right = right;
layout->shadow_top = top;
layout->shadow_bottom = bottom;
}
/**
* gdk_popup_layout_get_shadow_width :
* @ layout : a popup layout
* @ left : ( out ) : return location for the left shadow width
* @ right : ( out ) : return location for the right shadow width
* @ top : ( out ) : return location for the top shadow width
* @ bottom : ( out ) : return location for the bottom shadow width
*
* Obtains the shadow widths of this layout .
*
* Since : 4 . 2
*/
void
gdk_popup_layout_get_shadow_width (GdkPopupLayout *layout,
int *left,
int *right,
int *top,
int *bottom)
{
if (left)
*left = layout->shadow_left;
if (right)
*right = layout->shadow_right;
if (top)
*top = layout->shadow_top;
if (bottom)
*bottom = layout->shadow_bottom;
}
Messung V0.5 in Prozent C=98 H=94 G=95
¤ Dauer der Verarbeitung: 0.13 Sekunden
(vorverarbeitet am 2026-07-03)
¤
*© Formatika GbR, Deutschland
2026-07-09