1 /*
2  * This file is part of gtkD.
3  *
4  * gtkD is free software; you can redistribute it and/or modify
5  * it under the terms of the GNU Lesser General Public License
6  * as published by the Free Software Foundation; either version 3
7  * of the License, or (at your option) any later version, with
8  * some exceptions, please read the COPYING file.
9  *
10  * gtkD is distributed in the hope that it will be useful,
11  * but WITHOUT ANY WARRANTY; without even the implied warranty of
12  * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
13  * GNU Lesser General Public License for more details.
14  *
15  * You should have received a copy of the GNU Lesser General Public License
16  * along with gtkD; if not, write to the Free Software
17  * Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110, USA
18  */
19 
20 // generated automatically - do not change
21 // find conversion definition on APILookup.txt
22 // implement new conversion functionalities on the wrap.utils pakage
23 
24 
25 module gtk.ConstraintLayout;
26 
27 private import gio.ListModelIF;
28 private import glib.ConstructionException;
29 private import glib.ErrorG;
30 private import glib.GException;
31 private import glib.HashTable;
32 private import glib.ListG;
33 private import glib.Str;
34 private import gobject.ObjectG;
35 private import gtk.BuildableIF;
36 private import gtk.BuildableT;
37 private import gtk.Constraint;
38 private import gtk.ConstraintGuide;
39 private import gtk.ConstraintTargetIF;
40 private import gtk.LayoutManager;
41 private import gtk.c.functions;
42 public  import gtk.c.types;
43 
44 
45 /**
46  * A layout manager using constraints to describe relations between widgets.
47  * 
48  * `GtkConstraintLayout` is a layout manager that uses relations between
49  * widget attributes, expressed via [class@Gtk.Constraint] instances, to
50  * measure and allocate widgets.
51  * 
52  * ### How do constraints work
53  * 
54  * Constraints are objects defining the relationship between attributes
55  * of a widget; you can read the description of the [class@Gtk.Constraint]
56  * class to have a more in depth definition.
57  * 
58  * By taking multiple constraints and applying them to the children of
59  * a widget using `GtkConstraintLayout`, it's possible to describe
60  * complex layout policies; each constraint applied to a child or to the parent
61  * widgets contributes to the full description of the layout, in terms of
62  * parameters for resolving the value of each attribute.
63  * 
64  * It is important to note that a layout is defined by the totality of
65  * constraints; removing a child, or a constraint, from an existing layout
66  * without changing the remaining constraints may result in an unstable
67  * or unsolvable layout.
68  * 
69  * Constraints have an implicit "reading order"; you should start describing
70  * each edge of each child, as well as their relationship with the parent
71  * container, from the top left (or top right, in RTL languages), horizontally
72  * first, and then vertically.
73  * 
74  * A constraint-based layout with too few constraints can become "unstable",
75  * that is: have more than one solution. The behavior of an unstable layout
76  * is undefined.
77  * 
78  * A constraint-based layout with conflicting constraints may be unsolvable,
79  * and lead to an unstable layout. You can use the [property@Gtk.Constraint:strength]
80  * property of [class@Gtk.Constraint] to "nudge" the layout towards a solution.
81  * 
82  * ### GtkConstraintLayout as GtkBuildable
83  * 
84  * `GtkConstraintLayout` implements the [iface@Gtk.Buildable] interface and
85  * has a custom "constraints" element which allows describing constraints in
86  * a [class@Gtk.Builder] UI file.
87  * 
88  * An example of a UI definition fragment specifying a constraint:
89  * 
90  * ```xml
91  * <object class="GtkConstraintLayout">
92  * <constraints>
93  * <constraint target="button" target-attribute="start"
94  * relation="eq"
95  * source="super" source-attribute="start"
96  * constant="12"
97  * strength="required" />
98  * <constraint target="button" target-attribute="width"
99  * relation="ge"
100  * constant="250"
101  * strength="strong" />
102  * </constraints>
103  * </object>
104  * ```
105  * 
106  * The definition above will add two constraints to the GtkConstraintLayout:
107  * 
108  * - a required constraint between the leading edge of "button" and
109  * the leading edge of the widget using the constraint layout, plus
110  * 12 pixels
111  * - a strong, constant constraint making the width of "button" greater
112  * than, or equal to 250 pixels
113  * 
114  * The "target" and "target-attribute" attributes are required.
115  * 
116  * The "source" and "source-attribute" attributes of the "constraint"
117  * element are optional; if they are not specified, the constraint is
118  * assumed to be a constant.
119  * 
120  * The "relation" attribute is optional; if not specified, the constraint
121  * is assumed to be an equality.
122  * 
123  * The "strength" attribute is optional; if not specified, the constraint
124  * is assumed to be required.
125  * 
126  * The "source" and "target" attributes can be set to "super" to indicate
127  * that the constraint target is the widget using the GtkConstraintLayout.
128  * 
129  * There can be "constant" and "multiplier" attributes.
130  * 
131  * Additionally, the "constraints" element can also contain a description
132  * of the #GtkConstraintGuides used by the layout:
133  * 
134  * ```xml
135  * <constraints>
136  * <guide min-width="100" max-width="500" name="hspace"/>
137  * <guide min-height="64" nat-height="128" name="vspace" strength="strong"/>
138  * </constraints>
139  * ```
140  * 
141  * The "guide" element has the following optional attributes:
142  * 
143  * - "min-width", "nat-width", and "max-width", describe the minimum,
144  * natural, and maximum width of the guide, respectively
145  * - "min-height", "nat-height", and "max-height", describe the minimum,
146  * natural, and maximum height of the guide, respectively
147  * - "strength" describes the strength of the constraint on the natural
148  * size of the guide; if not specified, the constraint is assumed to
149  * have a medium strength
150  * - "name" describes a name for the guide, useful when debugging
151  * 
152  * ### Using the Visual Format Language
153  * 
154  * Complex constraints can be described using a compact syntax called VFL,
155  * or *Visual Format Language*.
156  * 
157  * The Visual Format Language describes all the constraints on a row or
158  * column, typically starting from the leading edge towards the trailing
159  * one. Each element of the layout is composed by "views", which identify
160  * a [iface@Gtk.ConstraintTarget].
161  * 
162  * For instance:
163  * 
164  * ```
165  * [button]-[textField]
166  * ```
167  * 
168  * Describes a constraint that binds the trailing edge of "button" to the
169  * leading edge of "textField", leaving a default space between the two.
170  * 
171  * Using VFL is also possible to specify predicates that describe constraints
172  * on attributes like width and height:
173  * 
174  * ```
175  * // Width must be greater than, or equal to 50
176  * [button(>=50)]
177  * 
178  * // Width of button1 must be equal to width of button2
179  * [button1(==button2)]
180  * ```
181  * 
182  * The default orientation for a VFL description is horizontal, unless
183  * otherwise specified:
184  * 
185  * ```
186  * // horizontal orientation, default attribute: width
187  * H:[button(>=150)]
188  * 
189  * // vertical orientation, default attribute: height
190  * V:[button1(==button2)]
191  * ```
192  * 
193  * It's also possible to specify multiple predicates, as well as their
194  * strength:
195  * 
196  * ```
197  * // minimum width of button must be 150
198  * // natural width of button can be 250
199  * [button(>=150@required, ==250@medium)]
200  * ```
201  * 
202  * Finally, it's also possible to use simple arithmetic operators:
203  * 
204  * ```
205  * // width of button1 must be equal to width of button2
206  * // divided by 2 plus 12
207  * [button1(button2 / 2 + 12)]
208  * ```
209  */
210 public class ConstraintLayout : LayoutManager, BuildableIF
211 {
212 	/** the main Gtk struct */
213 	protected GtkConstraintLayout* gtkConstraintLayout;
214 
215 	/** Get the main Gtk struct */
216 	public GtkConstraintLayout* getConstraintLayoutStruct(bool transferOwnership = false)
217 	{
218 		if (transferOwnership)
219 			ownedRef = false;
220 		return gtkConstraintLayout;
221 	}
222 
223 	/** the main Gtk struct as a void* */
224 	protected override void* getStruct()
225 	{
226 		return cast(void*)gtkConstraintLayout;
227 	}
228 
229 	/**
230 	 * Sets our main struct and passes it to the parent class.
231 	 */
232 	public this (GtkConstraintLayout* gtkConstraintLayout, bool ownedRef = false)
233 	{
234 		this.gtkConstraintLayout = gtkConstraintLayout;
235 		super(cast(GtkLayoutManager*)gtkConstraintLayout, ownedRef);
236 	}
237 
238 	// add the Buildable capabilities
239 	mixin BuildableT!(GtkConstraintLayout);
240 
241 
242 	/** */
243 	public static GType getType()
244 	{
245 		return gtk_constraint_layout_get_type();
246 	}
247 
248 	/**
249 	 * Creates a new `GtkConstraintLayout` layout manager.
250 	 *
251 	 * Returns: the newly created `GtkConstraintLayout`
252 	 *
253 	 * Throws: ConstructionException GTK+ fails to create the object.
254 	 */
255 	public this()
256 	{
257 		auto __p = gtk_constraint_layout_new();
258 
259 		if(__p is null)
260 		{
261 			throw new ConstructionException("null returned by new");
262 		}
263 
264 		this(cast(GtkConstraintLayout*) __p, true);
265 	}
266 
267 	/**
268 	 * Adds a constraint to the layout manager.
269 	 *
270 	 * The [property@Gtk.Constraint:source] and [property@Gtk.Constraint:target]
271 	 * properties of `constraint` can be:
272 	 *
273 	 * - set to `NULL` to indicate that the constraint refers to the
274 	 * widget using `layout`
275 	 * - set to the [class@Gtk.Widget] using `layout`
276 	 * - set to a child of the [class@Gtk.Widget] using `layout`
277 	 * - set to a [class@Gtk.ConstraintGuide] that is part of `layout`
278 	 *
279 	 * The @layout acquires the ownership of @constraint after calling
280 	 * this function.
281 	 *
282 	 * Params:
283 	 *     constraint = a [class@Gtk.Constraint]
284 	 */
285 	public void addConstraint(Constraint constraint)
286 	{
287 		gtk_constraint_layout_add_constraint(gtkConstraintLayout, (constraint is null) ? null : constraint.getConstraintStruct());
288 	}
289 
290 	/**
291 	 * Creates a list of constraints from a VFL description.
292 	 *
293 	 * The Visual Format Language, VFL, is based on Apple's AutoLayout [VFL](https://developer.apple.com/library/content/documentation/UserExperience/Conceptual/AutolayoutPG/VisualFormatLanguage.html).
294 	 *
295 	 * The `views` dictionary is used to match [iface@Gtk.ConstraintTarget]
296 	 * instances to the symbolic view name inside the VFL.
297 	 *
298 	 * The VFL grammar is:
299 	 *
300 	 * ```
301 	 * <visualFormatString> = (<orientation>)?
302 	 * (<superview><connection>)?
303 	 * <view>(<connection><view>)*
304 	 * (<connection><superview>)?
305 	 * <orientation> = 'H' | 'V'
306 	 * <superview> = '|'
307 	 * <connection> = '' | '-' <predicateList> '-' | '-'
308 	 * <predicateList> = <simplePredicate> | <predicateListWithParens>
309 	 * <simplePredicate> = <metricName> | <positiveNumber>
310 	 * <predicateListWithParens> = '(' <predicate> (',' <predicate>)* ')'
311 	 * <predicate> = (<relation>)? <objectOfPredicate> (<operatorList>)? ('@' <priority>)?
312 	 * <relation> = '==' | '<=' | '>='
313 	 * <objectOfPredicate> = <constant> | <viewName> | ('.' <attributeName>)?
314 	 * <priority> = <positiveNumber> | 'required' | 'strong' | 'medium' | 'weak'
315 	 * <constant> = <number>
316 	 * <operatorList> = (<multiplyOperator>)? (<addOperator>)?
317 	 * <multiplyOperator> = [ '*' | '/' ] <positiveNumber>
318 	 * <addOperator> = [ '+' | '-' ] <positiveNumber>
319 	 * <viewName> = [A-Za-z_]([A-Za-z0-9_]*) // A C identifier
320 	 * <metricName> = [A-Za-z_]([A-Za-z0-9_]*) // A C identifier
321 	 * <attributeName> = 'top' | 'bottom' | 'left' | 'right' | 'width' | 'height' |
322 	 * 'start' | 'end' | 'centerX' | 'centerY' | 'baseline'
323 	 * <positiveNumber> // A positive real number parseable by g_ascii_strtod()
324 	 * <number> // A real number parseable by g_ascii_strtod()
325 	 * ```
326 	 *
327 	 * **Note**: The VFL grammar used by GTK is slightly different than the one
328 	 * defined by Apple, as it can use symbolic values for the constraint's
329 	 * strength instead of numeric values; additionally, GTK allows adding
330 	 * simple arithmetic operations inside predicates.
331 	 *
332 	 * Examples of VFL descriptions are:
333 	 *
334 	 * ```
335 	 * // Default spacing
336 	 * [button]-[textField]
337 	 *
338 	 * // Width constraint
339 	 * [button(>=50)]
340 	 *
341 	 * // Connection to super view
342 	 * |-50-[purpleBox]-50-|
343 	 *
344 	 * // Vertical layout
345 	 * V:[topField]-10-[bottomField]
346 	 *
347 	 * // Flush views
348 	 * [maroonView][blueView]
349 	 *
350 	 * // Priority
351 	 * [button(100@strong)]
352 	 *
353 	 * // Equal widths
354 	 * [button1(==button2)]
355 	 *
356 	 * // Multiple predicates
357 	 * [flexibleButton(>=70,<=100)]
358 	 *
359 	 * // A complete line of layout
360 	 * |-[find]-[findNext]-[findField(>=20)]-|
361 	 *
362 	 * // Operators
363 	 * [button1(button2 / 3 + 50)]
364 	 *
365 	 * // Named attributes
366 	 * [button1(==button2.height)]
367 	 * ```
368 	 *
369 	 * Params:
370 	 *     lines = an array of Visual Format Language lines
371 	 *         defining a set of constraints
372 	 *     hspacing = default horizontal spacing value, or -1 for the fallback value
373 	 *     vspacing = default vertical spacing value, or -1 for the fallback value
374 	 *     views = a dictionary of `[ name, target ]`
375 	 *         pairs; the `name` keys map to the view names in the VFL lines, while
376 	 *         the `target` values map to children of the widget using a `GtkConstraintLayout`,
377 	 *         or guides
378 	 *
379 	 * Returns: the list of
380 	 *     [class@Gtk.Constraint] instances that were added to the layout
381 	 *
382 	 * Throws: GException on failure.
383 	 */
384 	public ListG addConstraintsFromDescriptionv(string[] lines, int hspacing, int vspacing, HashTable views)
385 	{
386 		GError* err = null;
387 
388 		auto __p = gtk_constraint_layout_add_constraints_from_descriptionv(gtkConstraintLayout, Str.toStringzArray(lines), cast(size_t)lines.length, hspacing, vspacing, (views is null) ? null : views.getHashTableStruct(), &err);
389 
390 		if (err !is null)
391 		{
392 			throw new GException( new ErrorG(err) );
393 		}
394 
395 		if(__p is null)
396 		{
397 			return null;
398 		}
399 
400 		return new ListG(cast(GList*) __p);
401 	}
402 
403 	/**
404 	 * Adds a guide to `layout`.
405 	 *
406 	 * A guide can be used as the source or target of constraints,
407 	 * like a widget, but it is not visible.
408 	 *
409 	 * The `layout` acquires the ownership of `guide` after calling
410 	 * this function.
411 	 *
412 	 * Params:
413 	 *     guide = a [class@Gtk.ConstraintGuide] object
414 	 */
415 	public void addGuide(ConstraintGuide guide)
416 	{
417 		gtk_constraint_layout_add_guide(gtkConstraintLayout, (guide is null) ? null : guide.getConstraintGuideStruct());
418 	}
419 
420 	/**
421 	 * Returns a `GListModel` to track the constraints that are
422 	 * part of the layout.
423 	 *
424 	 * Calling this function will enable extra internal bookkeeping
425 	 * to track constraints and emit signals on the returned listmodel.
426 	 * It may slow down operations a lot.
427 	 *
428 	 * Applications should try hard to avoid calling this function
429 	 * because of the slowdowns.
430 	 *
431 	 * Returns: a
432 	 *     `GListModel` tracking the layout's constraints
433 	 */
434 	public ListModelIF observeConstraints()
435 	{
436 		auto __p = gtk_constraint_layout_observe_constraints(gtkConstraintLayout);
437 
438 		if(__p is null)
439 		{
440 			return null;
441 		}
442 
443 		return ObjectG.getDObject!(ListModelIF)(cast(GListModel*) __p, true);
444 	}
445 
446 	/**
447 	 * Returns a `GListModel` to track the guides that are
448 	 * part of the layout.
449 	 *
450 	 * Calling this function will enable extra internal bookkeeping
451 	 * to track guides and emit signals on the returned listmodel.
452 	 * It may slow down operations a lot.
453 	 *
454 	 * Applications should try hard to avoid calling this function
455 	 * because of the slowdowns.
456 	 *
457 	 * Returns: a
458 	 *     `GListModel` tracking the layout's guides
459 	 */
460 	public ListModelIF observeGuides()
461 	{
462 		auto __p = gtk_constraint_layout_observe_guides(gtkConstraintLayout);
463 
464 		if(__p is null)
465 		{
466 			return null;
467 		}
468 
469 		return ObjectG.getDObject!(ListModelIF)(cast(GListModel*) __p, true);
470 	}
471 
472 	/**
473 	 * Removes all constraints from the layout manager.
474 	 */
475 	public void removeAllConstraints()
476 	{
477 		gtk_constraint_layout_remove_all_constraints(gtkConstraintLayout);
478 	}
479 
480 	/**
481 	 * Removes `constraint` from the layout manager,
482 	 * so that it no longer influences the layout.
483 	 *
484 	 * Params:
485 	 *     constraint = a [class@Gtk.Constraint]
486 	 */
487 	public void removeConstraint(Constraint constraint)
488 	{
489 		gtk_constraint_layout_remove_constraint(gtkConstraintLayout, (constraint is null) ? null : constraint.getConstraintStruct());
490 	}
491 
492 	/**
493 	 * Removes `guide` from the layout manager,
494 	 * so that it no longer influences the layout.
495 	 *
496 	 * Params:
497 	 *     guide = a [class@Gtk.ConstraintGuide] object
498 	 */
499 	public void removeGuide(ConstraintGuide guide)
500 	{
501 		gtk_constraint_layout_remove_guide(gtkConstraintLayout, (guide is null) ? null : guide.getConstraintGuideStruct());
502 	}
503 }