Quelle gtkfixed.c
Sprache: C
/* GTK - The GIMP Toolkit
* Copyright ( C ) 1995 - 1997 Peter Mattis , Spencer Kimball and Josh MacDonald
*
* 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/>.
*/
/*
* Modified by the GTK + Team and others 1997 - 2000 . See the AUTHORS
* file for a list of people on the GTK + Team . See the ChangeLog
* files for a list of changes . These files are distributed with
* GTK + at ftp : //ftp.gtk.org/pub/gtk/.
*/
/**
* GtkFixed :
*
* Places its child widgets at fixed positions and with fixed sizes .
*
* ` GtkFixed ` performs no automatic layout management .
*
* For most applications , you should not use this container ! It keeps
* you from having to learn about the other GTK containers , but it
* results in broken applications . With ` GtkFixed ` , the following
* things will result in truncated text , overlapping widgets , and
* other display bugs :
*
* - Themes , which may change widget sizes .
*
* - Fonts other than the one you used to write the app will of course
* change the size of widgets containing text ; keep in mind that
* users may use a larger font because of difficulty reading the
* default , or they may be using a different OS that provides different fonts .
*
* - Translation of text into other languages changes its size . Also ,
* display of non - English text will use a different font in many
* cases .
*
* In addition , ` GtkFixed ` does not pay attention to text direction and
* thus may produce unwanted results if your app is run under right - to - left
* languages such as Hebrew or Arabic . That is : normally GTK will order
* containers appropriately for the text direction , e . g . to put labels to
* the right of the thing they label when using an RTL language , but it can ’ t
* do that with ` GtkFixed ` . So if you need to reorder widgets depending on
* the text direction , you would need to manually detect it and adjust child
* positions accordingly .
*
* Finally , fixed positioning makes it kind of annoying to add / remove
* UI elements , since you have to reposition all the other elements . This
* is a long - term maintenance problem for your application .
*
* If you know none of these things are an issue for your application ,
* and prefer the simplicity of ` GtkFixed ` , by all means use the
* widget . But you should be aware of the tradeoffs .
*/
#include "config.h"
#include "gtkfixed.h"
#include "gtkfixedlayout.h"
#include "gtkprivate.h"
#include "gtkwidgetprivate.h"
#include "gtkbuildable.h"
typedef struct {
GtkLayoutManager *layout;
} GtkFixedPrivate;
static void gtk_fixed_buildable_iface_init (GtkBuildableIface *iface);
G_DEFINE_TYPE_WITH_CODE (GtkFixed, gtk_fixed, GTK_TYPE_WIDGET,
G_ADD_PRIVATE (GtkFixed)
G_IMPLEMENT_INTERFACE (GTK_TYPE_BUILDABLE,
gtk_fixed_buildable_iface_init))
static void
gtk_fixed_compute_expand (GtkWidget *widget,
gboolean *hexpand_p,
gboolean *vexpand_p)
{
GtkWidget *w;
gboolean hexpand = FALSE ;
gboolean vexpand = FALSE ;
for (w = gtk_widget_get_first_child (widget);
w != NULL;
w = gtk_widget_get_next_sibling (w))
{
hexpand = hexpand || gtk_widget_compute_expand (w, GTK_ORIENTATION_HORIZONTAL);
vexpand = vexpand || gtk_widget_compute_expand (w, GTK_ORIENTATION_VERTICAL);
}
*hexpand_p = hexpand;
*vexpand_p = vexpand;
}
static GtkSizeRequestMode
gtk_fixed_get_request_mode (GtkWidget *widget)
{
GtkWidget *w;
int wfh = 0 , hfw = 0 ;
for (w = gtk_widget_get_first_child (widget);
w != NULL;
w = gtk_widget_get_next_sibling (w))
{
GtkSizeRequestMode mode = gtk_widget_get_request_mode (w);
switch (mode)
{
case GTK_SIZE_REQUEST_HEIGHT_FOR_WIDTH:
hfw ++;
break ;
case GTK_SIZE_REQUEST_WIDTH_FOR_HEIGHT:
wfh ++;
break ;
case GTK_SIZE_REQUEST_CONSTANT_SIZE:
default :
break ;
}
}
if (hfw == 0 && wfh == 0 )
return GTK_SIZE_REQUEST_CONSTANT_SIZE;
else
return wfh > hfw ?
GTK_SIZE_REQUEST_WIDTH_FOR_HEIGHT :
GTK_SIZE_REQUEST_HEIGHT_FOR_WIDTH;
}
static void
gtk_fixed_dispose (GObject *object)
{
GtkWidget *child;
while ((child = gtk_widget_get_first_child (GTK_WIDGET (object))))
gtk_fixed_remove (GTK_FIXED (object), child);
G_OBJECT_CLASS (gtk_fixed_parent_class)->dispose (object);
}
static void
gtk_fixed_class_init (GtkFixedClass *klass)
{
GObjectClass *object_class = G_OBJECT_CLASS (klass);
GtkWidgetClass *widget_class = GTK_WIDGET_CLASS (klass);
object_class->dispose = gtk_fixed_dispose;
widget_class->compute_expand = gtk_fixed_compute_expand;
widget_class->get_request_mode = gtk_fixed_get_request_mode;
gtk_widget_class_set_layout_manager_type (widget_class, GTK_TYPE_FIXED_LAYOUT);
}
static GtkBuildableIface *parent_buildable_iface;
static void
gtk_fixed_buildable_add_child (GtkBuildable *buildable,
GtkBuilder *builder,
GObject *child,
const char *type)
{
if (GTK_IS_WIDGET (child))
gtk_fixed_put (GTK_FIXED (buildable), GTK_WIDGET (child), 0 , 0 );
else
parent_buildable_iface->add_child (buildable, builder, child, type);
}
static void
gtk_fixed_buildable_iface_init (GtkBuildableIface *iface)
{
parent_buildable_iface = g_type_interface_peek_parent (iface);
iface->add_child = gtk_fixed_buildable_add_child;
}
static void
gtk_fixed_init (GtkFixed *self)
{
GtkFixedPrivate *priv = gtk_fixed_get_instance_private (self);
gtk_widget_set_overflow (GTK_WIDGET (self), GTK_OVERFLOW_HIDDEN);
priv->layout = gtk_widget_get_layout_manager (GTK_WIDGET (self));
}
/**
* gtk_fixed_new :
*
* Creates a new ` GtkFixed ` .
*
* Returns : a new ` GtkFixed ` .
*/
GtkWidget*
gtk_fixed_new (void )
{
return g_object_new (GTK_TYPE_FIXED, NULL);
}
/**
* gtk_fixed_put :
* @ fixed : a ` GtkFixed `
* @ widget : the widget to add
* @ x : the horizontal position to place the widget at
* @ y : the vertical position to place the widget at
*
* Adds a widget to a ` GtkFixed ` at the given position .
*/
void
gtk_fixed_put (GtkFixed *fixed,
GtkWidget *widget,
double x,
double y)
{
GtkFixedPrivate *priv = gtk_fixed_get_instance_private (fixed);
GtkFixedLayoutChild *child_info;
GskTransform *transform = NULL;
g_return_if_fail (GTK_IS_FIXED (fixed));
g_return_if_fail (GTK_IS_WIDGET (widget));
g_return_if_fail (_gtk_widget_get_parent (widget) == NULL);
gtk_widget_set_parent (widget, GTK_WIDGET (fixed));
child_info = GTK_FIXED_LAYOUT_CHILD (gtk_layout_manager_get_layout_child (priv->layout, widget));
transform = gsk_transform_translate (transform, &GRAPHENE_POINT_INIT (x, y));
gtk_fixed_layout_child_set_transform (child_info, transform);
gsk_transform_unref (transform);
}
/**
* gtk_fixed_get_child_position :
* @ fixed : a ` GtkFixed `
* @ widget : a child of @ fixed
* @ x : ( out ) : the horizontal position of the @ widget
* @ y : ( out ) : the vertical position of the @ widget
*
* Retrieves the translation transformation of the
* given child ` GtkWidget ` in the ` GtkFixed ` .
*
* See also : [ method @ Gtk . Fixed . get_child_transform ] .
*/
void
gtk_fixed_get_child_position (GtkFixed *fixed,
GtkWidget *widget,
double *x,
double *y)
{
graphene_point_t p;
g_return_if_fail (GTK_IS_FIXED (fixed));
g_return_if_fail (GTK_IS_WIDGET (widget));
g_return_if_fail (x != NULL);
g_return_if_fail (y != NULL);
g_return_if_fail (gtk_widget_get_parent (widget) == GTK_WIDGET (fixed));
if (!gtk_widget_compute_point (widget, GTK_WIDGET (fixed),
&GRAPHENE_POINT_INIT (0 , 0 ), &p))
graphene_point_init (&p, 0 , 0 );
*x = p.x;
*y = p.y;
}
/**
* gtk_fixed_set_child_transform :
* @ fixed : a ` GtkFixed `
* @ widget : a ` GtkWidget ` , child of @ fixed
* @ transform : ( nullable ) : the transformation assigned to @ widget
* to reset @ widget ' s transform
*
* Sets the transformation for @ widget .
*
* This is a convenience function that retrieves the
* [ class @ Gtk . FixedLayoutChild ] instance associated to
* @ widget and calls [ method @ Gtk . FixedLayoutChild . set_transform ] .
*/
void
gtk_fixed_set_child_transform (GtkFixed *fixed,
GtkWidget *widget,
GskTransform *transform)
{
GtkFixedPrivate *priv = gtk_fixed_get_instance_private (fixed);
GtkFixedLayoutChild *child_info;
g_return_if_fail (GTK_IS_FIXED (fixed));
g_return_if_fail (GTK_IS_WIDGET (widget));
g_return_if_fail (gtk_widget_get_parent (widget) == GTK_WIDGET (fixed));
child_info = GTK_FIXED_LAYOUT_CHILD (gtk_layout_manager_get_layout_child (priv->layout, widget));
gtk_fixed_layout_child_set_transform (child_info, transform);
}
/**
* gtk_fixed_get_child_transform :
* @ fixed : a ` GtkFixed `
* @ widget : a ` GtkWidget ` , child of @ fixed
*
* Retrieves the transformation for @ widget set using
* gtk_fixed_set_child_transform ( ) .
*
* Returns : ( transfer none ) ( nullable ) : a ` GskTransform `
*/
GskTransform *
gtk_fixed_get_child_transform (GtkFixed *fixed,
GtkWidget *widget)
{
GtkFixedPrivate *priv = gtk_fixed_get_instance_private (fixed);
GtkFixedLayoutChild *child_info;
g_return_val_if_fail (GTK_IS_FIXED (fixed), NULL);
g_return_val_if_fail (GTK_IS_WIDGET (widget), NULL);
g_return_val_if_fail (gtk_widget_get_parent (widget) == GTK_WIDGET (fixed), NULL);
child_info = GTK_FIXED_LAYOUT_CHILD (gtk_layout_manager_get_layout_child (priv->layout, widget));
return gtk_fixed_layout_child_get_transform (child_info);
}
/**
* gtk_fixed_move :
* @ fixed : a ` GtkFixed `
* @ widget : the child widget
* @ x : the horizontal position to move the widget to
* @ y : the vertical position to move the widget to
*
* Sets a translation transformation to the given @ x and @ y
* coordinates to the child @ widget of the ` GtkFixed ` .
*/
void
gtk_fixed_move (GtkFixed *fixed,
GtkWidget *widget,
double x,
double y)
{
GtkFixedPrivate *priv = gtk_fixed_get_instance_private (fixed);
GtkFixedLayoutChild *child_info;
GskTransform *transform = NULL;
g_return_if_fail (GTK_IS_FIXED (fixed));
g_return_if_fail (GTK_IS_WIDGET (widget));
g_return_if_fail (gtk_widget_get_parent (widget) == GTK_WIDGET (fixed));
child_info = GTK_FIXED_LAYOUT_CHILD (gtk_layout_manager_get_layout_child (priv->layout, widget));
transform = gsk_transform_translate (transform, &GRAPHENE_POINT_INIT (x, y));
gtk_fixed_layout_child_set_transform (child_info, transform);
gsk_transform_unref (transform);
}
/**
* gtk_fixed_remove :
* @ fixed : a ` GtkFixed `
* @ widget : the child widget to remove
*
* Removes a child from @ fixed .
*/
void
gtk_fixed_remove (GtkFixed *fixed,
GtkWidget *widget)
{
g_return_if_fail (GTK_IS_FIXED (fixed));
g_return_if_fail (GTK_IS_WIDGET (widget));
g_return_if_fail (gtk_widget_get_parent (widget) == GTK_WIDGET (fixed));
gtk_widget_unparent (widget);
}
Messung V0.5 in Prozent C=98 H=96 G=96
¤ Dauer der Verarbeitung: 0.16 Sekunden
(vorverarbeitet am 2026-07-03)
¤
*© Formatika GbR, Deutschland
2026-07-09