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 }