Merge commit '81396a5322a7a48764fcf254d5d933ba1e57bdc5' as 'kiwi'

This commit is contained in:
2024-02-11 15:32:50 -06:00
76 changed files with 13184 additions and 0 deletions

View File

@@ -0,0 +1,142 @@
.. _uses-enaml:
Enaml
=====
.. include:: ../substitutions.sub
Enaml is a programming language and framework for creating professional-quality
user interfaces with minimal effort. It relies on Kiwi to layout widgets.
To implement its layout, Enaml uses a nestable model. Containers widgets
handle the constraints generation used to layout their children. Furthermore,
they pass to their their children a representation of the bounding box in
which they should live which allows the widgets to position themselves inside
their parent. Since each leaf component has a "preferred size", the system can
be solved from the bottom-up and set the size the parents based on the required
space of the children. If at a later time the parent is resized, this new input
can be used to solve the layout problem.
The following sections will describe in more details how the constraints are
generated and the preferred size estimated.
Widget variables
----------------
In Enaml, each widget that can be constrained defines a bunch of Kiwi
|Variable|: ``left``, ``top``, ``width`` and ``height``. In addition,
it provides easy access to combination of those: ``right``, ``bottom``,
``h_center``, ``v_center``. Those variables will be used to define the layout.
In addition, because each widget has a preferred size, it defines a set of
constraints related to that preferred size on which the user can act upon by
modifying their strength:
- hug_width: equivalent to (width == hint) | hug_width
- hug_height: equivalent to (height == hint) | hug_height
- resist_width: equivalent to (width >= hint) | resist_width
- resist_height: equivalent to (height >= hint) | resist_height
- limit_width: equivalent to (width <= hint) | limit_width
- limit_height: equivalent to (height <= hint) | limit_height
Finally, widget that can contain other widgets define a set of variables that
they expose to their children to allow to place themselves relative to their
parents. Those are: ``contents_left``, ``contents_top``, ``contents_width``,
``contents_height``, ``contents_right``, ``contents_bottom``,
``contents_h_center``, ``contents_v_center``. Those are usually not equivalent
to the non-prefixed variables (even-though they are related) because of the
container margins.
The base classes used a mixin to implement those behaviors are defined in:
https://github.com/nucleic/enaml/blob/main/enaml/layout/constrainable.py
Constraints definition
----------------------
Using the above variable, one can express any constraints. However, even for
simple vertical or horizontal boxes, the constraints to define, in
particular if one needs to introduce some spacing around the objects, become
quite painful to write by hand.
To make constraints definition easier, Enaml relies on helpers function and
classes. In the following, we will focus on how horizontal and vertical boxes
constraints are handled, by studying the following example in details:
.. image:: enaml_hbox.svg
Here we consider a container widget with three child widgets. The outer black
frame represents the limit of the container. The dashed frame represents the
contents visible to children when defining their constraint. The container uses
the margin definition to relate the outer left, top, width and height to their
'contents' equivalent.
The three widgets are arranged according to a horizontal box for which the
constraints are created using the `hbox` helper function which simply accepts
a list of widgets and spacers . To define the constraints from that list, Enaml
relies on the spacers represented here in orange. Each spacer has a
given size and a policy regarding that size (is it a minimum value, maximum,
how strongly to enforce that size). For each orientation, `hbox` add spacers so
that there is a spacer between each widget and between the widgets and the
parent boundaries. Some spacers can have a zero size, simply meaning that
widgets should be in contact.
When generating the constraints, `hbox` will be passed the container and use
the spacers to generate the constraints by simply glueing the anchors of
surrounding widgets. Each spacer can generate multiple constraints which gives
this process a lot of flexibility. Furthermore, those helpers define the same
variable as the widgets allowing for to position groups with respect to one
another.
.. note::
In practice, `hbox` itself relies on some helpers but the above gives you
the general idea.
For further details you can have a look at the source of the helpers described
in this section which can be found in the Enaml source:
- spacers: https://github.com/nucleic/enaml/blob/main/enaml/layout/spacers.py
- helpers:
- https://github.com/nucleic/enaml/blob/main/enaml/layout/layout_helpers.py
- https://github.com/nucleic/enaml/blob/main/enaml/layout/linear_box_helper.py
- https://github.com/nucleic/enaml/blob/main/enaml/layout/sequence_helper.py
Setting up the solver
---------------------
So far we have only defined the constraints that represent the layout, we will
now turn to how Enaml pass those to the solver and how it handle updates and
solver resets.
By default, each container manages its own solver independently. This has
the advantage of keeping the system relatively smalls and hence allow for
faster updates. When setting up the solver, the container will add for each
widget a set of constraints reflecting the preference of the widget regarding
its size as reported by the widget, and add to those the constraints defining
the layout. It will also add two edit variable representing the width and
height of the container.
Once the solver has been set up it can be used to compute different values,
such as the best size for the container (requesting a size of 0 with a 0.1*weak
strength), its min size (0 size, medium strength) and max size (max size,
medium strength).
When the parent is resized, the solver is invoked again with the new width and
height as suggestion. On the other hand, if the constraints change either
because widgets have been added or removed or because the users modified them,
the solver is reset and the constraints are rebuilt-from scratch. This means
that we never keep the solver around long enough to have to worry about memory
consumption due to unused variables in the solver.
In a complex hierarchy, the top parent will request the sizes of the nested
containers which will trigger the solving of their constraints. At some point
in the nested structure, we will only find widgets which provides a size hint
without requiring to solve constraints (ex: a button). This will allow to solve
the system and then propagate back upward.
Hopefully this brief introduction will have clarified how Enaml make use of
kiwi to layout its widgets. Some fine mechanics have been simplified for the
sake of this description but you can check Enaml sources for a more in depth
description.

