Constraint is:module

This module defines types and simple operations over constraints, as used in the type-checker and constraint solver.
ConstraintKinds made type classes into types of a new kind, Constraint.
Eq :: * -> Constraint
Ord :: * -> Constraint
Monad :: (* -> *) -> Constraint
The need for this extension was first publicized in the paper Scrap your boilerplate with class: extensible generic functions by Ralf Lämmel and Simon Peyton Jones in 2005, which shoehorned all the things they needed into a custom Sat typeclass. With ConstraintKinds we can put into code a lot of tools for manipulating these new types without such awkward workarounds.
Constraints for indexed datatypes. This module contains code that helps to specify that all elements of an indexed structure must satisfy a particular constraint.
GtkConstraint describes a constraint between attributes of two widgets, expressed as a linear equation. The typical equation for a constraint is:
target.target_attr = source.source_attr × multiplier + constant
Each GtkConstraint is part of a system that will be solved by a ConstraintLayout in order to allocate and position each child widget or guide. The source and target, as well as their attributes, of a GtkConstraint instance are immutable after creation.
This module provides proof object definitions of constraint key. Difference between this module and Database.Record.KeyConstraint is typed constraint key column definition is included in this module.
An implementation of the Semantic Versioning Constraints. In absence of a standard around constraints, the behavior of node-semver is closely followed. The behavior is outlined here: https://github.com/npm/node-semver#ranges
Describes a constraint between attributes of two widgets, expressed as a linear equation. The typical equation for a constraint is:
target.target_attr = source.source_attr × multiplier + constant
Each GtkConstraint is part of a system that will be solved by a ConstraintLayout in order to allocate and position each child widget or guide. The source and target, as well as their attributes, of a GtkConstraint instance are immutable after creation.
This module provides compatibility definitions of constraint context template for before temaplate-haskell-2.9
This module provides classes that emulate the behavior of GHC's constraint tuple syntax. Unlike GHC's built-in constraint tuples, the classes in this library can be partially applied. When building with GHC 9.10 or later, this will simply re-export the constraint tuples offered by GHC.Classes.
The GtkConstraintTarget interface is implemented by objects that can be used as source or target in GtkConstraints. Besides GtkWidget, it is also implemented by GtkConstraintGuide.
A GtkConstraintGuide is an invisible layout element in a GtkConstraintLayout. The GtkConstraintLayout treats guides like widgets. They can be used as the source or target of a GtkConstraint. Guides have a minimum, maximum and natural size. Depending on the constraints that are applied, they can act like a guideline that widgets can be aligned to, or like *flexible space*. Unlike a GtkWidget, a GtkConstraintGuide will not be drawn.
A layout manager using constraints to describe relations between widgets. GtkConstraintLayout is a layout manager that uses relations between widget attributes, expressed via Constraint instances, to measure and allocate widgets.

How do constraints work

Constraints are objects defining the relationship between attributes of a widget; you can read the description of the Constraint class to have a more in depth definition. By taking multiple constraints and applying them to the children of a widget using GtkConstraintLayout, it's possible to describe complex layout policies; each constraint applied to a child or to the parent widgets 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 an unstable or unsolvable layout. 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. You can use the Constraint:strength property of Constraint to "nudge" the layout towards a solution.

GtkConstraintLayout as GtkBuildable

GtkConstraintLayout implements the Buildable interface and has a custom "constraints" element which allows describing constraints in a Builder UI file. An example of a UI definition fragment specifying a constraint:

xml code

<object class="GtkConstraintLayout">
<constraints>
<constraint target="button" target-attribute="start"
relation="eq"
source="super" source-attribute="start"
constant="12"
strength="required" />
<constraint target="button" target-attribute="width"
relation="ge"
constant="250"
strength="strong" />
</constraints>
</object>
The definition above will add two constraints to the GtkConstraintLayout:
  • a required constraint between the leading edge of "button" and the leading edge of the widget using the constraint layout, plus 12 pixels
  • a strong, constant constraint making the width of "button" greater than, or equal to 250 pixels
The "target" and "target-attribute" attributes are required. The "source" and "source-attribute" attributes of the "constraint" element are optional; if they are not specified, the constraint is assumed to be a constant. The "relation" attribute is optional; if not specified, the constraint is assumed to be an equality. The "strength" attribute is optional; if not specified, the constraint is assumed to be required. The "source" and "target" attributes can be set to "super" to indicate that the constraint target is the widget using the GtkConstraintLayout. There can be "constant" and "multiplier" attributes. Additionally, the "constraints" element can also contain a description of the GtkConstraintGuides used by the layout:

xml code

<constraints>
<guide min-width="100" max-width="500" name="hspace"/>
<guide min-height="64" nat-height="128" name="vspace" strength="strong"/>
</constraints>
The "guide" element has the following optional attributes:
  • "min-width", "nat-width", and "max-width", describe the minimum, natural, and maximum width of the guide, respectively
  • "min-height", "nat-height", and "max-height", describe the minimum, natural, and maximum height of the guide, respectively
  • "strength" describes the strength of the constraint on the natural size of the guide; if not specified, the constraint is assumed to have a medium strength
  • "name" describes a name for the guide, useful when debugging

Using the Visual Format Language

