# Example ```python from layout import Document, Flex, Text, TextAlign, TextVerticalAlign, FlexAlignContent, FlexDirection, FlexAlignItems, FlexWrap doc = Document( width=800, height=400, bg_color=(206, 249, 242, 255), content=Flex( direction=FlexDirection.ROW, wrap=FlexWrap.WRAP, align_items=FlexAlignItems.STRETCH, align_content=FlexAlignContent.STRETCH, gap=20, padding=20, contents=[ Text( text="ITEM 1", bg_color=(4, 231, 98, 128), width=100, flex_grow=1, flex_shrink=1, text_align=TextAlign.CENTER, vertical_text_align=TextVerticalAlign.MIDDLE ), Text( text="ITEM 2", bg_color=(34, 49, 39, 128), width=300, flex_grow=1, flex_shrink=1, text_align=TextAlign.CENTER, vertical_text_align=TextVerticalAlign.MIDDLE ), Text( text="ITEM 3", bg_color=(220, 0, 115, 128), width=200, flex_grow=1, flex_shrink=1, text_align=TextAlign.CENTER, vertical_text_align=TextVerticalAlign.MIDDLE ), Text( text="ITEM 4", bg_color=(0, 139, 248, 128), width=400, flex_grow=1, flex_shrink=1, text_align=TextAlign.CENTER, vertical_text_align=TextVerticalAlign.MIDDLE ), Text( text="ITEM 5", bg_color=(71, 0, 99, 128), width=250, flex_grow=1, flex_shrink=1, text_align=TextAlign.CENTER, vertical_text_align=TextVerticalAlign.MIDDLE ), ] ) ) image = doc.get_image() image.show() ``` # Layouts ## Layout Base layout class, do not use directly. Provides the following properties: ```python from layout import Layout Layout( width=None, # width of the layout element height=None, # height of the layout element min_width=None, # minimum width of the layout element min_height=None, # minimum height of the layout element max_width=None, # maximum width of the layout element max_height=None, # maximum height of the layout element fg_color=None, # foreground color (inherited) bg_color=None, # background color (inherited) border_color=None, # border color (see section Borders) border_width=0, # border width (see section Borders) border_radius=0, # border radius (see section Borders) padding=0, # padding of the layout element font=None, # font for texts (inherited) overflow=None, # allow overflow of layout content left=None, # left absolute position (in children of Container layout) top=None, # top absolute position (in children of Container layout) right=None, # right absolute position (in children of Container layout) bottom=None, # bottom absolute position (in children of Container layout) flex_grow=0, # flex grow proportion (in children of Flex layout) flex_shrink=0, # flex grow proportion (in children of Flex layout) ) ``` ### Borders Borders are painted over the background but below potentially overflowing content. Every border property can be a single value or a tuple (except color) or list of up to four values. Multiple values for border width and color are given in the order (`left`, `top`, `right`, `bottom`). Multiple values for border radius are given in the order (`top-left`, `top-right`, `bottom-right`, `bottom-left`). The border color property can only be given as a single value or list of values, not as a tuple, since colors are defined as RGBA-tuples and a tuple value is interpreted as a single color. ## Container Simple layout container with absolute and automatic positioning. Children with any of their `left`/`top`/`right`/`bottom` properties set to something other than `None` are positioned absolutely. Other children are positioned automatically. ```python from layout import Container Container( contents=[], # child layouts ) ``` ## Flex Flexible layout container roughly based on the CSS flex specification. Children of this layout can use the `flex_grow` and `flex_shrink` properties. ```python from layout import Flex, FlexDirection, FlexWrap, FlexJustify, FlexAlignItems, FlexAlignContent Flex( contents=[], # child layouts direction=FlexDirection.ROW, wrap=FlexWrap.NO_WRAP, justify=FlexJustify.START, align_items=FlexAlignItems.START, align_content=FlexAlignContent.START, gap=0, # gap between flex items ) ``` The properties `direction`, `wrap`, `justify`, `align_items`, `align_content` and `gap` work roughly like their CSS counterparts. Flex layout arranges items into one or multiple lines. A line is a row in `ROW`/`ROW_REVERSE` and a column in `COLUMN`/`COLUMN_REVERSE` direction. The "main axis" is the axis in which direction the items are arranged, i.e. the x-axis for rows and the y-axis for columns. The "cross axis" is the other axis. ### FlexDirection Specifies the direction in which child layouts (items) are arranged in the layout. Other flex properties with values like `START` and `END` depend on the direction. #### FlexDirection.ROW Items are arranged in rows. #### FlexDirection.ROW_REVERSE Items are arranged in rows, in reverse order. The item that is first in the `contents` list is at the end and vice versa. Items are still *rendered* in the same order as they appear in the `contents` list, so overlapping items will be rendered on top of each other in that order. #### FlexDirection.COLUMN Items are arranged in columns. #### FlexDirection.COLUMN_REVERSE Like `ROW_REVERSE`, but with columns. ### FlexWrap Specifies whether and how flex items can wrap into multiple lines (rows/columns). #### FlexWrap.NO_WRAP Items can not wrap, all items are displayed in one line. #### FlexWrap.WRAP Items can wrap into multiple lines if they do not fit into the available space. #### FlexWrap.WRAP_REVERSE like `WRAP`, but lines are arranged in reverse order. ### FlexJustify This property corresponds to `justify-content` in CSS flex layouts. It determines how items within a line are arranged on the main axis if there is space left over along the main axis after growing/shrinking items. #### FlexJustify.START The available space is at the end of the line, the items at the beginning. #### FlexJustify.END The available space is at the beginning of the line, the items at the end. #### FlexJustify.CENTER The available space is equally distributed at the beginning and end of the line, the items are in the center. #### FlexJustify.SPACE_BETWEEN The available space is equally distributed between the items, the first and last item are at the beginning and end of the line. #### FlexJustify.SPACE_AROUND The available space is equally distributed to the items, and for each item equally distributed before and after the item. There is twice as much space between two items as there is before the first and after the last item. #### FlexJustify.SPACE_EVENLY The available space is equally distributed before, after and between the items. ### FlexAlignItems Specifies how items within a line are arranged on the cross axis if they don't fill the entire cross size of the line. #### FlexAlignItems.START Items are arranged at the start of the line, i.e. at the top for rows and at the left for columns. #### FlexAlignItems.END Items are arranged at the end of the line, i.e. at the bottom for rows and at the right for columns. #### FlexAlignItems.CENTER Items are arranged at the center of the line. #### FlexAlignItems.STRETCH Items are stretched out to fill the line. ### FlexAlignContent Specifies how multiple lines are arranged on the cross axis within the layout when they don't fill the cross size of the layout. This is only relevant for layouts with multiple lines, a single line is always stretched to fill the layout (the items within such a line can be controlled with `FlexAlignItems`). #### FlexAlignContent.START The lines are at the beginning of the layout, i.e. at the top for rows and at the left for columns. #### FlexAlignContent.END The lines are at the end of the layout, i.e. at the bottom for rows and at the right for columns. #### FlexAlignContent.CENTER The lines are at the center of the layout. #### FlexAlignContent.STRETCH The lines are stretched to fill the available space. The available space is distributed equally between the lines. #### FlexAlignContent.SPACE_BETWEEN The available space is distributed equally between the lines but not around them. #### FlexAlignContent.SPACE_AROUND The available space is distributed equally to the lines, and for each line distributed equally before and after that line. The space between two lines is twice as much as the space before the first and after the last line. #### FlexAlignContent.SPACE_EVENLY The available space is distributed equally before, between and after the lines. ## Box This layout can render a title over its own top border. ```python from layout import Box, BoxTitleAnchor Box( title=None, title_font=None, title_color=None, title_anchor=BoxTitleAnchor.LEFT, # anchor for positioning title_position=0, # x position of the title relative to the anchor title_padding=0, # additional space to remove from the border on the left and right of the text content=None, ) ``` ### BoxTitleAnchor Where to anchor the title along the top border. The top left and top right border radii are subtracted from the available space. #### BoxTitleAnchor.LEFT The title is anchored at the left edge of the border, plus the top left border radius. #### BoxTitleAnchor.CENTER The title is anchored in the middle of the border. #### BoxTitleAnchor.RIGHT The title is anchored at the right edge of the border, minus the top right border radius. ## Text This layout can render text. The layout algorithm is somewhat inefficient and arranging large amounts of texts can take a while. The line-breaking algorithm is very simplistic. Whitespace at the beginning (if left-aligned), end (if right-aligned) or begining and end (if center-aligned) is not rendered. ```python from layout import Text, TextAlign, TextVerticalAlign, TextWrap Text( text=None, # can be provided as a single string or as a list of lines, if a list then lines must not contain line breaks text_align=TextAlign.LEFT, vertical_text_align=TextVerticalAlign.TOP, text_wrap=TextWrap.NO_WRAP, line_spacing=0 # spacing between the end of one line and the beginning of the next ) ``` ### TextAlign How each line is aligned within the available horizontal space. #### TextAlign.LEFT #### TextAlign.CENTER #### TextAlign.RIGHT ### TextVerticalAlign How all the lines together are aligned within the available vertical space. #### TextVerticalAlign.TOP #### TextVerticalAlign.MIDDLE #### TextVerticalAlign.BOTTOM ### TextWrap #### TextWrap.NO_WRAP Text is not automatically wrapped to fit into the available horizontal space, but explicit line breaks are respected. #### TextWrap.ONLY_WORDS Text is wrapped on word boundaries. Words that are too long to fit into a single line overflow. #### TextWrap.PREFER_WORDS Text is wrapped on word boundaries, and words that are too long to fit into a single line are wrapped as well. #### TextWrap.EVERYWHERE Lines are filled up as much as possible and text is wrapped wherever necessary. ## Image ```python from layout import Image, ImageMode, ImageAnchor Image( image=None, mode=ImageMode.ORIGINAL, scale=1, # can be a number or a tuple of x- and y-scale position=ImageAnchor.TOP_LEFT, # anchor for positioning offset_x=0, # horizontal position of the image relative to the anchor offset_y=0, # vertical position of the image relative to the anchor ) ``` ### ImageMode How the image is displayed. This also affects how much space this layout tries to take up: With `ORIGINAL` mode both width and height correspond to the (scaled) width and height of the image. With `STRETCH_X` and `REPEAT_X` mode the height corresponds to the (scaled) height of the image, but the width is 0 unless forced otherwise. With `STRETCH_Y` and `REPEAT_Y` mode the width corresponds to the (scaled) width of the image, but the height is 0 unless forced otherwise. With all other modes the width and height are 0 unless forced otherwise. All modes except `STRETCH`, `CONTAIN` and `COVER` respect the `scale` property in some way. #### ImageMode.ORIGINAL The image is rendered at its original size, optionally scaled by the `scale` property. #### ImageMode.STRETCH The image is stretched to fill the available space. #### ImageMode.STRETCH_X The image is stretched in the x-axis to fill the available space and unmodified in the y-axis. #### ImageMode.STRETCH_Y The image is stretched in the y-axis to fill the available space and unmodified in the x-axis. #### ImageMode.CONTAIN The image is scaled proportionally to fill the available space as much as possible without being cut off. The image can still be cut off in places by positioning it or by rounded corners of the container. This can make the image smaller if the available space is smaller than the original image size. #### ImageMode.COVER The image is scaled proportionally to fill the available space completely. This can make the image smaller if the available space is smaller than the original image size. #### ImageMode.REPEAT The image is repeated on both axes to fill the available space. #### ImageMode.REPEAT_X The image is repeated on the x-axis to fill the available space. #### ImageMode.REPEAT_Y The image is repeated on the y-axis to fill the available space. #### ImageMode.REPEAT_X_STRETCH The image is repeated on the x-axis and stretched on the y-axis to fill the available space. #### ImageMode.REPEAT_Y_STRETCH The image is repeated on the y-axis and stretched on the x-axis to fill the available space. #### ImageMode.REPEAT_X_FILL The image is scaled like with `CONTAIN` on the y-axis and then repeated along the x-axis to fill the remaining space. #### ImageMode.REPEAT_Y_FILL The image is scaled like with `CONTAIN` on the x-axis and then repeated along the y-axis to fill the remaining space. ### ImageAnchor Where the image is anchored for positioning with `offset_x` and `offset_y`. #### ImageAnchor.TOP_LEFT #### ImageAnchor.TOP_CENTER #### ImageAnchor.TOP_RIGHT #### ImageAnchor.MIDDLE_LEFT #### ImageAnchor.MIDDLE_CENTER #### ImageAnchor.MIDDLE_RIGHT #### ImageAnchor.BOTTOM_LEFT #### ImageAnchor.BOTTOM_CENTER #### ImageAnchor.BOTTOM_RIGHT # custom layouts A layout should extend the `Layout` class and implement the following methods: # possible future features ## border modes option to render borders as outlines instead (i.e. not taking up layout space), with the following options: - `NORMAL`: border takes up layout space - `OUTLINE_INSIDE`: border is an overlay that takes up no space, inside of the layout rect - `OUTLINE_OUTSIDE`: border is an overlay that takes up no space, outside of the layout rect (only visible with overflow=true) - `OUTLINE_CENTERED`: border is an overlay that takes up no space, centered on the layout rect (only completely visible with overflow=true) ## border styles border styles like dotted, dashed, inset etc like in CSS