1
0
Fork 0
mirror of https://git.lynn.is/Gwen/python-layout.git synced 2024-01-13 01:31:55 +01:00
python-layout/readme.md
2023-02-04 15:40:41 +01:00

509 lines
15 KiB
Markdown

# 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