Complex constraints can be described using a compact syntax called VFL, or *Visual Format Language*. The Visual Format Language describes all the constraints on a row or column, typically starting from the leading edge towards the trailing one. Each element of the layout is composed by "views", which identify a ConstraintTarget. For instance:
[button]-[textField]
Describes a constraint that binds the trailing edge of "button" to the leading edge of "textField", leaving a default space between the two. Using VFL is also possible to specify predicates that describe constraints on attributes like width and height:
// Width must be greater than, or equal to 50
[button(>=50)]

// Width of button1 must be equal to width of button2
[button1(==button2)]
The default orientation for a VFL description is horizontal, unless otherwise specified:
// horizontal orientation, default attribute: width
H:[button(>=150)]

// vertical orientation, default attribute: height
V:[button1(==button2)]
It's also possible to specify multiple predicates, as well as their strength:
// minimum width of button must be 150
// natural width of button can be 250
[button(>=150@required, ==250@medium)]
Finally, it's also possible to use simple arithmetic operators:
// width of button1 must be equal to width of button2
// divided by 2 plus 12
[button1(button2 / 2 + 12)]
GtkLayoutChild subclass for children in a GtkConstraintLayout.
Support for operating on Barbie-types with constrained functions.
Makes it possible to use an object as source or target in a Constraint. Besides GtkWidget, it is also implemented by GtkConstraintGuide.
An invisible layout element in a GtkConstraintLayout. The GtkConstraintLayout treats guides like widgets. They can be used as the source or target of a GtkConstraint. Guides have a minimum, maximum and natural size. Depending on the constraints that are applied, they can act like a guideline that widgets can be aligned to, or like *flexible space*. Unlike a GtkWidget, a GtkConstraintGuide will not be drawn.
Uses constraints to describe relations between widgets. GtkConstraintLayout is a layout manager that uses relations between widget attributes, expressed via Constraint instances, to measure and allocate widgets.

How do constraints work

Constraints are objects defining the relationship between attributes of a widget; you can read the description of the Constraint class to have a more in depth definition. By taking multiple constraints and applying them to the children of a widget using GtkConstraintLayout, it's possible to describe complex layout policies; each constraint applied to a child or to the parent widgets 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 an unstable or unsolvable layout. 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. You can use the Constraint:strength property of Constraint to "nudge" the layout towards a solution.

GtkConstraintLayout as GtkBuildable

GtkConstraintLayout implements the Buildable interface and has a custom "constraints" element which allows describing constraints in a Builder UI file. An example of a UI definition fragment specifying a constraint:

xml code

<object class="GtkConstraintLayout">
<constraints>
<constraint target="button" target-attribute="start"
relation="eq"
source="super" source-attribute="start"
constant="12"
strength="required" />
<constraint target="button" target-attribute="width"
relation="ge"
constant="250"
strength="strong" />
</constraints>
</object>
The definition above will add two constraints to the GtkConstraintLayout:
  • a required constraint between the leading edge of "button" and the leading edge of the widget using the constraint layout, plus 12 pixels
  • a strong, constant constraint making the width of "button" greater than, or equal to 250 pixels
The "target" and "target-attribute" attributes are required. The "source" and "source-attribute" attributes of the "constraint" element are optional; if they are not specified, the constraint is assumed to be a constant. The "relation" attribute is optional; if not specified, the constraint is assumed to be an equality. The "strength" attribute is optional; if not specified, the constraint is assumed to be required. The "source" and "target" attributes can be set to "super" to indicate that the constraint target is the widget using the GtkConstraintLayout. There can be "constant" and "multiplier" attributes. Additionally, the "constraints" element can also contain a description of the GtkConstraintGuides used by the layout:

xml code

<constraints>
<guide min-width="100" max-width="500" name="hspace"/>
<guide min-height="64" nat-height="128" name="vspace" strength="strong"/>
</constraints>
The "guide" element has the following optional attributes:
  • "min-width", "nat-width", and "max-width", describe the minimum, natural, and maximum width of the guide, respectively
  • "min-height", "nat-height", and "max-height", describe the minimum, natural, and maximum height of the guide, respectively
  • "strength" describes the strength of the constraint on the natural size of the guide; if not specified, the constraint is assumed to have a medium strength
  • "name" describes a name for the guide, useful when debugging

Using the Visual Format Language

Complex constraints can be described using a compact syntax called VFL, or *Visual Format Language*. The Visual Format Language describes all the constraints on a row or column, typically starting from the leading edge towards the trailing one. Each element of the layout is composed by "views", which identify a ConstraintTarget. For instance:
[button]-[textField]
Describes a constraint that binds the trailing edge of "button" to the leading edge of "textField", leaving a default space between the two. Using VFL is also possible to specify predicates that describe constraints on attributes like width and height:
// Width must be greater than, or equal to 50
[button(>=50)]

// Width of button1 must be equal to width of button2
[button1(==button2)]
The default orientation for a VFL description is horizontal, unless otherwise specified:
// horizontal orientation, default attribute: width
H:[button(>=150)]

// vertical orientation, default attribute: height
V:[button1(==button2)]
It's also possible to specify multiple predicates, as well as their strength:
// minimum width of button must be 150
// natural width of button can be 250
[button(>=150@required, ==250@medium)]
Finally, it's also possible to use simple arithmetic operators:
// width of button1 must be equal to width of button2
// divided by 2 plus 12
[button1(button2 / 2 + 12)]