View File

@@ -0,0 +1,244 @@
<?xml version="1.0" encoding="utf-8"?>
<!-- Generator: Adobe Illustrator 18.1.1, SVG Export Plug-In . SVG Version: 6.00 Build 0) -->
<svg version="1.1" id="Layer_1" xmlns="http://www.w3.org/2000/svg" xmlns:xlink="http://www.w3.org/1999/xlink" x="0px" y="0px"
viewBox="0 0 449.8 112.7" enable-background="new 0 0 449.8 112.7" xml:space="preserve">
<font horiz-adv-x="1000">
<!-- Copyright 2000, 2004 , 2005Adobe Systems Incorporated. All Rights Reserved. U.S. Patent D454,582.Myriad is a registered trademark of Adobe Systems Incorporated. -->
<font-face font-family="MyriadPro-Bold" units-per-em="1000" underline-position="-100" underline-thickness="50"/>
<missing-glyph horiz-adv-x="500" d="M0,0l500,0l0,700l-500,0M250,395l-170,255l340,0M280,350l170,255l0,-510M80,50l170,255l170,-255M50,605l170,-255l-170,-255z"/>
<glyph unicode="C" horiz-adv-x="595" d="M538,138C508,126 457,116 411,116C275,116 195,201 195,336C195,486 289,559 410,559C464,559 507,547 538,534l31,121C542,669 482,685 403,685C199,685 35,557 35,327C35,135 155,-11 388,-11C470,-11 533,5 561,19z"/>
<glyph unicode="W" horiz-adv-x="888" d="M342,0l64,290C422,358 433,422 445,498l2,0C455,421 466,358 479,290l57,-290l165,0l174,674l-155,0l-55,-276C651,318 636,239 626,164l-2,0C614,239 603,311 588,390l-54,284l-162,0l-57,-276C298,315 282,234 271,161l-2,0C258,229 244,316 229,397l-51,277l-163,0l160,-674z"/>
<glyph unicode="a" horiz-adv-x="528" d="M469,289C469,404 417,500 254,500C165,500 98,476 64,457l28,-98C124,379 177,396 227,396C302,396 316,359 316,333l0,-7C143,327 29,266 29,139C29,61 88,-11 187,-11C245,-11 295,10 327,49l3,0l9,-49l137,0C471,27 469,72 469,119M321,178C321,169 320,160 318,152C308,121 277,96 239,96C205,96 179,115 179,154C179,213 241,232 321,231z"/>
<glyph unicode="d" horiz-adv-x="596" d="M383,710l0,-265l-2,0C359,479 312,500 252,500C135,500 32,405 33,240C33,88 126,-11 242,-11C305,-11 364,17 395,72l2,0l7,-72l135,0C537,33 535,91 535,146l0,564M383,218C383,205 382,194 379,183C370,140 335,110 291,110C228,110 187,162 187,245C187,322 223,384 292,384C339,384 372,350 381,309C382,301 383,290 383,282z"/>
<glyph unicode="e" horiz-adv-x="528" d="M493,196C495,207 498,230 498,256C498,377 438,500 280,500C110,500 33,363 33,239C33,86 128,-11 294,-11C360,-11 421,0 471,20l-20,103C410,110 368,103 316,103C245,103 183,133 178,196M177,300C181,341 207,399 271,399C341,399 357,337 357,300z"/>
<glyph unicode="g" horiz-adv-x="585" d="M524,344C524,417 526,458 528,489l-132,0l-5,-58l-2,0C364,471 322,500 255,500C135,500 33,400 33,243C33,102 119,4 240,4C296,4 343,27 372,68l2,0l0,-32C374,-54 319,-93 247,-93C190,-93 136,-74 105,-56l-30,-115C119,-196 187,-209 251,-209C323,-209 396,-195 450,-149C505,-100 524,-23 524,71M372,218C372,205 371,189 367,178C357,142 326,116 287,116C223,116 187,173 187,246C187,335 232,385 287,385C329,385 358,358 369,318C371,310 372,300 372,290z"/>
<glyph unicode="i" horiz-adv-x="274" d="M213,0l0,489l-152,0l0,-489M137,702C88,702 56,669 57,625C56,583 88,549 136,549C186,549 218,583 218,625C217,669 186,702 137,702z"/>
<glyph unicode="n" horiz-adv-x="586" d="M61,0l152,0l0,282C213,296 215,310 219,320C229,348 254,377 296,377C351,377 373,334 373,271l0,-271l152,0l0,290C525,434 450,500 350,500C269,500 219,453 199,422l-3,0l-7,67l-132,0C59,446 61,394 61,333z"/>
<glyph unicode="o" horiz-adv-x="577" d="M294,500C137,500 33,399 33,241C33,83 143,-11 286,-11C417,-11 544,71 544,250C544,397 444,500 294,500M290,392C359,392 387,318 387,245C387,157 349,98 290,98C225,98 190,161 190,245C190,317 217,392 290,392z"/>
<glyph unicode="1" horiz-adv-x="555" d="M236,0l147,0l0,650l-126,0l-172,-80l25,-114l124,59l2,0z"/>
<glyph unicode="r" horiz-adv-x="380" d="M61,0l152,0l0,248C213,260 214,272 216,282C226,329 264,359 320,359C337,359 350,357 361,354l0,144C350,500 343,500 329,500C282,500 222,470 197,399l-4,0l-5,90l-131,0C59,447 61,400 61,328z"/>
<glyph unicode=" " horiz-adv-x="202"/>
<glyph unicode="t" horiz-adv-x="367" d="M82,581l0,-92l-65,0l0,-112l65,0l0,-200C82,108 96,61 124,32C148,7 189,-11 238,-11C281,-11 317,-5 337,3l-1,115C321,115 312,114 291,114C245,114 231,141 231,200l0,177l109,0l0,112l-109,0l0,133z"/>
<glyph unicode="3" horiz-adv-x="555" d="M38,35C76,11 147,-11 231,-11C396,-11 497,73 497,188C497,273 434,332 356,346l0,2C436,376 475,430 475,499C475,588 398,661 259,661C175,661 97,637 58,612l31,-110C116,518 172,541 225,541C289,541 321,512 321,473C321,418 256,399 205,398l-59,0l0,-109l62,0C275,289 339,260 339,196C339,147 299,109 220,109C158,109 96,135 69,149z"/>
<glyph unicode="2" horiz-adv-x="555" d="M503,0l0,125l-245,0l0,2l60,50C412,261 491,348 491,457C491,575 410,661 263,661C175,661 99,631 50,594l43,-109C127,511 176,539 232,539C307,539 339,497 339,444C337,368 268,295 126,168l-84,-76l0,-92z"/>
</font>
<font horiz-adv-x="1000">
<!-- Copyright 2000, 2004 , 2005Adobe Systems Incorporated. All Rights Reserved. U.S. Patent D454,582.Myriad is a registered trademark of Adobe Systems Incorporated. -->
<font-face font-family="MyriadPro-Regular" units-per-em="1000" underline-position="-100" underline-thickness="50"/>
<missing-glyph horiz-adv-x="500" d="M0,0l500,0l0,700l-500,0M250,395l-170,255l340,0M280,350l170,255l0,-510M80,50l170,255l170,-255M50,605l170,-255l-170,-255z"/>
<glyph unicode="a" horiz-adv-x="482" d="M413,297C413,394 377,495 229,495C168,495 110,478 70,452l20,-58C124,416 171,430 216,430C315,430 326,358 326,318l0,-10C139,309 35,245 35,128C35,58 85,-11 183,-11C252,-11 304,23 331,61l3,0l7,-61l80,0C415,33 413,74 413,116M328,163C328,154 326,144 323,135C309,94 269,54 206,54C161,54 123,81 123,138C123,232 232,249 328,247z"/>
<glyph unicode="b" horiz-adv-x="569" d="M73,125C73,82 71,33 69,0l76,0l4,80l3,0C188,16 244,-11 314,-11C422,-11 531,75 531,248C532,395 447,495 327,495C249,495 193,460 162,406l-2,0l0,304l-87,0M160,281C160,295 163,307 165,317C183,384 239,425 299,425C393,425 443,342 443,245C443,134 388,59 296,59C232,59 181,101 164,162C162,172 160,183 160,194z"/>
<glyph unicode="e" horiz-adv-x="501" d="M462,226C463,235 465,249 465,267C465,356 423,495 265,495C124,495 38,380 38,234C38,88 127,-11 276,-11C353,-11 406,6 437,20l-15,63C389,69 351,58 288,58C200,58 124,107 122,226M123,289C130,350 169,432 258,432C357,432 381,345 380,289z"/>
<glyph unicode="f" horiz-adv-x="292" d="M169,0l0,417l117,0l0,67l-117,0l0,26C169,584 188,650 263,650C288,650 306,645 319,639l12,68C314,714 287,721 256,721C215,721 171,708 138,676C97,637 82,575 82,507l0,-23l-68,0l0,-67l68,0l0,-417z"/>
<glyph unicode="g" horiz-adv-x="559" d="M486,351C486,410 488,449 490,484l-77,0l-4,-73l-2,0C386,451 340,495 256,495C145,495 38,402 38,238C38,104 124,2 244,2C319,2 371,38 398,83l2,0l0,-54C400,-93 334,-140 244,-140C184,-140 134,-122 102,-102l-22,-67C119,-195 183,-209 241,-209C302,-209 370,-195 417,-151C464,-109 486,-41 486,70M399,206C399,191 397,174 392,159C373,103 324,69 270,69C175,69 127,148 127,243C127,355 187,426 271,426C335,426 378,384 394,333C398,321 399,308 399,293z"/>
<glyph unicode="h" horiz-adv-x="555" d="M73,0l88,0l0,292C161,309 162,322 167,334C183,382 228,422 285,422C368,422 397,356 397,278l0,-278l88,0l0,288C485,455 381,495 316,495C283,495 252,485 226,470C199,455 177,433 163,408l-2,0l0,302l-88,0z"/>
<glyph unicode="i" horiz-adv-x="234" d="M161,0l0,484l-88,0l0,-484M117,675C85,675 62,651 62,620C62,590 84,566 115,566C150,566 172,590 171,620C171,651 150,675 117,675z"/>
<glyph unicode="l" horiz-adv-x="236" d="M73,0l88,0l0,710l-88,0z"/>
<glyph unicode="m" horiz-adv-x="834" d="M73,0l86,0l0,292C159,307 161,322 166,335C180,379 220,423 275,423C342,423 376,367 376,290l0,-290l86,0l0,299C462,315 465,331 469,343C484,386 523,423 573,423C644,423 678,367 678,274l0,-274l86,0l0,285C764,453 669,495 605,495C559,495 527,483 498,461C478,446 459,425 444,398l-2,0C421,455 371,495 305,495C225,495 180,452 153,406l-3,0l-4,78l-77,0C72,444 73,403 73,353z"/>
<glyph unicode="n" horiz-adv-x="555" d="M73,0l88,0l0,291C161,306 163,321 167,332C182,381 227,422 285,422C368,422 397,357 397,279l0,-279l88,0l0,289C485,455 381,495 314,495C234,495 178,450 154,404l-2,0l-5,80l-78,0C72,444 73,403 73,353z"/>
<glyph unicode="o" horiz-adv-x="549" d="M278,495C144,495 38,400 38,238C38,85 139,-11 270,-11C387,-11 511,67 511,246C511,394 417,495 278,495M276,429C380,429 421,325 421,243C421,134 358,55 274,55C188,55 127,135 127,241C127,333 172,429 276,429z"/>
<glyph unicode="p" horiz-adv-x="569" d="M73,-198l87,0l0,263l2,0C191,17 247,-11 311,-11C425,-11 531,75 531,249C531,396 443,495 326,495C247,495 190,460 154,401l-2,0l-4,83l-79,0C71,438 73,388 73,326M160,280C160,292 163,305 166,316C183,382 239,425 299,425C392,425 443,342 443,245C443,134 389,58 296,58C233,58 180,100 164,161C162,172 160,184 160,197z"/>
<glyph unicode="r" horiz-adv-x="327" d="M73,0l87,0l0,258C160,273 162,287 164,299C176,365 220,412 282,412C294,412 303,411 312,409l0,83C304,494 297,495 287,495C228,495 175,454 153,389l-4,0l-3,95l-77,0C72,439 73,390 73,333z"/>
<glyph unicode=" " horiz-adv-x="212"/>
<glyph unicode="t" horiz-adv-x="331" d="M93,573l0,-89l-75,0l0,-67l75,0l0,-264C93,96 102,53 127,27C148,3 181,-11 222,-11C256,-11 283,-5 300,2l-4,66C283,64 269,62 245,62C196,62 179,96 179,156l0,261l126,0l0,67l-126,0l0,116z"/>
</font>
<g>
<g>
<polyline fill="none" stroke="#000000" stroke-miterlimit="10" points="418.2,95.1 418.2,101.1 412.2,101.1 "/>
<line fill="none" stroke="#000000" stroke-miterlimit="10" stroke-dasharray="12.2842,12.2842" x1="399.9" y1="101.1" x2="37.5" y2="101.1"/>
<polyline fill="none" stroke="#000000" stroke-miterlimit="10" points="31.4,101.1 25.4,101.1 25.4,95.1 "/>
<line fill="none" stroke="#000000" stroke-miterlimit="10" stroke-dasharray="11.6852,11.6852" x1="25.4" y1="83.4" x2="25.4" y2="42.5"/>
<polyline fill="none" stroke="#000000" stroke-miterlimit="10" points="25.4,36.6 25.4,30.6 31.4,30.6 "/>
<line fill="none" stroke="#000000" stroke-miterlimit="10" stroke-dasharray="12.2842,12.2842" x1="43.6" y1="30.6" x2="406" y2="30.6"/>
<polyline fill="none" stroke="#000000" stroke-miterlimit="10" points="412.2,30.6 418.2,30.6 418.2,36.6 "/>
<line fill="none" stroke="#000000" stroke-miterlimit="10" stroke-dasharray="11.6852,11.6852" x1="418.2" y1="48.3" x2="418.2" y2="89.2"/>
</g>
</g>
<rect x="14.7" y="19.5" fill="none" stroke="#000000" stroke-miterlimit="10" width="414.1" height="92.7"/>
<g>
<rect x="34" y="58.4" fill="#349980" stroke="#000000" stroke-miterlimit="10" width="87.4" height="20.8"/>
<text transform="matrix(1 0 0 1 55.2495 72.3085)" font-family="'MyriadPro-Bold'" font-size="12">Widget 1</text>
</g>
<g>
<rect x="144.1" y="48.3" fill="#349980" stroke="#000000" stroke-miterlimit="10" width="102.2" height="41"/>
<text transform="matrix(1 0 0 1 172.7653 72.3085)" font-family="'MyriadPro-Bold'" font-size="12">Widget 2</text>
</g>
<g>
<rect x="275.8" y="44" fill="#349980" stroke="#000000" stroke-miterlimit="10" width="120" height="42.2"/>
<text transform="matrix(1 0 0 1 313.3092 68.6263)" font-family="'MyriadPro-Bold'" font-size="12">Widget 3</text>
</g>
<g>
<g>
<line fill="none" stroke="#000000" stroke-miterlimit="10" x1="15.9" y1="35.1" x2="24.2" y2="35.1"/>
<g>
<polygon points="17.9,36.8 16.2,35.1 17.9,33.4 16.4,33.4 14.7,35.1 16.4,36.8 "/>
</g>
<g>
<polygon points="22.2,36.8 23.9,35.1 22.2,33.4 23.7,33.4 25.4,35.1 23.7,36.8 "/>
</g>
</g>
</g>
<g>
<g>
<line fill="none" stroke="#000000" stroke-miterlimit="10" x1="419.3" y1="32.1" x2="427.7" y2="32.1"/>
<g>
<polygon points="421.3,33.8 419.6,32.1 421.3,30.4 419.9,30.4 418.2,32.1 419.9,33.8 "/>
</g>
<g>
<polygon points="425.7,33.8 427.4,32.1 425.7,30.4 427.1,30.4 428.8,32.1 427.1,33.8 "/>
</g>
</g>
</g>
<g>
<line fill="#13007C" x1="395.8" y1="69.1" x2="418.2" y2="69.1"/>
<g>
<line fill="none" stroke="#FF8000" stroke-miterlimit="10" x1="396.9" y1="69.1" x2="417" y2="69.1"/>
<g>
<polygon fill="#FF8000" points="398.9,70.8 397.2,69.1 398.9,67.4 397.5,67.4 395.8,69.1 397.5,70.8 "/>
</g>
<g>
<polygon fill="#FF8000" points="415,70.8 416.7,69.1 415,67.4 416.5,67.4 418.2,69.1 416.5,70.8 "/>
</g>
</g>
</g>
<g>
<line fill="#13007C" x1="245.7" y1="69.1" x2="275.8" y2="69.1"/>
<g>
<line fill="none" stroke="#FF8000" stroke-miterlimit="10" x1="246.9" y1="69.1" x2="274.6" y2="69.1"/>
<g>
<polygon fill="#FF8000" points="248.9,70.8 247.2,69.1 248.9,67.4 247.4,67.4 245.7,69.1 247.4,70.8 "/>
</g>
<g>
<polygon fill="#FF8000" points="272.6,70.8 274.3,69.1 272.6,67.4 274.1,67.4 275.8,69.1 274.1,70.8 "/>
</g>
</g>
</g>
<g>
<g>
<line fill="none" stroke="#FF8000" stroke-miterlimit="10" x1="122.5" y1="68.8" x2="143" y2="68.8"/>
<g>
<polygon fill="#FF8000" points="124.5,70.5 122.8,68.8 124.5,67.1 123.1,67.1 121.4,68.8 123.1,70.5 "/>
</g>
<g>
<polygon fill="#FF8000" points="141,70.5 142.7,68.8 141,67.1 142.4,67.1 144.1,68.8 142.4,70.5 "/>
</g>
</g>
</g>
<g>
<line fill="#13007C" x1="25.4" y1="71.1" x2="34" y2="71.1"/>
<g>
<line fill="none" stroke="#FF8000" stroke-miterlimit="10" x1="26.5" y1="71.1" x2="32.9" y2="71.1"/>
<g>
<polygon fill="#FF8000" points="28.5,72.8 26.8,71.1 28.5,69.4 27.1,69.4 25.4,71.1 27.1,72.8 "/>
</g>
<g>
<polygon fill="#FF8000" points="30.9,72.8 32.6,71.1 30.9,69.4 32.3,69.4 34,71.1 32.3,72.8 "/>
</g>
</g>
</g>
<g>
<line fill="#13007C" x1="73.2" y1="58.9" x2="73.2" y2="30.6"/>
<g>
<line fill="none" stroke="#FF8000" stroke-miterlimit="10" x1="73.2" y1="57.8" x2="73.2" y2="31.8"/>
<g>
<polygon fill="#FF8000" points="74.9,55.8 73.2,57.5 71.5,55.8 71.5,57.2 73.2,58.9 74.9,57.2 "/>
</g>
<g>
<polygon fill="#FF8000" points="74.9,33.8 73.2,32.1 71.5,33.8 71.5,32.3 73.2,30.6 74.9,32.3 "/>
</g>
</g>
</g>
<g>
<line fill="#13007C" x1="73.2" y1="100.7" x2="73.2" y2="79.2"/>
<g>
<line fill="none" stroke="#FF8000" stroke-miterlimit="10" x1="73.2" y1="99.6" x2="73.2" y2="80.3"/>
<g>
<polygon fill="#FF8000" points="74.9,97.6 73.2,99.3 71.5,97.6 71.5,99 73.2,100.7 74.9,99 "/>
</g>
<g>
<polygon fill="#FF8000" points="74.9,82.3 73.2,80.6 71.5,82.3 71.5,80.9 73.2,79.2 74.9,80.9 "/>
</g>
</g>
</g>
<g>
<line fill="#13007C" x1="195.2" y1="100.6" x2="195.2" y2="89.9"/>
<g>
<line fill="none" stroke="#FF8000" stroke-miterlimit="10" x1="195.2" y1="99.4" x2="195.2" y2="91.1"/>
<g>
<polygon fill="#FF8000" points="196.9,97.4 195.2,99.1 193.5,97.4 193.5,98.9 195.2,100.6 196.9,98.9 "/>
</g>
<g>
<polygon fill="#FF8000" points="196.9,93.1 195.2,91.4 193.5,93.1 193.5,91.6 195.2,89.9 196.9,91.6 "/>
</g>
</g>
</g>
<g>
<line fill="#13007C" x1="189.9" y1="48.3" x2="189.9" y2="30.6"/>
<g>
<line fill="none" stroke="#FF8000" stroke-miterlimit="10" x1="189.9" y1="47.1" x2="189.9" y2="31.8"/>
<g>
<polygon fill="#FF8000" points="191.6,45.1 189.9,46.8 188.2,45.1 188.2,46.6 189.9,48.3 191.6,46.6 "/>
</g>
<g>
<polygon fill="#FF8000" points="191.6,33.8 189.9,32.1 188.2,33.8 188.2,32.3 189.9,30.6 191.6,32.3 "/>
</g>
</g>
</g>
<g>
<line fill="#13007C" x1="330.9" y1="101.1" x2="330.9" y2="86.2"/>
<g>
<line fill="none" stroke="#FF8000" stroke-miterlimit="10" x1="330.9" y1="99.9" x2="330.9" y2="87.3"/>
<g>
<polygon fill="#FF8000" points="332.6,97.9 330.9,99.6 329.2,97.9 329.2,99.4 330.9,101.1 332.6,99.4 "/>
</g>
<g>
<polygon fill="#FF8000" points="332.6,89.3 330.9,87.6 329.2,89.3 329.2,87.9 330.9,86.2 332.6,87.9 "/>
</g>
</g>
</g>
<g>
<line fill="#13007C" x1="330.9" y1="44" x2="330.9" y2="30.6"/>
<g>
<line fill="none" stroke="#FF8000" stroke-miterlimit="10" x1="330.9" y1="42.9" x2="330.9" y2="31.8"/>
<g>
<polygon fill="#FF8000" points="332.6,40.9 330.9,42.6 329.2,40.9 329.2,42.3 330.9,44 332.6,42.3 "/>
</g>
<g>
<polygon fill="#FF8000" points="332.6,33.8 330.9,32.1 329.2,33.8 329.2,32.3 330.9,30.6 332.6,32.3 "/>
</g>
</g>
</g>
<g>
<g>
<line fill="none" stroke="#000000" stroke-miterlimit="10" x1="175.8" y1="111" x2="175.8" y2="102.7"/>
<g>
<polygon points="177.5,109.1 175.8,110.7 174.1,109.1 174.1,110.5 175.8,112.2 177.5,110.5 "/>
</g>
<g>
<polygon points="177.5,104.7 175.8,103 174.1,104.7 174.1,103.2 175.8,101.6 177.5,103.2 "/>
</g>
</g>
</g>
<g>
<g>
<line fill="none" stroke="#000000" stroke-miterlimit="10" x1="172.8" y1="29" x2="172.8" y2="20.7"/>
<g>
<polygon points="174.5,27 172.8,28.7 171.1,27 171.1,28.4 172.8,30.1 174.5,28.4 "/>
</g>
<g>
<polygon points="174.5,22.6 172.8,20.9 171.1,22.6 171.1,21.2 172.8,19.5 174.5,21.2 "/>
</g>
</g>
</g>
<text transform="matrix(1 0 0 1 175.7678 27.3395)" font-family="'MyriadPro-Regular'" font-size="10">top margin</text>
<text transform="matrix(1 0 0 1 178.9794 109.875)" font-family="'MyriadPro-Regular'" font-size="10">bottom margin</text>
<text transform="matrix(1 0 0 1 1.220703e-04 16.7404)" font-family="'MyriadPro-Regular'" font-size="10">left margin</text>
<text transform="matrix(1 0 0 1 397.8374 16.7405)" font-family="'MyriadPro-Regular'" font-size="10">right margin</text>
<text transform="matrix(1 0 0 1 199.7852 8.3701)" font-family="'MyriadPro-Bold'" font-size="10">Container</text>
</svg>

After

Width:  |  Height:  |  Size: 17 KiB

View File

@@ -0,0 +1,13 @@
.. _uses:
Kiwisolver real uses
====================
The following sections describe how kiwisolver is used in third-party project,
and aim at providing more involved example of how kiwisolver can be used in
real life project.
.. toctree::
:maxdepth: 2
enaml.rst