Top |
GObject ╰── GInitiallyUnowned ╰── GtkWidget ╰── GtkContainer ├── GtkBin │ ╰── EmeusConstraintLayoutChild ╰── EmeusConstraintLayout
EmeusConstraintLayout implements AtkImplementorIface and GtkBuildable.
EmeusConstraintLayoutChild implements AtkImplementorIface and GtkBuildable.
EmeusConstraintLayout is a GtkContainter that uses constraints associated to each of its children to decide their layout.
Constraints are objects defining the relationship between attributes of a widget; you can read the description of the EmeusConstraint class to have a more in depth definition.
By taking multiple constraints and applying them to the children of an EmeusConstraintLayout, it's possible to describe complex layout policies; each constraint applied to a child or to the layout itself contributes to the full description of the layout, in terms of parameters for resolving the value of each attribute.
It is important to note that a layout is defined by the totality of constraints; removing a child, or a constraint, from an existing layout without changing the remaining constraints may result in a layout that cannot be solved.
Constraints have an implicit "reading order"; you should start describing each edge of each child, as well as their relationship with the parent container, from the top left (or top right, in RTL languages), horizontally first, and then vertically.
A constraint-based layout with too few constraints can become "unstable", that is: have more than one solution. The behavior of an unstable layout is undefined.
A constraint-based layout with conflicting constraints may be unsolvable, and lead to an unstable layout.
EmeusConstraintLayout accepts only one type of widget as its direct
child, EmeusConstraintLayoutChild. As a convenience for the developer,
EmeusConstraintLayout will automatically add an EmeusConstraintLayoutChild
for any other widget type when calling emeus_constraint_layout_pack()
or
gtk_container_add()
.
Similarly, when removing a GtkWidget from an EmeusConstraintLayout, the container will remove the intermediate EmeusConstraintLayoutChild that was added automatically.
When iterating over the children of EmeusConstraintLayout, you will
get only EmeusConstraintLayoutChild instances; use gtk_bin_get_child()
to retrieve the grandchild of the layout.
When creating an EmeusConstraintLayout layout with GtkBuilder, it can be simpler to also load constraints directly from the UI definition file.
EmeusConstraintLayout implements the GtkBuildable interface, and
adds the constraints
tag, which contains constraint
elements.
The constraint
element has various attributes:
target-object
, used to point to a widget using its builder id; this
attribute is mandatory, and specifies the value of the
“target-object” property
target-attr
, which contains an EmeusConstraintAttribute
value; this
attribute is mandatory, and specifies the value of the
“taregt-attribute” property
source-object
, used to point to a widget using its builder id; this
attribute is optional, for constant constraints, and specifies the value
of the “source-object” property
source-attr
, which contains an EmeusConstraintAttribute
value; this
attribute is optional, for constant constraints, and specifies the value
of the “source-attribute” property
relation
, which contains an EmeusConstraintRelation
value; this
attribute is optional, and if not found the relation will be
EMEUS_CONSTRAINT_RELATION_EQ
constant
, which contains the constant factor value as a floating point
numer; this attribute is optional, and if not found the constant will
be set to 0
multiplier
, which contains the multiplication factor value as a
floating point number; this attribute is option, and if not found the
multiplier will be set to 1
strength
, which contains an EmeusConstraintStrength
value, or a positive
integer; this attribute is optional, and if not found the strength will
be EMEUS_CONSTRAINT_STRENGTH_REQUIRED
A simple layout definitions is:
<object class="EmeusConstraintLayout" id="layout"> <property name="visible">True</property> <child> <object class="GtkButton" id="button1"> ... </object> </child> <child> <object class="GtkButton" id="button2"> ... </object> </child> <constraints> <constraint target-object="button1" target-attr="width" relation="EMEUS_CONSTRAINT_RELATION_GE" constant="250" strength="EMEUS_CONSTRAINT_STRENGTH_STRONG"/> <constraint target-object="button2" target-attr="width" relation="EMEUS_CONSTRAINT_RELATION_EQ" source-object="button1" source-attr="width"/> ... </constraints> </object>
While it's entirely possible to describe layouts by writing constraints by hand, it can be tedious to do so. Additionally, writing constraints by hand may lead to forgetting one or more of them, thus causing the layout to be unstable or incomplete; or to add conflicting constraints, thus causing the layout to be unsolvable.
In order to quickly visualize, and generate, constraints for a layout, Emeus implements a Visual Format language. Each row and column of a layout can be described by the VFL, and translated into constraints to be applied on top of a EmeusConstraintLayout and its children. Once the layout has been established, it's also possible to impose new constraints for additional layout rules.
A simple VFL description of a layout is:
|-[view0]-[view1(view0)]-| [view2(view1)]-| V:|-[view0]-| V:|-[view1]-[view2(view1)]-|
The description will generate a layout composed by three widgets arrange in two columns: one with 'view0', and the other with 'view1' and 'view2'. The 'view1' and 'view2' widgets will have the same width and height, and all three widgets will grow to fill the available space if their parent grows.
See emeus_create_constraints_from_description()
for the VFL grammar and
additional examples of layouts.
GtkWidget *
emeus_constraint_layout_new (void
);
Creates a new constraint-based layout manager.
Since: 1.0
void emeus_constraint_layout_pack (EmeusConstraintLayout *layout
,GtkWidget *child
,const char *name
,EmeusConstraint *first_constraint
,...
);
Adds child
to the layout
, and applies a list of constraints to it.
This convenience function is the equivalent of calling
gtk_container_add()
and emeus_constraint_layout_child_add_constraint()
for each constraint instance.
layout |
||
child |
||
name |
an optional name for the |
[nullable] |
first_constraint |
[nullable] | |
... |
a |
Since: 1.0
void emeus_constraint_layout_add_constraint (EmeusConstraintLayout *layout
,EmeusConstraint *constraint
);
Adds constraint
to the layout
.
Since: 1.0
void emeus_constraint_layout_add_constraints (EmeusConstraintLayout *layout
,EmeusConstraint *first_constraint
,...
);
Adds multiple EmeusConstraints at once to the layout
.
See also: emeus_constraint_layout_add_constraints()
layout |
||
first_constraint |
the first EmeusConstraint |
|
... |
a |
Since: 1.0
GList *
emeus_constraint_layout_get_constraints
(EmeusConstraintLayout *layout
);
Retrieves all the constraints used by the layout
.
a list of EmeusConstraint instances, owned by the EmeusConstraintLayout.
[transfer container][element-type EmeusConstraint]
Since: 1.0
void
emeus_constraint_layout_clear_constraints
(EmeusConstraintLayout *layout
);
Removes all constraints from a EmeusConstraintLayout.
Since: 1.0
GList * emeus_create_constraints_from_description (const char * const lines[]
,guint n_lines
,int hspacing
,int vspacing
,GHashTable *views
,GHashTable *metrics
);
Creates a list of constraints they formal description using the Visual Format Language syntax.
The views
dictionary is used to match widgets to the symbolic view name
inside the VFL; the metrics
dictionary is used to substitute symbolic
names with numeric values, to avoid hard coding constants inside the
VFL strings.
The VFL grammar is:
<visualFormatString> = (<orientation>)? (<superview><connection>)? <view>(<connection><view>)* (<connection><superview>)? <orientation> = 'H' | 'V' <superview> = '|' <connection> = '' | '-' <predicateList> '-' | '-' <predicateList> = <simplePredicate> | <predicateListWithParens> <simplePredicate> = <metricName> | <positiveNumber> <predicateListWithParens> = '(' <predicate> (',' <predicate>)* ')' <predicate> = (<relation>)? <objectOfPredicate> (<operatorList>)? ('@' <priority>)? <relation> = '==' | '<=' | '>=' <objectOfPredicate> = <constant> | <viewName> | <metricName> ('.' <attributeName>)? <priority> = <positiveNumber> | 'required' | 'strong' | 'medium' | 'weak' <constant> = <number> <operatorList> = (<multiplyOperator>)? (<addOperator>)? <multiplyOperator> = [ '*' | '/' ] <positiveNumber> <addOperator> = [ '+' | '-' ] <positiveNumber> <viewName> = [A-Za-z_]([A-Za-z0-9_]*) // A C identifier <metricName> = [A-Za-z_]([A-Za-z0-9_]*) // A C identifier <attributeName> = 'top' | 'bottom' | 'left' | 'right' | 'width' | 'height' | 'start' | 'end' | 'centerX' | 'centerY' | 'baseline' <positiveNumber> // A positive real number parseable by g_ascii_strtod() <number> // A real number parseable by g_ascii_strtod()
**Note**: The VFL grammar is slightly different than the one defined by Apple, as it uses symbolic values for the constraint's priority instead of numeric values.
Examples of VFL descriptions are:
// Default spacing [button]-[textField] // Width constraint [button(>=50)] // Connection to super view |-50-[purpleBox]-50-| // Vertical layout V:[topField]-10-[bottomField] // Flush views [maroonView][blueView] // Priority [button(100@strong)] // Equal widths [button1(==button2)] // Multiple predicates [flexibleButton(>=70,<=100)] // A complete line of layout |-[find]-[findNext]-[findField(>=20)]-| // Operators [button1(button2 / 3 + 50)] // Named attributes [button1(==button2.height)]
lines |
an array of Visual Format Language lines defining a set of constraints. |
[array length=n_lines] |
n_lines |
the number of lines |
|
hspacing |
default horizontal spacing value, or -1 for the fallback value |
|
vspacing |
default vertical spacing value, or -1 for the fallback value |
|
views |
a dictionary of [ name, widget ]
pairs; the |
[element-type utf8 Gtk.Widget] |
metrics |
a dictionary of
[ name, value ] pairs; the |
[element-type utf8 double][nullable] |
a list of EmeusConstraint instances, to be used with an EmeusConstraintLayout.
[transfer container][element-type Emeus.Constraint]
Since: 1.0
GtkWidget *
emeus_constraint_layout_child_new (const char *name
);
Creates a new EmeusConstraintLayoutChild widget.
[constructor]
Since: 1.0
void emeus_constraint_layout_child_add_constraint (EmeusConstraintLayoutChild *child
,EmeusConstraint *constraint
);
Adds the given constraint
to the list of constraints applied to
the child
of a EmeusConstraintLayout
The EmeusConstraintLayoutChild will own the constraint
until the
child
is removed, or until the constraint
is removed.
Since: 1.0
void emeus_constraint_layout_child_remove_constraint (EmeusConstraintLayoutChild *child
,EmeusConstraint *constraint
);
Removes the given constraint
from the list of constraints applied
to the child
of a EmeusConstraintLayout.
Since: 1.0
void
emeus_constraint_layout_child_clear_constraints
(EmeusConstraintLayoutChild *child
);
Clears all the constraints associated with a child of EmeusConstraintLayout.
Since: 1.0
const char *
emeus_constraint_layout_child_get_name
(EmeusConstraintLayoutChild *child
);
Retrieves the name of the child
.
Since: 1.0
int
emeus_constraint_layout_child_get_top (EmeusConstraintLayoutChild *child
);
Retrieves the value of the EMEUS_CONSTRAINT_ATTRIBUTE_TOP
for the child
.
Since: 1.0
int
emeus_constraint_layout_child_get_bottom
(EmeusConstraintLayoutChild *child
);
Retrieves the value of the EMEUS_CONSTRAINT_ATTRIBUTE_BOTTOM
for the child
.
Since: 1.0
int
emeus_constraint_layout_child_get_left
(EmeusConstraintLayoutChild *child
);
Retrieves the value of the EMEUS_CONSTRAINT_ATTRIBUTE_LEFT
for the child
.
Since: 1.0
int
emeus_constraint_layout_child_get_right
(EmeusConstraintLayoutChild *child
);
Retrieves the value of the EMEUS_CONSTRAINT_ATTRIBUTE_RIGHT
for the child
.
Since: 1.0
int
emeus_constraint_layout_child_get_width
(EmeusConstraintLayoutChild *child
);
Retrieves the value of the EMEUS_CONSTRAINT_ATTRIBUTE_WIDTH
for the child
.
Since: 1.0
int
emeus_constraint_layout_child_get_height
(EmeusConstraintLayoutChild *child
);
Retrieves the value of the EMEUS_CONSTRAINT_ATTRIBUTE_HEIGHT
for the child
.
Since: 1.0
int
emeus_constraint_layout_child_get_center_x
(EmeusConstraintLayoutChild *child
);
Retrieves the value of the EMEUS_CONSTRAINT_ATTRIBUTE_CENTER_X
for the child
.
Since: 1.0
int
emeus_constraint_layout_child_get_center_y
(EmeusConstraintLayoutChild *child
);
Retrieves the value of the EMEUS_CONSTRAINT_ATTRIBUTE_CENTER_Y
for the child
.
Since: 1.0
void emeus_constraint_layout_child_set_intrinsic_height (EmeusConstraintLayoutChild *child
,int height
);
Creates a new constraint on the height of the child
.
If height
is a negative value, the constraint is removed.
Since: 1.0
void emeus_constraint_layout_child_set_intrinsic_width (EmeusConstraintLayoutChild *child
,int width
);
Creates a new constraint on the width of the child
.
If width
is a negative value, the constraint is removed.
Since: 1.0
typedef struct _EmeusConstraintLayout EmeusConstraintLayout;
A container that uses constraints to determine the layout policy.
The contents of the EmeusConstraintLayout
are private and should never be
accessed directly.
Since: 1.0
typedef struct _EmeusConstraintLayoutChild EmeusConstraintLayoutChild;
A child in a EmeusConstraintLayout.
The contents of the EmeusConstraintLayoutChild
structure are private and
should never be accessed directly.
Since: 1.0