83 lines
4.2 KiB
Markdown
83 lines
4.2 KiB
Markdown
|
Title: Coordinate systems in GTK
|
|||
|
Slug: gtk-coordinates
|
|||
|
|
|||
|
All coordinate systems in GTK have the origin at the top left, with the X axis
|
|||
|
pointing right, and the Y axis pointing down. This matches the convention used
|
|||
|
in X11, Wayland and cairo, but differs from OpenGL and PostScript, where the origin
|
|||
|
is in the lower left, and the Y axis is pointing up.
|
|||
|
|
|||
|
Every widget in a window has its own coordinate system that it uses to place its
|
|||
|
child widgets and to interpret events. Most of the time, this fact can be safely
|
|||
|
ignored. The section will explain the details for the few cases when it is important.
|
|||
|
|
|||
|
## The box model
|
|||
|
|
|||
|
When it comes to rendering, GTK follows the CSS box model as far as practical.
|
|||
|
|
|||
|
<picture>
|
|||
|
<source srcset="box-model-dark.png" media="(prefers-color-scheme: dark)">
|
|||
|
<img alt="Box Model" src="box-model-light.png">
|
|||
|
</picture>
|
|||
|
|
|||
|
The CSS stylesheet that is in use determines the sizes (and appearance) of the
|
|||
|
margin, border and padding areas for each widget. The size of the content area
|
|||
|
is determined by GTKs layout algorithm using each widget’s [vfunc@Gtk.Widget.measure]
|
|||
|
and [vfunc@Gtk.Widget.size_allocate] vfuncs.
|
|||
|
|
|||
|
You can learn more about the CSS box model by reading the
|
|||
|
[CSS specification](https://www.w3.org/TR/css-box-3/#box-model) or the
|
|||
|
Mozilla [documentation](https://developer.mozilla.org/en-US/docs/Learn/CSS/Building_blocks/The_box_model).
|
|||
|
|
|||
|
To learn more about where GTK CSS differs from CSS on the web, see the
|
|||
|
[CSS overview](css-overview.html).
|
|||
|
|
|||
|
## Widgets
|
|||
|
|
|||
|
The content area in the CSS box model is the region that the widget considers its own.
|
|||
|
|
|||
|
The origin of the widget’s coordinate system is the top left corner of the content area,
|
|||
|
and its size is the widget’s size. The size can be queried with [method@Gtk.Widget.get_width]
|
|||
|
and [method@Gtk.Widget.get_height]. GTK allows general 3D transformations to position
|
|||
|
widgets (although most of the time, the transformation will be a simple 2D translation).
|
|||
|
The transform to go from one widget’s coordinate system to another one can be obtained
|
|||
|
with [method@Gtk.Widget.compute_transform].
|
|||
|
|
|||
|
In addition to a size, widgets can optionally have a **_baseline_** to position text on.
|
|||
|
Containers such as [class@Gtk.Box] may position their children to match up their baselines.
|
|||
|
[method@Gtk.Widget.get_baseline] returns the y position of the baseline in widget coordinates.
|
|||
|
|
|||
|
When widget APIs expect positions or areas, they need to be expressed in this coordinate
|
|||
|
system, typically called **_widget coordinates_**. GTK provides a number of APIs to translate
|
|||
|
between different widgets' coordinate systems, such as [method@Gtk.Widget.compute_point]
|
|||
|
or [method@Gtk.Widget.compute_bounds]. These methods can fail (either because the widgets
|
|||
|
don't share a common ancestor, or because of a singular transformation), and callers need
|
|||
|
to handle this eventuality.
|
|||
|
|
|||
|
Another area that is occasionally relevant are the widget’s **_bounds_**, which is the area
|
|||
|
that a widget’s rendering is typically confined to (technically, widgets can draw outside
|
|||
|
of this area, unless clipping is enforced via the [property@Gtk.Widget:overflow] property).
|
|||
|
In CSS terms, the bounds of a widget correspond to the border area.
|
|||
|
|
|||
|
During GTK's layout algorithm, a parent widget needs to measure each visible child and
|
|||
|
allocate them at least as much size as measured. These functions take care of respecting
|
|||
|
the CSS box model and widget properties such as align and margin. This happens in the
|
|||
|
parent's coordinate system.
|
|||
|
|
|||
|
Note that the **_text direction_** of a widget does not influence its coordinate
|
|||
|
system, but simply determines whether text flows in the direction of increasing
|
|||
|
or decreasing X coordinates.
|
|||
|
|
|||
|
## Events
|
|||
|
|
|||
|
Event controllers and gestures report positions in the coordinate system of the widget
|
|||
|
they are attached to.
|
|||
|
|
|||
|
If you are dealing with raw events in the form of [class@Gdk.Event] that have positions
|
|||
|
associated with them (e.g. the pointer position), such positions are expressed in
|
|||
|
**_surface coordinates_**, which have their origin at the top left corner of the
|
|||
|
[class@Gdk.Surface].
|
|||
|
|
|||
|
To translate from surface to widget coordinates, you have to apply the offset from the
|
|||
|
top left corner of the surface to the top left corner of the topmost widget, which can
|
|||
|
be obtained with [method@Gtk.Native.get_surface_transform].
|