Difference between revisions of "UI"
From Future Skill
(18 intermediate revisions by 3 users not shown) | |||
Line 43: | Line 43: | ||
All elements can have a parent, and some can have children. | All elements can have a parent, and some can have children. | ||
If an element switches parent it will be removed from the previous parent's list of children. | If an element switches parent it will be removed from the previous parent's list of children. | ||
− | You can either use the <code>parent</code> attribute or the <code>.add_child(child)</code>/<code>.remove_child(child)</code> methods to update the | + | You can either use the <code>parent</code> attribute or the <code>.add_child(child)</code>/<code>.remove_child(child)</code> methods to update the hierarchy. |
But remember that for an element to show up in the canvas it needs to have it as an ancestor. | But remember that for an element to show up in the canvas it needs to have it as an ancestor. | ||
Line 61: | Line 61: | ||
Remember to add the element to the import list, or you will get an error. | Remember to add the element to the import list, or you will get an error. | ||
+ | |||
+ | All elements extend either the <code>BaseElement</code> or <code>ContainerElement</code> base class which provides the [[#Common|common]] and [[#Container|container]] attributes and methods. | ||
=== Shapes === | === Shapes === | ||
Line 72: | Line 74: | ||
Use to make squares, rectangles and rounded rectangles. | Use to make squares, rectangles and rounded rectangles. | ||
− | General attributes: [[#Common|common]], [[#Container|container]], [[#Shape|shape]], [[#Action|action]], [[#Click|click]], [[#Drag|drag]] | + | General attributes/methods: [[#Common|common]], [[#Container|container]], [[#Shape|shape]], [[#Action|action]], [[#Click|click]], [[#Drag|drag]], [[#Keyboard|keyboard]] |
;<code>corner_radius</code> - <code>float | None</code> S | ;<code>corner_radius</code> - <code>float | None</code> S | ||
: Add rounded corners to the rectangle | : Add rounded corners to the rectangle | ||
Line 83: | Line 85: | ||
Use to make circles. | Use to make circles. | ||
− | General attributes: [[#Common|common]], [[#Container|container]], [[#Shape|shape]], [[#Action|action]], [[#Click|click]], [[#Drag|drag]] | + | General attributes/methods: [[#Common|common]], [[#Container|container]], [[#Shape|shape]], [[#Action|action]], [[#Click|click]], [[#Drag|drag]], [[#Keyboard|keyboard]] |
;<code>radius</code>/<code>r</code> - <code>float</code> S | ;<code>radius</code>/<code>r</code> - <code>float</code> S | ||
: The radius of the circle, use instead of <code>width</code>/<code>height</code> | : The radius of the circle, use instead of <code>width</code>/<code>height</code> | ||
Line 99: | Line 101: | ||
Use to make any other straight edge shapes. | Use to make any other straight edge shapes. | ||
− | Consider using images if you need | + | Consider using images if you need a large number of points. |
− | General attributes: [[#Common|common]], [[#Container|container]], [[#Shape|shape]], [[#Action|action]], [[#Click|click]], [[#Drag|drag]] | + | General attributes/methods: [[#Common|common]], [[#Container|container]], [[#Shape|shape]], [[#Action|action]], [[#Click|click]], [[#Drag|drag]], [[#Keyboard|keyboard]] |
;<code>points</code> - <code>list[tuple[float, float]]</code> R | ;<code>points</code> - <code>list[tuple[float, float]]</code> R | ||
: A list of points to use to draw the polygon, required and positional | : A list of points to use to draw the polygon, required and positional | ||
Line 108: | Line 110: | ||
<div class="mw-collapsible-content" style="background: #F0F0F0"> | <div class="mw-collapsible-content" style="background: #F0F0F0"> | ||
<nowiki>Polygon([(0, -5), (5, 5), (-5, 5)], color="red")</nowiki> | <nowiki>Polygon([(0, -5), (5, 5), (-5, 5)], color="red")</nowiki> | ||
+ | </div> | ||
+ | |||
+ | ==== ComplexShape ==== | ||
+ | |||
+ | Use to make a shape with straight or Bézier curves. | ||
+ | Consider using images if you need very complex shapes or a large number of points. | ||
+ | |||
+ | General attributes/methods: [[#Common|common]], [[#Container|container]], [[#Shape|shape]], [[#Action|action]], [[#Click|click]], [[#Drag|drag]], [[#Keyboard|keyboard]] | ||
+ | ;<code>segments</code> - <code>list[list[tuple[float, float]]]</code> R | ||
+ | : A list of segments (list of points) to use to draw the shape, required and positional | ||
+ | : Each segment must consist of one to three points (first must be one point): | ||
+ | :* Single point means a straight line to that point | ||
+ | :* Two points is a quadratic Bézier curve with a control point (first) and an end point (second) | ||
+ | :* Three points is a cubic Bézier curve with two control points and an end point (last) | ||
+ | ;<code>bounds</code> - <code>tuple[tuple[float, float], tuple[float, float]]</code> S | ||
+ | : The bounds of the shape used to determine size and pivot, calculated if omitted | ||
+ | ;<code>closed</code> - <code>bool</code> S | ||
+ | : Whether the shape should be closed or not | ||
+ | <div class="mw-collapsible-content" style="background: #F0F0F0"> | ||
+ | <nowiki>ComplexShape([[(0, 0)], [(5, 5), (0, 10)], [(10, 10)], [(5, 5), (15, 5), (10, 0)]], color="green")</nowiki> | ||
</div> | </div> | ||
Line 118: | Line 140: | ||
Simple text element. The size is based on the text string and font size. | Simple text element. The size is based on the text string and font size. | ||
− | General attributes: [[#Common|common]], [[#Action|action]], [[#Click|click]], [[#Drag|drag]] | + | General attributes/methods: [[#Common|common]], [[#Action|action]], [[#Click|click]], [[#Drag|drag]], [[#Keyboard|keyboard]] |
;<code>text</code> - <code>str</code> | ;<code>text</code> - <code>str</code> | ||
: The text to display, required and positional | : The text to display, required and positional | ||
Line 134: | Line 156: | ||
Alternative to <code>Text</code> where the text is adjusted to fit within the size rather than the other way around. | Alternative to <code>Text</code> where the text is adjusted to fit within the size rather than the other way around. | ||
− | |||
− | General attributes: [[#Common|common]], [[#Action|action]], [[#Click|click]], [[#Drag|drag]] | + | General attributes/methods: [[#Common|common]], [[#Action|action]], [[#Click|click]], [[#Drag|drag]], [[#Keyboard|keyboard]], [[#FitToContent|fit to content]] |
;<code>text</code> - <code>str</code> | ;<code>text</code> - <code>str</code> | ||
: The text to display, required and positional | : The text to display, required and positional | ||
Line 157: | Line 178: | ||
It is possible to include images and CSS, using normal HTML syntax. | It is possible to include images and CSS, using normal HTML syntax. | ||
− | General attributes: [[#Common|common]], [[#Scroll|scroll]] | + | General attributes/methods: [[#Common|common]], [[#Scroll|scroll]] |
;<code>html</code> - <code>str</code> | ;<code>html</code> - <code>str</code> | ||
: The HTML text to display, required and positional | : The HTML text to display, required and positional | ||
Line 164: | Line 185: | ||
;<code>align_x</code> - <code>"left" | "right" | "center"</code> | ;<code>align_x</code> - <code>"left" | "right" | "center"</code> | ||
: The horizontal text align | : The horizontal text align | ||
+ | ;<code>disable_scroll</code> - <code>bool</code> | ||
+ | : Disables scroll and all ScrollArea features so it will limit the HtmlArea to its width and height. | ||
+ | ;<code>disable_auto_font_scale</code> - <code>bool</code> | ||
+ | : Disables auto font scale and the text font size will be applied. | ||
<div class="mw-collapsible-content" style="background: #F0F0F0"> | <div class="mw-collapsible-content" style="background: #F0F0F0"> | ||
− | <nowiki>HtmlArea("Hello <b>World</b>!", font_size=5, w=50, h=20)</nowiki> | + | <nowiki>HtmlArea("Hello <b>World</b>!", font_size=5, w=50, h=20, disable_scroll=True, disable_auto_font_scale=True)</nowiki> |
</div> | </div> | ||
Line 176: | Line 201: | ||
Displays a static image. | Displays a static image. | ||
− | General attributes: [[#Common|common]], [[#Action|action]], [[#Click|click]], [[#Drag|drag]] | + | General attributes/methods: [[#Common|common]], [[#Action|action]], [[#Click|click]], [[#Drag|drag]], [[#Keyboard|keyboard]] |
;<code>image</code> - <code>str</code> S | ;<code>image</code> - <code>str</code> S | ||
: The name of the image to show | : The name of the image to show | ||
Line 189: | Line 214: | ||
Displays an animated image. | Displays an animated image. | ||
− | General attributes: [[#Common|common]], [[#Action|action]], [[#Click|click]], [[#Drag|drag]] | + | General attributes/methods: [[#Common|common]], [[#Action|action]], [[#Click|click]], [[#Drag|drag]], [[#Keyboard|keyboard]] |
;<code>image</code> - <code>str</code> S | ;<code>image</code> - <code>str</code> S | ||
: The name of the image to show | : The name of the image to show | ||
Line 212: | Line 237: | ||
Use when you want some content to be scrollable (vertical and/or horizontal). | Use when you want some content to be scrollable (vertical and/or horizontal). | ||
− | General attributes: [[#Common|common]], [[#Scroll|scroll]] | + | General attributes/methods: [[#Common|common]], [[#Scroll|scroll]] |
<div class="mw-collapsible-content" style="background: #F0F0F0"> | <div class="mw-collapsible-content" style="background: #F0F0F0"> | ||
<nowiki>scroll = ScrollArea(w=40, h=20) | <nowiki>scroll = ScrollArea(w=40, h=20) | ||
Line 223: | Line 248: | ||
Consider putting tab content into <code>ScrollArea</code>s for even more space. | Consider putting tab content into <code>ScrollArea</code>s for even more space. | ||
− | General attributes: [[#Common|common]], [[#Style|style]] | + | General attributes/methods: [[#Common|common]], [[#Style|style]] |
;<code>tabs</code> - <code>dict[str, BaseElement]</code> | ;<code>tabs</code> - <code>dict[str, BaseElement]</code> | ||
: The tab names and content to include, required and positional, constructor only | : The tab names and content to include, required and positional, constructor only | ||
Line 238: | Line 263: | ||
These elements can be used to simplify positioning of elements. | These elements can be used to simplify positioning of elements. | ||
− | They handle | + | They handle addition, removal and resizing of elements as well. |
+ | Also, these elements cascade resizing down to any children. Other elements like Rectangle are resized if the parent is a Layout element, but a Rectangle doesn't cascade resizing to its children. | ||
==== Horizontal ==== | ==== Horizontal ==== | ||
Line 244: | Line 270: | ||
Use to position elements horizontally. | Use to position elements horizontally. | ||
− | General attributes: [[#Common|common]], [[#Layout|Layout]] | + | General attributes/methods: [[#Common|common]], [[#Layout|Layout]] |
All positional arguments are added as children | All positional arguments are added as children | ||
+ | ;<code>proportions</code> - <code>list[float]</code> | ||
+ | : Proportions of size to give to each element, 0 means an even proportion of the remaining space | ||
<div class="mw-collapsible-content" style="background: #F0F0F0"> | <div class="mw-collapsible-content" style="background: #F0F0F0"> | ||
<nowiki>Horizontal(Rectangle(color="yellow"), Rectangle(color="magenta"), Rectangle(color="cyan"))</nowiki> | <nowiki>Horizontal(Rectangle(color="yellow"), Rectangle(color="magenta"), Rectangle(color="cyan"))</nowiki> | ||
Line 255: | Line 283: | ||
Use to position elements vertically. | Use to position elements vertically. | ||
− | General attributes: [[#Common|common]], [[#Layout|Layout]] | + | General attributes/methods: [[#Common|common]], [[#Layout|Layout]] |
All positional arguments are added as children | All positional arguments are added as children | ||
+ | ;<code>proportions</code> - <code>list[float]</code> | ||
+ | : Proportions of size to give to each element, 0 means an even proportion of the remaining space | ||
<div class="mw-collapsible-content" style="background: #F0F0F0"> | <div class="mw-collapsible-content" style="background: #F0F0F0"> | ||
<nowiki>Vertical(*[Text(str(i)) for i in range(5)], spacing=5)</nowiki> | <nowiki>Vertical(*[Text(str(i)) for i in range(5)], spacing=5)</nowiki> | ||
Line 266: | Line 296: | ||
Use to position elements in a grid. | Use to position elements in a grid. | ||
− | General attributes: [[#Common|common]], [[#Layout|Layout]] | + | General attributes/methods: [[#Common|common]], [[#Layout|Layout]] |
All positional arguments are added as children | All positional arguments are added as children | ||
+ | ;<code>rows</code> - <code>int</code> | ||
+ | : Number of rows in the grid, calculated if not set | ||
;<code>columns</code> - <code>int</code> | ;<code>columns</code> - <code>int</code> | ||
− | : Number of columns in the grid, | + | : Number of columns in the grid, calculated if not set |
+ | ;<code>transpose</code> - <code>bool</code> | ||
+ | : Whether to place columns first, rather than rows first | ||
+ | ;<code>alignments</code> - <code>tuple[list["left" | "right" | "center" | None], list["top" | "bottom" | "center" | None]</code> | ||
+ | : Alignments for each column or row and column, None means use the <code>align_x/align_y</code> value | ||
+ | ;<code>proportions</code> - <code>tuple[list[float], list[float]</code> | ||
+ | : Proportions of size to give to each row and column, 0 means an even proportion of the remaining space | ||
<div class="mw-collapsible-content" style="background: #F0F0F0"> | <div class="mw-collapsible-content" style="background: #F0F0F0"> | ||
<nowiki>Grid(*[Text(str(i)) for i in range(20)], columns=5, w=30, h=30, spacing=5)</nowiki> | <nowiki>Grid(*[Text(str(i)) for i in range(20)], columns=5, w=30, h=30, spacing=5)</nowiki> | ||
Line 283: | Line 321: | ||
Use to create a button. | Use to create a button. | ||
− | General attributes: [[#Common|common]], [[#Style|style]], [[#Action|action]], [[#Click|click]] | + | General attributes/methods: [[#Common|common]], [[#Style|style]], [[#Action|action]], [[#Click|click]], [[#FitToContent|fit to content]] |
;<code>text</code> - <code>str</code> | ;<code>text</code> - <code>str</code> | ||
: The text on the button, required and positional | : The text on the button, required and positional | ||
Line 315: | Line 353: | ||
Use to create a checkbox. | Use to create a checkbox. | ||
− | General attributes: [[#Common|common]], [[#Style|style]], [[#Action|action]], [[#Click|click]] | + | General attributes/methods: [[#Common|common]], [[#Style|style]], [[#Action|action]], [[#Click|click]] |
;<code>checked</code> - <code>bool</code> S | ;<code>checked</code> - <code>bool</code> S | ||
: Whether the checkbox is checked or not | : Whether the checkbox is checked or not | ||
Line 345: | Line 383: | ||
==== Panel ==== | ==== Panel ==== | ||
− | A simple panel. | + | A simple panel. Can have a title and a title image. Can also have content with will be resized based on the panel size. |
− | General attributes: [[#Common|common]], [[#Style|style]] | + | General attributes/methods: [[#Common|common]], [[#Style|style]] |
+ | ;<code>content</code> - <code>BaseElement</code> R | ||
+ | : Content to but inside the panel, constructor only | ||
+ | ;<code>title</code> - <code>str</code> R | ||
+ | : A title for the panel, constructor only | ||
+ | ;<code>title_image</code> - <code>str</code> | ||
+ | : An image to put in the top-right corner of the panel, only visible if a title is set | ||
+ | ;<code>font_size</code> - <code>float</code> | ||
+ | : The font size of the title text | ||
;<code>corner_radius</code> - <code>float | None</code> | ;<code>corner_radius</code> - <code>float | None</code> | ||
: The radius of the corners of the panel, set to <code>None</code> for a square panel | : The radius of the corners of the panel, set to <code>None</code> for a square panel | ||
;<code>overlay</code> - <code>bool</code> | ;<code>overlay</code> - <code>bool</code> | ||
: Whether to use the overlay styling for this panel or not | : Whether to use the overlay styling for this panel or not | ||
+ | ;<code>spacing</code> - <code>float</code> | ||
+ | : The distance between the title and content | ||
+ | ;<code>padding</code> - <code>float</code> | ||
+ | : The distance between panel content/title and the outer edge | ||
<div class="mw-collapsible-content" style="background: #F0F0F0"> | <div class="mw-collapsible-content" style="background: #F0F0F0"> | ||
− | <nowiki>Panel(w=50, h=50, | + | <nowiki>Panel(w=50, h=50, content=Circle(color="blue"), title="My Panel")</nowiki> |
</div> | </div> | ||
Line 361: | Line 411: | ||
Children within each area are arranged horizontally. | Children within each area are arranged horizontally. | ||
− | General attributes: [[#Common|common]], [[#Style|style]] | + | General attributes/methods: [[#Common|common]], [[#Style|style]] |
;<code>corner_radius</code> - <code>float | None</code> | ;<code>corner_radius</code> - <code>float | None</code> | ||
: The radius of the corners of the panel, set to <code>None</code> for a square panel | : The radius of the corners of the panel, set to <code>None</code> for a square panel | ||
Line 388: | Line 438: | ||
Only works properly in interact mode. | Only works properly in interact mode. | ||
− | General attributes: [[#Common|common]], [[#Style|style]] | + | General attributes/methods: [[#Common|common]], [[#Style|style]] |
;<code>text</code> - <code>str</code> R | ;<code>text</code> - <code>str</code> R | ||
: The message to display, required and positional, constructor only | : The message to display, required and positional, constructor only | ||
Line 423: | Line 473: | ||
There can only be one element at each coordinate, which can be fetch like so: <code>board[0, 2]</code>. | There can only be one element at each coordinate, which can be fetch like so: <code>board[0, 2]</code>. | ||
− | General attributes: [[#Common|common]], [[#Style|style]] | + | General attributes/methods: [[#Common|common]], [[#Style|style]] |
;<code>rows</code> - <code>int</code> R | ;<code>rows</code> - <code>int</code> R | ||
: How many rows the board should have | : How many rows the board should have | ||
Line 461: | Line 511: | ||
It is recommended to use those rather than using this element directly. | It is recommended to use those rather than using this element directly. | ||
− | General attributes: [[#Common|common]], [[#Style|style]] | + | General attributes/methods: [[#Common|common]], [[#Style|style]] |
;<code>content</code> - <code>BaseElement</code> R | ;<code>content</code> - <code>BaseElement</code> R | ||
: The main content to put in the middle of the stage, required and positional, constructor only | : The main content to put in the middle of the stage, required and positional, constructor only | ||
Line 481: | Line 531: | ||
: The height of the toolbar | : The height of the toolbar | ||
− | == Attributes == | + | ==== SpeechBubble ==== |
+ | |||
+ | Use to create a speech bubble. Mainly used by the <code>.say(...)</code> command for character actors in [[World|world]]. | ||
+ | |||
+ | General attributes/methods: [[#Common|common]], [[#FitToContent|fit to content]] | ||
+ | ;<code>text</code> - <code>str</code> S | ||
+ | : The text within the speech bubble, required and positional | ||
+ | ;<code>font_size</code> - <code>float</code> S | ||
+ | : The desired text font size | ||
+ | ;<code>settings</code> - <code>SpeechBubbleSettings</code> S | ||
+ | : Specifies the shape of the speech bubble: | ||
+ | :* <code>radius</code> - The radius of the speech-bubble "corners" | ||
+ | :* <code>tail_inset</code> - How far in the tail should be positioned (x-offset) | ||
+ | :* <code>tail_width</code> - How thick the tail should be | ||
+ | :* <code>tail_height</code> - How tall the tail should be | ||
+ | :* <code>tail_point_offset</code> - How the tail tip should be positioned (x-offset) | ||
+ | :* <code>tail_position</code> - Where to put the tail, one of "bottom_left", "bottom_right", "top_left", or "top_right" | ||
+ | :* <code>shadow_height</code> - How high up the lower shading of the bubble should go | ||
+ | :* <code>edge_size</code> - How thick the edge around the bubble should be | ||
+ | ;<code>theme</code> - <code>SpeechBubbleTheme</code> | ||
+ | : Specifies the color scheme of the speech bubble: | ||
+ | :* <code>text_color</code> - The color of the text | ||
+ | :* <code>bubble_color</code> - The background color of the bubble | ||
+ | :* <code>shadow_color</code> - The shading color of the bubble | ||
+ | :* <code>edge_color</code> - The color of the bubble edge | ||
+ | ;<code>auto_fit</code> - <code>bool</code> | ||
+ | : Whether to automatically resize the bubble to fit the text or not, can use <code>.fit_to_content()</code> manually) | ||
+ | ;<code>auto_anchor</code> - <code>bool</code> | ||
+ | : Whether to automatically anchor the element position to the tail tip or not, can use <code>.anchor_at_tail()</code> manually | ||
+ | |||
+ | ==== Table ==== | ||
+ | |||
+ | Extends the <code>Grid</code> element with grid lines. | ||
+ | It is recommended to use a [[Data|data manager]] rather than using this element directly. | ||
+ | |||
+ | Almost identical to <code>Grid</code>, but with the following additional attributes: | ||
+ | ;<code>style</code> - <code>Style</code> | ||
+ | : See [[#Styling|styling]] | ||
+ | ;<code>line_size</code> - <code>float | None</code> | ||
+ | : The thickness of the grid lines, use <code>None</code> to remove the lines | ||
+ | |||
+ | == Attributes / Methods == | ||
+ | |||
+ | This section lists the attributes and methods common among several elements, check each element above for which apply. | ||
− | This | + | A few attributes are marked with a letter, they have the following meanings: |
+ | ;C - coordinate | ||
+ | : This attribute is a coordinate property, see [[#Coordinates|coordinates]] | ||
+ | ;E - event callback | ||
+ | : This attribute is an event callback, see [[#Events|events]] | ||
+ | ;R - readonly | ||
+ | : This attribute can not be updated (or animated) | ||
+ | ;S - static | ||
+ | : This attribute can not be animated, see [[#Animation|animation]] | ||
=== Common === | === Common === | ||
+ | ;<code>parent</code> - <code>Container | None</code> S | ||
+ | : The parent of the element | ||
+ | ;<code>size</code> - <code>tuple[float, float]</code> C | ||
+ | : The size (width and height) of the element | ||
+ | : Some elements calculate these values based on other attributes, in which case the size is read-only | ||
+ | ;<code>.request_size(size)</code> | ||
+ | : Ask the element to adjust its size to match the given size, taking into account min and max size and other restrictions | ||
+ | ;<code>.request_size(size, time)</code> | ||
+ | : Same as above but using an animation time, see [[#Animation|animation]] | ||
+ | ;<code>size_x</code>/<code>width</code>/<code>w</code> - <code>float</code> | ||
+ | : The width of the element, component of <code>size</code> | ||
+ | ;<code>.request_width(width)</code> | ||
+ | : Ask the element to adjust its width to match the given width, taking into account min and max width and other restrictions | ||
+ | ;<code>.request_width(width, time)</code> | ||
+ | : Same as above but using an animation time, see [[#Animation|animation]] | ||
+ | ;<code>size_y</code>/<code>height</code>/<code>h</code> - <code>float</code> | ||
+ | : The height of the element, component of <code>size</code> | ||
+ | ;<code>.request_height(height)</code> | ||
+ | : Ask the element to adjust its height to match the given height, taking into account min and max height and other restrictions | ||
+ | ;<code>.request_height(height, time)</code> | ||
+ | : Same as above but using an animation time, see [[#Animation|animation]] | ||
+ | ;<code>min_size</code> - <code>tuple[float, float]</code> C | ||
+ | : The minimum size of the element, does not apply automatically and does not prevent setting the size manually | ||
+ | ;<code>min_size_x</code>/<code>min_width</code>/<code>min_w</code> - <code>float</code> | ||
+ | : The minimum width of the element, component of <code>min_size</code> | ||
+ | ;<code>min_size_y</code>/<code>min_height</code>/<code>min_h</code> - <code>float</code> | ||
+ | : The minimum height of the element, component of <code>min_size</code> | ||
+ | ;<code>max_size</code> - <code>tuple[float, float]</code> C | ||
+ | : The maximum size of the element, does not apply automatically and does not prevent setting the size manually | ||
+ | ;<code>max_size_x</code>/<code>max_width</code>/<code>max_w</code> - <code>float</code> | ||
+ | : The maximum width of the element, component of <code>max_size</code> | ||
+ | ;<code>max_size_y</code>/<code>max_height</code>/<code>max_h</code> - <code>float</code> | ||
+ | : The maximum height of the element, component of <code>max_size</code> | ||
+ | ;<code>fixed_width</code> - <code>bool</code> | ||
+ | : If set to <code>True</code> then the width will not be changed automatically, can still be changed manually though | ||
+ | ;<code>fixed_height</code> - <code>bool</code> | ||
+ | : If set to <code>True</code> then the height will not be changed automatically, can still be changed manually though | ||
+ | ;<code>position</code>/<code>pos</code> - <code>tuple[float, float]</code> C | ||
+ | : The position of the element, relative to the <code>anchor</code> (usually center of the element) | ||
+ | ;<code>position_x</code>/<code>pos_x</code>/<code>x</code> - <code>float</code> | ||
+ | : The x-position of the element, component of <code>position</code> | ||
+ | ;<code>position_y</code>/<code>pos_y</code>/<code>y</code> - <code>float</code> | ||
+ | : The y-position of the element, component of <code>position</code> | ||
+ | ;<code>offset</code> - <code>tuple[float, float]</code> C | ||
+ | : An offset to apply to the element position, useful if the position is controlled by another element | ||
+ | ;<code>offset_x</code> - <code>float</code> | ||
+ | : The x-offset of the element, component of <code>offset</code> | ||
+ | ;<code>offset_y</code> - <code>float</code> | ||
+ | : The y-offset of the element, component of <code>offset</code> | ||
+ | ;<code>anchor</code> - <code>tuple[float, float]</code> C | ||
+ | : The anchor point of the element, <code>0</code> means center, <code>-1</code> means left/top and <code>1</code> means right/bottom. | ||
+ | ;<code>anchor_x</code> - <code>float</code> | ||
+ | : The x-anchor of the element, component of <code>anchor</code> | ||
+ | ;<code>anchor_y</code> - <code>float</code> | ||
+ | : The y-anchor of the element, component of <code>anchor</code> | ||
+ | ;<code>z_index</code>/<code>z</code> - <code>float</code> | ||
+ | : The visual sorting of the element or "distance from the screen", an element with higher z-index will be drawn above others | ||
+ | : Children will have the same z-index as their parents from the outside | ||
+ | ;<code>scale</code> - <code>tuple[float, float]</code> C | ||
+ | : Scaling factor for the element, is not considered when estimating the size or position of the element | ||
+ | ;<code>scale_x</code> - <code>float</code> | ||
+ | : The x-scale of the element, component of <code>scale</code> | ||
+ | ;<code>scale_y</code> - <code>float</code> | ||
+ | : The y-scale of the element, component of <code>scale</code> | ||
+ | ;<code>rotation</code> - <code>float</code> | ||
+ | : The rotation of the element in degrees, positive values means clockwise and negative means counter-clockwise | ||
+ | ;<code>pivot</code> - <code>tuple[float, float]</code> C | ||
+ | : The pivot point of the element, which is used as the rotation point | ||
+ | : Note: does not work properly for <code>Text</code>, <code>Image</code>, and <code>Sprite</code> | ||
+ | ;<code>pivot_x</code> - <code>float</code> | ||
+ | : The x-pivot of the element, component of <code>pivot</code> | ||
+ | ;<code>pivot_y</code> - <code>float</code> | ||
+ | : The y-pivot of the element, component of <code>pivot</code> | ||
+ | ;<code>toggle_group</code> - <code>str | None</code> | ||
+ | : The toggle group of the element, see [[#Toggling|toggling]] | ||
+ | ;<code>toggle_by_default</code> - <code>bool</code> | ||
+ | : Whether the element should start out toggled on | ||
+ | ;<code>opacity</code> - <code>float</code> | ||
+ | : The opacity of the element, <code>1</code> means fully opaque and <code>0</code> means fully transparant | ||
+ | ;<code>on_resize</code> - <code>(ResizeEventData) -> None</code> E | ||
+ | : Called after the element is given a new size | ||
=== Container === | === Container === | ||
;<code>children</code> - <code>list[BaseElement]</code> R | ;<code>children</code> - <code>list[BaseElement]</code> R | ||
− | : Elements to add as children | + | : Elements to add as children if in constructor otherwise a read-only list of current children |
+ | ;<code>.add_child(child)</code> | ||
+ | : Add a new child to the element, removing it from any previous parent | ||
+ | ;<code>.add_children(child_1, child_2, ...)</code> | ||
+ | : Add several new children to the element | ||
+ | ;<code>.remove_child(child)</code> | ||
+ | : Removes a child from the element | ||
+ | ;<code>.remove_children(child_1, child_2, ...)</code> | ||
+ | : Removes several children from the element | ||
;<code>on_add_child</code> - <code>(ChildEventData) -> None</code> E | ;<code>on_add_child</code> - <code>(ChildEventData) -> None</code> E | ||
: Called when a (public) child is added to the container | : Called when a (public) child is added to the container | ||
Line 526: | Line 716: | ||
;<code>drag_effect</code> - <code>Effect | None</code> | ;<code>drag_effect</code> - <code>Effect | None</code> | ||
: Effect to apply when the element is being dragged | : Effect to apply when the element is being dragged | ||
+ | |||
+ | === Keyboard === | ||
+ | ;<code>key_list</code> - <code>list[str]</code> S | ||
+ | : Keys this element should listen for, see [[#Keys|keys]] | ||
+ | ;<code>on_key_up</code> - <code>(KeyboardEventData) -> None</code> E | ||
+ | : Called when a key is released (if in <code>key_list</code> or it is empty) | ||
=== Scroll === | === Scroll === | ||
Line 546: | Line 742: | ||
;<code>style</code> - <code>Style</code> | ;<code>style</code> - <code>Style</code> | ||
: The style to apply to this element, see [[#Styling|Styling]] | : The style to apply to this element, see [[#Styling|Styling]] | ||
+ | |||
+ | === FitToContent === | ||
+ | ;<code>.fit_to_content()</code> | ||
+ | : Ask element to adjust its size based on the content | ||
+ | ;<code>.fit_to_content(time)</code> | ||
+ | : Same as <code>.fit_to_content()</code> but at the given animation time | ||
+ | |||
+ | == Coordinates == | ||
+ | |||
+ | The attributes marked with a <b>C</b> is a coordinate attribute. | ||
+ | This means that it has two component attributes for the x and y values. | ||
+ | You can modify either of these three attributes (or any aliases) to change (part) of the coordinate. | ||
+ | |||
+ | The coordinate property has some additional convenience features: | ||
+ | * Vector operations such as addition, subtraction, multiplication and division | ||
+ | * Conversion of scalar values to a pair | ||
+ | This menas that we can write code like this: | ||
+ | <div class="mw-collapsible-content" style="background: #F0F0F0"> | ||
+ | <nowiki>rect = Rectangle() | ||
+ | rect.size = 20 # set size to (20, 20) | ||
+ | rect.pos += (5, 10) # add (5, 10) to position | ||
+ | rect.anchor -= 1 # subtract (1, 1) from anchor | ||
+ | rect.scale *= 2 # multily scale by 2</nowiki> | ||
+ | </div> | ||
+ | |||
+ | You can also access the x and y elements of the coordinates as members, e.g. <code>rect.pivot.x</code>, | ||
+ | but you can not assign to them, so it is better to always use <code>rect.pivot_x</code>. | ||
+ | |||
+ | == Animation == | ||
+ | |||
+ | Many attributes are animated when modified, such as gradually turning transparent when setting <code>opacity</code> to <code>0</code>. | ||
+ | But it is possible to control this in more detail using the animation features of the UI library. | ||
+ | |||
+ | You can specify the values of many attributes with more precise timing using the <code>.time(time)</code> method. | ||
+ | It returns a virtual copy of the element which represents the element at that time. | ||
+ | The time should be a number from <code>0</code> to <code>1</code>. | ||
+ | |||
+ | Here is an example of creating a shaking animation: | ||
+ | <div class="mw-collapsible-content" style="background: #F0F0F0"> | ||
+ | <nowiki># setup_canvas / setup_view | ||
+ | self.box = Rectangle() | ||
+ | |||
+ | # update_canvas / update_view | ||
+ | self.box.time(0.2).rotation = 15 | ||
+ | self.box.time(0.4).rotation = -10 | ||
+ | self.box.time(0.6).rotation = 10 | ||
+ | self.box.time(0.8).rotation = -15 | ||
+ | self.box.time(1).rotation = 0</nowiki> | ||
+ | </div> | ||
+ | |||
+ | You might realize that you do not want an attribute to be animated, in which case you can use <code>.instant</code> which is the same as <code>.time(0)</code>. | ||
+ | This will ensure that the value change occurs immediately without any intermediate values. | ||
== Effects == | == Effects == | ||
+ | |||
+ | It is possible to apply effects on some attributes while certain conditions are met, such as when an element is hovered over with the mouse. | ||
+ | This is specified using the <code>Effect</code> object and effect attributes, such as <code>hover_effect</code>. | ||
+ | |||
+ | The <code>Effect</code> object has support for the following attributes: | ||
+ | *<code>color</code> | ||
+ | *<code>opacity</code> | ||
+ | *<code>rotation</code> | ||
+ | *<code>scale</code> or <code>scale_x</code>/<code>scale_y</code> | ||
+ | The specified values will be applied while the condition is met, and reverted once it is not. | ||
+ | |||
+ | Here is an example of a hover effect on a circle: | ||
+ | <div class="mw-collapsible-content" style="background: #F0F0F0"> | ||
+ | <nowiki>Circle(r=30, color="blue", hover_effect=Effect(color="orange"))</nowiki> | ||
+ | </div> | ||
+ | |||
+ | Many times you would want an effect only when an element is interactable. | ||
+ | For this we have the <code>action_effect</code> attribute. | ||
+ | |||
+ | In this example the circle will only be interactable when clickable: | ||
+ | <div class="mw-collapsible-content" style="background: #F0F0F0"> | ||
+ | <nowiki>Circle(r=30, color="blue", action_effect=Effect(color="orange"), on_click=lambda e: setattr(e.source, "color", "green"))</nowiki> | ||
+ | </div> | ||
+ | |||
+ | Effects of child elements will trigger if the effect of the parent would trigger. | ||
== Events == | == Events == | ||
+ | |||
+ | There are several events that can be listened to in order to react to element changes or user input. | ||
+ | The easiest way to do this is to use to <code>on_[event]</code> attributes. | ||
+ | These attributes takes callbacks, which are functions with a single parameter which will be an <code>EventData</code> object. | ||
+ | Look at the example for <code>Button</code>, or the last example of the previous section. | ||
+ | |||
+ | The subsections lists the additional attributes that are available for the different kinds of <code>EventData</code> objects. | ||
+ | |||
+ | === ResizeEventData === | ||
+ | ;<code>source</code> - <code>BaseElement</code> | ||
+ | : The source element of the event | ||
+ | ;<code>time</code> - <code>float | None</code> | ||
+ | : The time of the change, see [[#Animation|animation]] | ||
+ | ;<code>dimensions</code>/<code>dims</code> - <code>Dimensions</code> | ||
+ | : The dimensions affected by the change | ||
=== ChildEventData === | === ChildEventData === | ||
+ | ;<code>source</code> - <code>BaseElement</code> | ||
+ | : The source element of the event | ||
+ | ;<code>child</code> - <code>BaseElement</code> | ||
+ | : The child in question | ||
+ | |||
=== ClickEventData === | === ClickEventData === | ||
+ | ;<code>source</code> - <code>BaseElement</code> | ||
+ | : The source element of the event | ||
+ | |||
=== DragEventData === | === DragEventData === | ||
+ | ;<code>source</code> - <code>BaseElement</code> | ||
+ | : The source element of the event | ||
+ | ;<code>position</code>/<code>pos</code> - <code>tuple[float, float]</code> | ||
+ | : The drop position | ||
+ | ;<code>position_x</code>/<code>pos_x</code>/<code>x</code> - <code>float</code> | ||
+ | : The x-component of the drop position | ||
+ | ;<code>position_y</code>/<code>pos_y</code>/<code>y</code> - <code>float</code> | ||
+ | : The y-component of the drop position | ||
+ | |||
+ | === KeyboardEventData === | ||
+ | ;<code>source</code> - <code>BaseElement</code> | ||
+ | : The source element of the event | ||
+ | ;<code>key</code> - <code>str</code> | ||
+ | : The pressed key, see [[#Keys|keys]] | ||
+ | |||
=== CheckboxEventData === | === CheckboxEventData === | ||
+ | ;<code>source</code> - <code>BaseElement</code> | ||
+ | : The source element of the event | ||
+ | ;<code>checked</code> - <code>bool</code> | ||
+ | : The new <code>checked</code> value | ||
+ | ;<code>intermediate</code> - <code>bool</code> | ||
+ | : The new <code>intermediate</code> value | ||
+ | |||
+ | == Keys == | ||
+ | |||
+ | The <code>key</code> value in <code>KeyboardEventData</code> or the <code>key_list</code> attribute can either be a character matching the key (accounting for modifiers (e.g. shift or alt) and keyboard layout) or a special value corresponding to the key. | ||
+ | The following table list some convenient constants that can be used: | ||
+ | |||
+ | {| class="wikitable" style="margin:auto" | ||
+ | ! Constant !! Key | ||
+ | |- | ||
+ | | Key.UP || Up arrow | ||
+ | |- | ||
+ | | Key.DOWN || Down arrow | ||
+ | |- | ||
+ | | Key.LEFT || Left arrow | ||
+ | |- | ||
+ | | Key.RIGHT || Right arrow | ||
+ | |- | ||
+ | | Key.SPACE || Spacebar | ||
+ | |- | ||
+ | | Key.ENTER || Enter key | ||
+ | |} | ||
+ | |||
+ | You can also check keyboard values yourself using the following code snippet (need to be in interact mode): | ||
+ | <div class="mw-collapsible-content" style="background: #F0F0F0"> | ||
+ | <nowiki>Rectangle(opacity=0, parent=self.canvas, on_key_up=lambda e: print(e.key))</nowiki> | ||
+ | </div> | ||
== Toggling == | == Toggling == | ||
+ | |||
+ | This section covers the toggling system which can be used to create lightweight interactable UI. | ||
+ | It is used for tabs and popups, but can be used for other purposes as well. | ||
+ | |||
+ | Toggling can be triggered by hovering, clicking or dragging using <code>hover_targets</code>, <code>click_targets</code> and <code>drag_targets</code>. | ||
+ | When an element is added as part of these lists, it will automatically be hidden and only shown once toggled. | ||
+ | This can be avoided by setting <code>toggle_by_default</code> to <code>True</code> on the element in question. | ||
+ | |||
+ | It is possible to group together elements in a toggle group by setting <code>toggle_group</code> to the same value for all elements. | ||
+ | When elements are in a group at most one of the elements can be toggled on at a time. | ||
+ | The toggling logic is slightly modified for elements within a toggle group, particularly they will not toggled off unless another element is toggled on. | ||
+ | |||
+ | Here is an example of creating a tooltip: | ||
+ | <div class="mw-collapsible-content" style="background: #F0F0F0"> | ||
+ | <nowiki>tooltip_text = Text("My tooltip") | ||
+ | tooltip = Panel(size=tooltip_text.size + 3, y=-5, children=[tooltip_text]) | ||
+ | Circle(children=[tooltip], hover_targets=[tooltip])</nowiki> | ||
+ | </div> | ||
== Styling == | == Styling == | ||
− | + | Some elements have a <code>style</code> attribute which will be used to determine color and opacity. | |
+ | This <code>Style</code> object can be replaced with a custom style object to have different styling. |
Latest revision as of 12:22, 15 October 2024
This article goes through how to use the Freecode canvas and the UI library.
Contents
How to use the canvas
Depending on what skeleton you are using, the way you add your graphics to the canvas differs. The templates for either skeleton will include an example of using the canvas.
If you use BasicChallenge
(or no skeleton) you will want to manually add the elements to the canvas, like so:
def setup_canvas(self): self.my_rectangle = Rectangle(x=10, y=10, color="green", parent=self.canvas)
If you use StageChallenge
or GameChallenge
you will want to return the element in the setup_view
method:
def setup_view(self): self.my_rectangle = Rectangle(color="green") return self.my_rectangle
Note that you neither specify parent nor position in setup_view
, this is done for you
Overview
The UI library is object oriented, meaning that the graphical elements are represented by Python objects. You create a new element by creating a new object and you can modify the elements by modifying the objects. An element will not show up on the canvas unless the object has the canvas as a parent (or grand parent).
A child element will inherit some of the attributes from it's parent. They will be positioned relative to the parent, scaled according to the parent, and opacity of the parent is applied. A child with opacity of 0.5 and with a parent with opacity of 0.5 will in effect have an opacity of 0.25.
When creating an element object, you can (and sometimes must) include a number of attributes.
You can use any of the names listed here, e.g. width
or w
or size_x
.
The same names can be used to get or modify the attributes later on.
Here is an example of this:
my_rect = Rectangle(w=8, h=6, x=10, y=12, parent=self.canvas) my_rect.width = 4 my_rect.color = "blue"
All elements can have a parent, and some can have children.
If an element switches parent it will be removed from the previous parent's list of children.
You can either use the parent
attribute or the .add_child(child)
/.remove_child(child)
methods to update the hierarchy.
But remember that for an element to show up in the canvas it needs to have it as an ancestor.
The following section and subsections will detail the different elements available in the UI library, grouped by similarities. Many elements have common attributes, which are detailed in their own section to make things cleaner.
Elements
All these elements can be imported from the lib.ui
package, along with any of the enums and constants listed here.
As an example:
from lib.ui import Rectangle, Text my_rect = Rectangle(children=[Text("Hello")])
Remember to add the element to the import list, or you will get an error.
All elements extend either the BaseElement
or ContainerElement
base class which provides the common and container attributes and methods.
Shapes
These elements are used to make geometric shapes, either filled or outlines.
Use Polygon
to make additional shapes such as triangles and hexagons.
For more complex shapes, consider using images instead.
Rectangle
Use to make squares, rectangles and rounded rectangles.
General attributes/methods: common, container, shape, action, click, drag, keyboard
corner_radius
-float | None
S- Add rounded corners to the rectangle
Rectangle(w=10, h=5, x=10, y=10, color="green", corner_radius=1)
Circle
Use to make circles.
General attributes/methods: common, container, shape, action, click, drag, keyboard
radius
/r
-float
S- The radius of the circle, use instead of
width
/height
min_radius
/min_r
-float
- The minimum radius for this element, does not affect the current radius
max_radius
/max_r
-float
- The maximum radius for this element, does not affect the current radius
fixed_radius
-bool
- Prevents automatic resizing of the circle
Circle(r=20, color="blue", stroke=2)
Polygon
Use to make any other straight edge shapes. Consider using images if you need a large number of points.
General attributes/methods: common, container, shape, action, click, drag, keyboard
points
-list[tuple[float, float]]
R- A list of points to use to draw the polygon, required and positional
bounds
-tuple[tuple[float, float], tuple[float, float]]
S- The bounds of the polygon used to determine size and pivot, calculated if omitted
Polygon([(0, -5), (5, 5), (-5, 5)], color="red")
ComplexShape
Use to make a shape with straight or Bézier curves. Consider using images if you need very complex shapes or a large number of points.
General attributes/methods: common, container, shape, action, click, drag, keyboard
segments
-list[list[tuple[float, float]]]
R- A list of segments (list of points) to use to draw the shape, required and positional
- Each segment must consist of one to three points (first must be one point):
- Single point means a straight line to that point
- Two points is a quadratic Bézier curve with a control point (first) and an end point (second)
- Three points is a cubic Bézier curve with two control points and an end point (last)
bounds
-tuple[tuple[float, float], tuple[float, float]]
S- The bounds of the shape used to determine size and pivot, calculated if omitted
closed
-bool
S- Whether the shape should be closed or not
ComplexShape([[(0, 0)], [(5, 5), (0, 10)], [(10, 10)], [(5, 5), (15, 5), (10, 0)]], color="green")
Text
These elements can be used to display text.
Text
Simple text element. The size is based on the text string and font size.
General attributes/methods: common, action, click, drag, keyboard
text
-str
- The text to display, required and positional
color
-str
- The text color
font_size
-float
- The text font size
align_x
-"left" | "right" | "center"
- The horizontal text align
Text("Hello World!", font_size=10, color="yellow")
DynamicText
Alternative to Text
where the text is adjusted to fit within the size rather than the other way around.
General attributes/methods: common, action, click, drag, keyboard, fit to content
text
-str
- The text to display, required and positional
color
-str
- The text color
font_size
-float
- The text font size
align_x
-"left" | "right" | "center"
- The horizontal text align
align_y
-"top" | "bottom" | "center"
- The vertical text align
DynamicText("Hello World!", font_size=10, color="yellow", w=40, h=10)
HtmlArea
Use to add a block of text that can be formatted using HTML code. If the content is wider or taller than the element size, a scrollbar will appear. It is possible to include images and CSS, using normal HTML syntax.
General attributes/methods: common, scroll
html
-str
- The HTML text to display, required and positional
font_size
-float
- The text font size
align_x
-"left" | "right" | "center"
- The horizontal text align
disable_scroll
-bool
- Disables scroll and all ScrollArea features so it will limit the HtmlArea to its width and height.
disable_auto_font_scale
-bool
- Disables auto font scale and the text font size will be applied.
HtmlArea("Hello <b>World</b>!", font_size=5, w=50, h=20, disable_scroll=True, disable_auto_font_scale=True)
Graphics
These elements can be used to display images and animations.
Image
Displays a static image.
General attributes/methods: common, action, click, drag, keyboard
image
-str
S- The name of the image to show
color
-str
- A color to use for tinting the image
Image("TODO", w=30, h=30, opacity=0.75)
Sprite
Displays an animated image.
General attributes/methods: common, action, click, drag, keyboard
image
-str
S- The name of the image to show
color
-str
- A color to use for tinting the image
animation
/anim
-str
S- The name of the animation to play, use
"default"
for the default animation start_frame
/start
-int | None
S- An animation frame to start on
end_frame
/end
-int | None
S- An animation frame to end on
Sprite("TODO", w=30, h=30)
Containers
These elements can be used to fit more content in the canvas.
ScrollArea
Use when you want some content to be scrollable (vertical and/or horizontal).
General attributes/methods: common, scroll
scroll = ScrollArea(w=40, h=20) Text("Hello World!", font_size=20, parent=scroll)
TabArea
Use when you want to split up some content into tabs.
Consider putting tab content into ScrollArea
s for even more space.
General attributes/methods: common, style
tabs
-dict[str, BaseElement]
- The tab names and content to include, required and positional, constructor only
font_size
-float
- The font size to use for the tab headers
red = Rectangle(color="red", children=[Text("R", font_size=20)]) green = Rectangle(color="green", children=[Text("G", font_size=20)]) blue = Rectangle(color="blue", children=[Text("B", font_size=20)]) TabArea({"Red": red, "Green": green, "Blue": blue}, w=30, h=50)
Layouts
These elements can be used to simplify positioning of elements. They handle addition, removal and resizing of elements as well. Also, these elements cascade resizing down to any children. Other elements like Rectangle are resized if the parent is a Layout element, but a Rectangle doesn't cascade resizing to its children.
Horizontal
Use to position elements horizontally.
General attributes/methods: common, Layout
All positional arguments are added as children
proportions
-list[float]
- Proportions of size to give to each element, 0 means an even proportion of the remaining space
Horizontal(Rectangle(color="yellow"), Rectangle(color="magenta"), Rectangle(color="cyan"))
Vertical
Use to position elements vertically.
General attributes/methods: common, Layout
All positional arguments are added as children
proportions
-list[float]
- Proportions of size to give to each element, 0 means an even proportion of the remaining space
Vertical(*[Text(str(i)) for i in range(5)], spacing=5)
Grid
Use to position elements in a grid.
General attributes/methods: common, Layout
All positional arguments are added as children
rows
-int
- Number of rows in the grid, calculated if not set
columns
-int
- Number of columns in the grid, calculated if not set
transpose
-bool
- Whether to place columns first, rather than rows first
alignments
-tuple[list["left" | "right" | "center" | None], list["top" | "bottom" | "center" | None]
- Alignments for each column or row and column, None means use the
align_x/align_y
value proportions
-tuple[list[float], list[float]
- Proportions of size to give to each row and column, 0 means an even proportion of the remaining space
Grid(*[Text(str(i)) for i in range(20)], columns=5, w=30, h=30, spacing=5)
Controls
These elements are interactive UI elements mostly useful in interact mode.
Button
Use to create a button.
General attributes/methods: common, style, action, click, fit to content
text
-str
- The text on the button, required and positional
font_size
-float
- The font size of the button text
align_x
-"left" | "right" | "center"
- The horizontal text align
align_y
-"top" | "bottom" | "center"
- The vertical text align
padding
-float
- Padding around the text within the button
border_size
-float | None
- The thickness of the border around the button
corner_radius
-float | None
- The radius of the corners of the button, set to
None
for a square button overlay
-bool
- Whether to use the overlay styling for this button or not
primary
-bool
- Whether to use the primary styling for this button or not
enabled
-bool
S- If set to
False
will both disable click callbacks and use the disabled styling
def callback(event): print("Button clicked!") Button("Click me!", on_click=callback)
Checkbox
Use to create a checkbox.
General attributes/methods: common, style, action, click
checked
-bool
S- Whether the checkbox is checked or not
intermediate
-bool
S- Whether the checkbox is in an intermediate state or not
intermediate_value
-bool
- The checked value to use when the checkbox is in an intermediate state
text
-str | None
- The label next to the checkbox
font_size
-float
- The font size of the checkbox label
solid
-bool
S- Whether to use the solid icons for this checkbox or not
enabled
-bool
S- If set to
False
will both disable click callbacks and use the disabled styling on_change
-(CheckboxEventData) -> None
E- Called whenever the checkbox changes state
def callback(event): print("Checkbox was checked" if event.checked else "Checkbox was unchecked") Checkbox(scale=4, on_change=callback)
Panels
These elements can be used to visually separate a set of other elements.
Panel
A simple panel. Can have a title and a title image. Can also have content with will be resized based on the panel size.
General attributes/methods: common, style
content
-BaseElement
R- Content to but inside the panel, constructor only
title
-str
R- A title for the panel, constructor only
title_image
-str
- An image to put in the top-right corner of the panel, only visible if a title is set
font_size
-float
- The font size of the title text
corner_radius
-float | None
- The radius of the corners of the panel, set to
None
for a square panel overlay
-bool
- Whether to use the overlay styling for this panel or not
spacing
-float
- The distance between the title and content
padding
-float
- The distance between panel content/title and the outer edge
Panel(w=50, h=50, content=Circle(color="blue"), title="My Panel")
Toolbar
A penel with three distinct areas: left, right, and center. Children within each area are arranged horizontally.
General attributes/methods: common, style
corner_radius
-float | None
- The radius of the corners of the panel, set to
None
for a square panel overlay
-bool
- Whether to use the overlay styling for this panel or not
spacing
-float
- The distance between children within each area
padding
-float
- The distance between toolbar content and the outer edge
Toolbar( w=80, h=10, fixed_height=True, left_children=[Circle()], right_children=[Rectangle()], center_children=[Text("TOOLBAR")], )
Popup
A popup panel with a message and ability to add buttons. The popup needs to be activated by toggling. Clicking any of the popup buttons will close the popup. Only works properly in interact mode.
General attributes/methods: common, style
text
-str
R- The message to display, required and positional, constructor only
buttons
-list[Button]
R- The buttons to include, required and positional, constructor only
corner_radius
-float | None
- The radius of the corners of the panel, set to
None
for a square panel overlay
-bool
- Whether to use the overlay styling for this panel or not
spacing
-float
- The distance between buttons
padding
-float
- The distance between popup content and the outer edge
def callback(event): print("Deal!") buttons = [Button("OK", primary=True, on_click=callback), Button("Cancel")] popup = Popup("My Popup!", buttons, w=30, h=15, anchor_y=1, y=-5) Rectangle(size=10, hover_targets=[popup], children=[popup])
Specialized
These elements are not as generally useful as the others, but are very useful for specific tasks.
Board
Use to create a chess-like game board of square grids. If you need something more dynamic or want more features, take a look at world.
You can place elements on the board by coordinates, e.g. board[0, 2] = Circle(color="red")
.
The elements will automatically be positioned and resized to match the specified square.
There can only be one element at each coordinate, which can be fetch like so: board[0, 2]
.
General attributes/methods: common, style
rows
-int
R- How many rows the board should have
columns
-int
R- How many columns the board should have
line_size
-float
- The thickness of the grid lines
edge_size
-float
- The thickness of the edge outside the grid
font_size
-float
- The font size of the square coordinate labels
row_labels
-list[str]
R- The labels to use for the rows, you can use the constants
LOWERCASE_LABELS
,UPPERCASE_LABELS
, andNUMBER_LABELS
column_labels
-list[str]
R- The labels to use for the columns, you can use the constants
LOWERCASE_LABELS
,UPPERCASE_LABELS
, andNUMBER_LABELS
invert_rows
-bool
R- Will draw the rows bottom to top rather than top to bottom
invert_columns
-bool
R- Will draw the columns right to left rather than left to right
corner_radius
-float | None
- The radius of the corners of the board, set to
None
for a square panel overlay
-bool
- Whether to use the overlay styling for this board or not
def callback(event): event.source.color = "orange" board = Board(size=80) for r in range(board.rows): for c in range(board.columns): board[r, c] = Circle(scale=0.9, color="green", on_click=callback)
Stage
This element is primarily used by the StageChallenge
and GameChallenge
skeletons.
It is recommended to use those rather than using this element directly.
General attributes/methods: common, style
content
-BaseElement
R- The main content to put in the middle of the stage, required and positional, constructor only
info_panel
-BaseElement | None
R- Optional content to put on the left-hand side, constructor only
tabs
-dict[str, BaseElement]
R- Tabs to show on the right-hand side, constructor only
show_toolbar
-bool
R- Whether to show the toolbar or not, constructor only
center_buttons
-list[Button]
R- Buttons to put in the center of the toolbar, constructor only
right_buttons
-list[Button]
R- Buttons to put to the right of the toolbar, constructor only
info_prompt
-str
- Text to show in the toolbar on the lower left
spacing
-float
- Distance between the areas of the stage
toolbar_height
-float
- The height of the toolbar
SpeechBubble
Use to create a speech bubble. Mainly used by the .say(...)
command for character actors in world.
General attributes/methods: common, fit to content
text
-str
S- The text within the speech bubble, required and positional
font_size
-float
S- The desired text font size
settings
-SpeechBubbleSettings
S- Specifies the shape of the speech bubble:
radius
- The radius of the speech-bubble "corners"tail_inset
- How far in the tail should be positioned (x-offset)tail_width
- How thick the tail should betail_height
- How tall the tail should betail_point_offset
- How the tail tip should be positioned (x-offset)tail_position
- Where to put the tail, one of "bottom_left", "bottom_right", "top_left", or "top_right"shadow_height
- How high up the lower shading of the bubble should goedge_size
- How thick the edge around the bubble should be
theme
-SpeechBubbleTheme
- Specifies the color scheme of the speech bubble:
text_color
- The color of the textbubble_color
- The background color of the bubbleshadow_color
- The shading color of the bubbleedge_color
- The color of the bubble edge
auto_fit
-bool
- Whether to automatically resize the bubble to fit the text or not, can use
.fit_to_content()
manually) auto_anchor
-bool
- Whether to automatically anchor the element position to the tail tip or not, can use
.anchor_at_tail()
manually
Table
Extends the Grid
element with grid lines.
It is recommended to use a data manager rather than using this element directly.
Almost identical to Grid
, but with the following additional attributes:
style
-Style
- See styling
line_size
-float | None
- The thickness of the grid lines, use
None
to remove the lines
Attributes / Methods
This section lists the attributes and methods common among several elements, check each element above for which apply.
A few attributes are marked with a letter, they have the following meanings:
- C - coordinate
- This attribute is a coordinate property, see coordinates
- E - event callback
- This attribute is an event callback, see events
- R - readonly
- This attribute can not be updated (or animated)
- S - static
- This attribute can not be animated, see animation
Common
parent
-Container | None
S- The parent of the element
size
-tuple[float, float]
C- The size (width and height) of the element
- Some elements calculate these values based on other attributes, in which case the size is read-only
.request_size(size)
- Ask the element to adjust its size to match the given size, taking into account min and max size and other restrictions
.request_size(size, time)
- Same as above but using an animation time, see animation
size_x
/width
/w
-float
- The width of the element, component of
size
.request_width(width)
- Ask the element to adjust its width to match the given width, taking into account min and max width and other restrictions
.request_width(width, time)
- Same as above but using an animation time, see animation
size_y
/height
/h
-float
- The height of the element, component of
size
.request_height(height)
- Ask the element to adjust its height to match the given height, taking into account min and max height and other restrictions
.request_height(height, time)
- Same as above but using an animation time, see animation
min_size
-tuple[float, float]
C- The minimum size of the element, does not apply automatically and does not prevent setting the size manually
min_size_x
/min_width
/min_w
-float
- The minimum width of the element, component of
min_size
min_size_y
/min_height
/min_h
-float
- The minimum height of the element, component of
min_size
max_size
-tuple[float, float]
C- The maximum size of the element, does not apply automatically and does not prevent setting the size manually
max_size_x
/max_width
/max_w
-float
- The maximum width of the element, component of
max_size
max_size_y
/max_height
/max_h
-float
- The maximum height of the element, component of
max_size
fixed_width
-bool
- If set to
True
then the width will not be changed automatically, can still be changed manually though fixed_height
-bool
- If set to
True
then the height will not be changed automatically, can still be changed manually though position
/pos
-tuple[float, float]
C- The position of the element, relative to the
anchor
(usually center of the element) position_x
/pos_x
/x
-float
- The x-position of the element, component of
position
position_y
/pos_y
/y
-float
- The y-position of the element, component of
position
offset
-tuple[float, float]
C- An offset to apply to the element position, useful if the position is controlled by another element
offset_x
-float
- The x-offset of the element, component of
offset
offset_y
-float
- The y-offset of the element, component of
offset
anchor
-tuple[float, float]
C- The anchor point of the element,
0
means center,-1
means left/top and1
means right/bottom. anchor_x
-float
- The x-anchor of the element, component of
anchor
anchor_y
-float
- The y-anchor of the element, component of
anchor
z_index
/z
-float
- The visual sorting of the element or "distance from the screen", an element with higher z-index will be drawn above others
- Children will have the same z-index as their parents from the outside
scale
-tuple[float, float]
C- Scaling factor for the element, is not considered when estimating the size or position of the element
scale_x
-float
- The x-scale of the element, component of
scale
scale_y
-float
- The y-scale of the element, component of
scale
rotation
-float
- The rotation of the element in degrees, positive values means clockwise and negative means counter-clockwise
pivot
-tuple[float, float]
C- The pivot point of the element, which is used as the rotation point
- Note: does not work properly for
Text
,Image
, andSprite
pivot_x
-float
- The x-pivot of the element, component of
pivot
pivot_y
-float
- The y-pivot of the element, component of
pivot
toggle_group
-str | None
- The toggle group of the element, see toggling
toggle_by_default
-bool
- Whether the element should start out toggled on
opacity
-float
- The opacity of the element,
1
means fully opaque and0
means fully transparant on_resize
-(ResizeEventData) -> None
E- Called after the element is given a new size
Container
children
-list[BaseElement]
R- Elements to add as children if in constructor otherwise a read-only list of current children
.add_child(child)
- Add a new child to the element, removing it from any previous parent
.add_children(child_1, child_2, ...)
- Add several new children to the element
.remove_child(child)
- Removes a child from the element
.remove_children(child_1, child_2, ...)
- Removes several children from the element
on_add_child
-(ChildEventData) -> None
E- Called when a (public) child is added to the container
on_remove_child
-(ChildEventData) -> None
E- Called when a (public) child is removed from the container
Shape
color
-str
- The fill or stroke color of the shape
stroke
-float | None
S- Draw the edge of the shape rather than the area
Action
action_effect
-Effect | None
- Effect to apply when hovering the element and it is interactable
hover_effect
-Effect | None
- Effect to apply when hovering the element
hover_targets
-list[BaseElement]
- Elements that will be toggled while this element is hovered
Click
on_click
-(ClickEventData) -> None
E- Called when this element is clicked in interact mode
click_targets
-list[BaseElement]
- Elements that will be toggled when this element is clicked
interact_click_targets
-list[BaseElement]
- Same as
click_targets
but only works in interact mode
Drag
draggable
-bool | None
S- Whether the element should be draggable, set to
None
for default behaviour on_drop
-(DragEventData) -> None
E- Called when this element is dropped after being dragged
drag_targets
-list[BaseElement]
- Elements that will be toggled while this element is dragged
drag_effect
-Effect | None
- Effect to apply when the element is being dragged
Keyboard
key_list
-list[str]
S- Keys this element should listen for, see keys
on_key_up
-(KeyboardEventData) -> None
E- Called when a key is released (if in
key_list
or it is empty)
Scroll
widget_color
-str
- The color of the scroll bars
widget_size
-float
S- The size of the scroll bars
follow_bottom
-bool
- If set to
True
then the area will continue scrolling automatically if at the bottom
Layout
spacing
-float
- Distance between elements
align_x
-"left" | "right" | "center"
- The horizontal element align
align_y
-"top" | "bottom" | "center"
- The vertical element align
Style
style
-Style
- The style to apply to this element, see Styling
FitToContent
.fit_to_content()
- Ask element to adjust its size based on the content
.fit_to_content(time)
- Same as
.fit_to_content()
but at the given animation time
Coordinates
The attributes marked with a C is a coordinate attribute. This means that it has two component attributes for the x and y values. You can modify either of these three attributes (or any aliases) to change (part) of the coordinate.
The coordinate property has some additional convenience features:
- Vector operations such as addition, subtraction, multiplication and division
- Conversion of scalar values to a pair
This menas that we can write code like this:
rect = Rectangle() rect.size = 20 # set size to (20, 20) rect.pos += (5, 10) # add (5, 10) to position rect.anchor -= 1 # subtract (1, 1) from anchor rect.scale *= 2 # multily scale by 2
You can also access the x and y elements of the coordinates as members, e.g. rect.pivot.x
,
but you can not assign to them, so it is better to always use rect.pivot_x
.
Animation
Many attributes are animated when modified, such as gradually turning transparent when setting opacity
to 0
.
But it is possible to control this in more detail using the animation features of the UI library.
You can specify the values of many attributes with more precise timing using the .time(time)
method.
It returns a virtual copy of the element which represents the element at that time.
The time should be a number from 0
to 1
.
Here is an example of creating a shaking animation:
# setup_canvas / setup_view self.box = Rectangle() # update_canvas / update_view self.box.time(0.2).rotation = 15 self.box.time(0.4).rotation = -10 self.box.time(0.6).rotation = 10 self.box.time(0.8).rotation = -15 self.box.time(1).rotation = 0
You might realize that you do not want an attribute to be animated, in which case you can use .instant
which is the same as .time(0)
.
This will ensure that the value change occurs immediately without any intermediate values.
Effects
It is possible to apply effects on some attributes while certain conditions are met, such as when an element is hovered over with the mouse.
This is specified using the Effect
object and effect attributes, such as hover_effect
.
The Effect
object has support for the following attributes:
color
opacity
rotation
scale
orscale_x
/scale_y
The specified values will be applied while the condition is met, and reverted once it is not.
Here is an example of a hover effect on a circle:
Circle(r=30, color="blue", hover_effect=Effect(color="orange"))
Many times you would want an effect only when an element is interactable.
For this we have the action_effect
attribute.
In this example the circle will only be interactable when clickable:
Circle(r=30, color="blue", action_effect=Effect(color="orange"), on_click=lambda e: setattr(e.source, "color", "green"))
Effects of child elements will trigger if the effect of the parent would trigger.
Events
There are several events that can be listened to in order to react to element changes or user input.
The easiest way to do this is to use to on_[event]
attributes.
These attributes takes callbacks, which are functions with a single parameter which will be an EventData
object.
Look at the example for Button
, or the last example of the previous section.
The subsections lists the additional attributes that are available for the different kinds of EventData
objects.
ResizeEventData
source
-BaseElement
- The source element of the event
time
-float | None
- The time of the change, see animation
dimensions
/dims
-Dimensions
- The dimensions affected by the change
ChildEventData
source
-BaseElement
- The source element of the event
child
-BaseElement
- The child in question
ClickEventData
source
-BaseElement
- The source element of the event
DragEventData
source
-BaseElement
- The source element of the event
position
/pos
-tuple[float, float]
- The drop position
position_x
/pos_x
/x
-float
- The x-component of the drop position
position_y
/pos_y
/y
-float
- The y-component of the drop position
KeyboardEventData
source
-BaseElement
- The source element of the event
key
-str
- The pressed key, see keys
CheckboxEventData
source
-BaseElement
- The source element of the event
checked
-bool
- The new
checked
value intermediate
-bool
- The new
intermediate
value
Keys
The key
value in KeyboardEventData
or the key_list
attribute can either be a character matching the key (accounting for modifiers (e.g. shift or alt) and keyboard layout) or a special value corresponding to the key.
The following table list some convenient constants that can be used:
Constant | Key |
---|---|
Key.UP | Up arrow |
Key.DOWN | Down arrow |
Key.LEFT | Left arrow |
Key.RIGHT | Right arrow |
Key.SPACE | Spacebar |
Key.ENTER | Enter key |
You can also check keyboard values yourself using the following code snippet (need to be in interact mode):
Rectangle(opacity=0, parent=self.canvas, on_key_up=lambda e: print(e.key))
Toggling
This section covers the toggling system which can be used to create lightweight interactable UI. It is used for tabs and popups, but can be used for other purposes as well.
Toggling can be triggered by hovering, clicking or dragging using hover_targets
, click_targets
and drag_targets
.
When an element is added as part of these lists, it will automatically be hidden and only shown once toggled.
This can be avoided by setting toggle_by_default
to True
on the element in question.
It is possible to group together elements in a toggle group by setting toggle_group
to the same value for all elements.
When elements are in a group at most one of the elements can be toggled on at a time.
The toggling logic is slightly modified for elements within a toggle group, particularly they will not toggled off unless another element is toggled on.
Here is an example of creating a tooltip:
tooltip_text = Text("My tooltip") tooltip = Panel(size=tooltip_text.size + 3, y=-5, children=[tooltip_text]) Circle(children=[tooltip], hover_targets=[tooltip])
Styling
Some elements have a style
attribute which will be used to determine color and opacity.
This Style
object can be replaced with a custom style object to have different styling.