mirror of
https://github.com/danbulant/cushy
synced 2026-06-24 17:12:11 +00:00
Work on guide
This commit is contained in:
parent
bb28f96b58
commit
8fb372e743
17 changed files with 366 additions and 133 deletions
33
.github/workflows/docs.yml
vendored
33
.github/workflows/docs.yml
vendored
|
|
@ -5,7 +5,6 @@ on: [push]
|
|||
jobs:
|
||||
docs:
|
||||
runs-on: ubuntu-latest
|
||||
if: github.ref == 'refs/heads/main'
|
||||
steps:
|
||||
- uses: actions/checkout@v3
|
||||
|
||||
|
|
@ -32,4 +31,34 @@ jobs:
|
|||
api-key: ${{ secrets.DOSSIER_API_KEY }}
|
||||
project: cushy
|
||||
from: target/doc/
|
||||
to: /${{ github.ref_name }}/docs
|
||||
to: /${{ github.ref_name }}/docs
|
||||
|
||||
guide:
|
||||
runs-on: ubuntu-latest
|
||||
steps:
|
||||
- uses: actions/checkout@v3
|
||||
|
||||
- uses: dtolnay/rust-toolchain@stable
|
||||
|
||||
- name: Download mdbook
|
||||
run: |
|
||||
curl -sSL https://github.com/rust-lang/mdBook/releases/download/v0.4.36/mdbook-v0.4.36-x86_64-unknown-linux-gnu.tar.gz | tar -xz
|
||||
|
||||
- name: Install mdbook-variables
|
||||
run: |
|
||||
cargo install mdbook-variables
|
||||
|
||||
- name: Build Guide
|
||||
run: |
|
||||
./mdbook build guide
|
||||
|
||||
- name: Deploy
|
||||
uses: khonsulabs/sync-to-dossier@main
|
||||
if: github.ref == 'refs/heads/main' || github.ref == 'refs/heads/release' || startsWith(github.ref, 'refs/tags/')
|
||||
with:
|
||||
url: ${{ secrets.DOSSIER_URL }}
|
||||
api-key-id: ${{ secrets.DOSSIER_API_KEY_ID }}
|
||||
api-key: ${{ secrets.DOSSIER_API_KEY }}
|
||||
project: cushy
|
||||
from: target/guide/
|
||||
to: /${{ github.ref_name }}/guide
|
||||
|
|
@ -4,3 +4,10 @@ language = "en"
|
|||
multilingual = false
|
||||
src = "src"
|
||||
title = "Cushy User's Guide"
|
||||
|
||||
[build]
|
||||
build-dir = "../target/guide"
|
||||
extra-watch-dirs = ["./guide-examples/"]
|
||||
|
||||
[preprocessor.variables.variables]
|
||||
docs = "https://cushy.rs/main/docs/cushy"
|
||||
|
|
|
|||
|
|
@ -1,133 +1,167 @@
|
|||
use std::array;
|
||||
|
||||
use cushy::figures::units::{Lp, Px};
|
||||
use cushy::figures::{Point, Size};
|
||||
use cushy::styles::{Edges, ThemePair};
|
||||
use cushy::styles::ThemePair;
|
||||
use cushy::widget::MakeWidget;
|
||||
use cushy::widgets::Space;
|
||||
use guide_examples::BookExample;
|
||||
use cushy::widgets::grid::{GridDimension, GridWidgets};
|
||||
use cushy::widgets::{Grid, Space};
|
||||
use guide_examples::book_example;
|
||||
|
||||
// ANCHOR: content
|
||||
fn content() -> impl MakeWidget {
|
||||
Space::primary().size(Size::squared(Px::new(32)))
|
||||
Space::primary().size(Size::squared(Px::new(32)..))
|
||||
}
|
||||
// ANCHOR_END: content
|
||||
|
||||
fn align_left() -> impl MakeWidget {
|
||||
// ANCHOR: align-left
|
||||
content().align_left()
|
||||
// ANCHOR_END: align-left
|
||||
}
|
||||
|
||||
fn centered() -> impl MakeWidget {
|
||||
// ANCHOR: horizontal-center
|
||||
content().centered()
|
||||
// ANCHOR_END: horizontal-center
|
||||
}
|
||||
|
||||
fn align_right() -> impl MakeWidget {
|
||||
// ANCHOR: align-right
|
||||
content().align_right()
|
||||
// ANCHOR_END: align-right
|
||||
}
|
||||
|
||||
fn align_horizontal() -> impl MakeWidget {
|
||||
Grid::from_rows(
|
||||
GridWidgets::new()
|
||||
.and(("Unaligned", content()))
|
||||
.and(("align_left()", align_left()))
|
||||
.and(("centered()", centered()))
|
||||
.and(("align_right()", align_right())),
|
||||
)
|
||||
.dimensions([
|
||||
GridDimension::FitContent,
|
||||
GridDimension::Fractional { weight: 1 },
|
||||
])
|
||||
}
|
||||
|
||||
fn align_top() -> impl MakeWidget {
|
||||
// ANCHOR: align-top
|
||||
content().align_top()
|
||||
// ANCHOR_END: align-top
|
||||
}
|
||||
|
||||
fn align_bottom() -> impl MakeWidget {
|
||||
// ANCHOR: align-bottom
|
||||
content().align_bottom()
|
||||
// ANCHOR_END: align-bottom
|
||||
}
|
||||
|
||||
fn align_vertical() -> impl MakeWidget {
|
||||
Grid::from_rows(
|
||||
GridWidgets::new()
|
||||
.and(("Unaligned", "align_top()", "centered()", "align_bottom()"))
|
||||
.and((
|
||||
content().height(Lp::inches(1)).centered(),
|
||||
align_top(),
|
||||
centered(),
|
||||
align_bottom(),
|
||||
)),
|
||||
)
|
||||
.dimensions(array::from_fn(|_| GridDimension::Fractional { weight: 1 }))
|
||||
}
|
||||
|
||||
fn align() -> impl MakeWidget {
|
||||
"Horizontal Alignment"
|
||||
.and(align_horizontal().contain())
|
||||
.and("Vertical Alignment")
|
||||
.and(align_vertical().contain())
|
||||
.into_rows()
|
||||
}
|
||||
|
||||
fn main() {
|
||||
BookExample::new(
|
||||
"align-horizontal",
|
||||
"Default Behavior"
|
||||
.and(content())
|
||||
.and("align_left()")
|
||||
.and({
|
||||
// ANCHOR: align-left
|
||||
content().align_left()
|
||||
// ANCHOR_END: align-left
|
||||
})
|
||||
.and("pad_by().align_left()")
|
||||
.and({
|
||||
// ANCHOR: align-left-pad
|
||||
content()
|
||||
.pad_by(Edges::default().with_left(Lp::inches(1)))
|
||||
.align_left()
|
||||
// ANCHOR_END: align-left-pad
|
||||
})
|
||||
.and("centered()")
|
||||
.and({
|
||||
// ANCHOR: centered
|
||||
content().centered()
|
||||
// ANCHOR_END: centered
|
||||
})
|
||||
.and("pad_by().align_right()")
|
||||
.and({
|
||||
// ANCHOR: align-right-pad
|
||||
content()
|
||||
.pad_by(Edges::default().with_right(Lp::inches(1)))
|
||||
.align_right()
|
||||
// ANCHOR_END: align-right-pad
|
||||
})
|
||||
.and("align_right()")
|
||||
.and({
|
||||
// ANCHOR: align-right
|
||||
content().align_right()
|
||||
// ANCHOR_END: align-right
|
||||
})
|
||||
.into_rows(),
|
||||
)
|
||||
.still_frame(|recorder| {
|
||||
const LEFT: u32 = 40;
|
||||
const PADDING: u32 = 96;
|
||||
const RIGHT: u32 = 710;
|
||||
const CENTER: u32 = 375;
|
||||
let theme = ThemePair::default();
|
||||
let container_color = theme.dark.surface.low_container;
|
||||
let primary = theme.dark.primary.color;
|
||||
book_example!(align).still_frame(|recorder| {
|
||||
const LEFT: u32 = 145;
|
||||
const RIGHT: u32 = 705;
|
||||
const H_CENTER: u32 = (RIGHT + LEFT) / 2;
|
||||
const TOP: u32 = 282;
|
||||
const BOTTOM: u32 = 345;
|
||||
const V_CENTER: u32 = (TOP + BOTTOM) / 2;
|
||||
|
||||
let container_color = ThemePair::default().dark.surface.lowest_container;
|
||||
let primary = ThemePair::default().dark.primary.color;
|
||||
|
||||
recorder.assert_pixel_color(Point::new(LEFT, 35), container_color, "surface");
|
||||
// Verify the inner container color
|
||||
recorder.assert_pixel_color(Point::new(32, 62), container_color, "surface");
|
||||
|
||||
// Default fills the entire space
|
||||
recorder.assert_pixel_color(Point::new(LEFT, 70), primary, "default spacer");
|
||||
recorder.assert_pixel_color(Point::new(CENTER, 70), primary, "default spacer");
|
||||
recorder.assert_pixel_color(Point::new(RIGHT, 70), primary, "default spacer");
|
||||
recorder.assert_pixel_color(Point::new(LEFT, 78), primary, "default spacer");
|
||||
recorder.assert_pixel_color(Point::new(H_CENTER, 78), primary, "default spacer");
|
||||
recorder.assert_pixel_color(Point::new(RIGHT, 78), primary, "default spacer");
|
||||
|
||||
// align-left
|
||||
recorder.assert_pixel_color(Point::new(LEFT, 140), primary, "align-left spacer");
|
||||
recorder.assert_pixel_color(Point::new(LEFT, 110), primary, "align-left spacer");
|
||||
recorder.assert_pixel_color(
|
||||
Point::new(LEFT + PADDING, 140),
|
||||
Point::new(H_CENTER, 110),
|
||||
container_color,
|
||||
"align-left empty",
|
||||
);
|
||||
|
||||
// align-left-pad
|
||||
recorder.assert_pixel_color(
|
||||
Point::new(LEFT + PADDING, 215),
|
||||
primary,
|
||||
"align-left-pad spacer",
|
||||
);
|
||||
recorder.assert_pixel_color(
|
||||
Point::new(LEFT, 215),
|
||||
container_color,
|
||||
"align-left-pad empty before",
|
||||
);
|
||||
recorder.assert_pixel_color(
|
||||
Point::new(CENTER, 215),
|
||||
container_color,
|
||||
"align-left-pad empty after",
|
||||
);
|
||||
|
||||
// centered
|
||||
recorder.assert_pixel_color(Point::new(CENTER, 295), primary, "centered spacer");
|
||||
recorder.assert_pixel_color(Point::new(H_CENTER, 142), primary, "centered spacer");
|
||||
recorder.assert_pixel_color(
|
||||
Point::new(LEFT + PADDING, 295),
|
||||
Point::new(LEFT, 142),
|
||||
container_color,
|
||||
"centered empty before",
|
||||
);
|
||||
recorder.assert_pixel_color(
|
||||
Point::new(RIGHT - PADDING, 295),
|
||||
Point::new(RIGHT, 142),
|
||||
container_color,
|
||||
"centered empty after",
|
||||
);
|
||||
|
||||
// align-right-pad
|
||||
recorder.assert_pixel_color(
|
||||
Point::new(RIGHT - PADDING, 360),
|
||||
primary,
|
||||
"align-right-pad spacer",
|
||||
);
|
||||
recorder.assert_pixel_color(
|
||||
Point::new(CENTER, 360),
|
||||
container_color,
|
||||
"align-right-pad empty before",
|
||||
);
|
||||
recorder.assert_pixel_color(
|
||||
Point::new(RIGHT, 360),
|
||||
container_color,
|
||||
"align-right-pad empty after",
|
||||
);
|
||||
|
||||
// align-right
|
||||
recorder.assert_pixel_color(Point::new(RIGHT, 435), primary, "align-right spacer");
|
||||
recorder.assert_pixel_color(Point::new(RIGHT, 175), primary, "align-right spacer");
|
||||
recorder.assert_pixel_color(
|
||||
Point::new(RIGHT - PADDING, 435),
|
||||
Point::new(V_CENTER, 175),
|
||||
container_color,
|
||||
"align-right empty",
|
||||
);
|
||||
|
||||
// Default fills the entire space
|
||||
recorder.assert_pixel_color(Point::new(115, TOP), primary, "default spacer");
|
||||
recorder.assert_pixel_color(Point::new(115, V_CENTER), primary, "default spacer");
|
||||
recorder.assert_pixel_color(Point::new(115, BOTTOM), primary, "default spacer");
|
||||
|
||||
// align-top
|
||||
recorder.assert_pixel_color(Point::new(285, TOP), primary, "align-top spacer");
|
||||
recorder.assert_pixel_color(
|
||||
Point::new(285, V_CENTER),
|
||||
container_color,
|
||||
"align-top empty",
|
||||
);
|
||||
|
||||
// centered
|
||||
recorder.assert_pixel_color(Point::new(460, V_CENTER), primary, "centered spacer");
|
||||
recorder.assert_pixel_color(
|
||||
Point::new(460, TOP),
|
||||
container_color,
|
||||
"centered empty before",
|
||||
);
|
||||
recorder.assert_pixel_color(
|
||||
Point::new(460, BOTTOM),
|
||||
container_color,
|
||||
"centered empty after",
|
||||
);
|
||||
|
||||
// align-bottom
|
||||
recorder.assert_pixel_color(Point::new(635, BOTTOM), primary, "align-bottom spacer");
|
||||
recorder.assert_pixel_color(
|
||||
Point::new(635, V_CENTER),
|
||||
container_color,
|
||||
"align-bottom empty",
|
||||
);
|
||||
});
|
||||
}
|
||||
|
||||
|
|
|
|||
|
|
@ -67,3 +67,10 @@ impl BookExample {
|
|||
// {
|
||||
// }
|
||||
}
|
||||
|
||||
#[macro_export]
|
||||
macro_rules! book_example {
|
||||
($name:ident) => {
|
||||
guide_examples::BookExample::new(stringify!($name), $name())
|
||||
};
|
||||
}
|
||||
|
|
|
|||
|
|
@ -1,3 +1,42 @@
|
|||
# Summary
|
||||
|
||||
- [Chapter 1](./chapter_1.md)
|
||||
<!-- markdownlint-disable no-empty-links -->
|
||||
|
||||
[Introduction](./intro.md)
|
||||
|
||||
- [About Cushy](./about.md)
|
||||
- [Cushy's Philosophies](./about/philosophies.md)
|
||||
- [Widgets]()
|
||||
- [Layout Widgets](./widgets/layout.md)
|
||||
- [Align](./widgets/layout/align.md)
|
||||
- [Collapse]()
|
||||
- [Container]()
|
||||
- [Expand]()
|
||||
- [Grid]()
|
||||
- [Layers]()
|
||||
- [Resize]()
|
||||
- [Stack]()
|
||||
- [Wrap]()
|
||||
- [Controls](./widgets/controls.md)
|
||||
- [Button]()
|
||||
- [Canvas]()
|
||||
- [Checkbox]()
|
||||
- [Color Pickers]()
|
||||
- [Disclose]()
|
||||
- [Input]()
|
||||
- [Label]()
|
||||
- [ProgressBar]()
|
||||
- [Radio]()
|
||||
- [Scroll]()
|
||||
- [Select]()
|
||||
- [Slider]()
|
||||
- [Switcher]()
|
||||
- [Image]()
|
||||
- [TileMap]()
|
||||
- [Utility Widgets](./widgets/utility.md)
|
||||
- [Custom]()
|
||||
- [Data]()
|
||||
- [Style]()
|
||||
- [Themed]()
|
||||
- [ThemedMode]()
|
||||
- [Space](./widgets/utility/space.md)
|
||||
|
|
|
|||
1
guide/src/about.md
Normal file
1
guide/src/about.md
Normal file
|
|
@ -0,0 +1 @@
|
|||
# About
|
||||
34
guide/src/about/philosophies.md
Normal file
34
guide/src/about/philosophies.md
Normal file
|
|
@ -0,0 +1,34 @@
|
|||
# Cushy's Philosophies
|
||||
|
||||
There are a lot of GUI libraries with wildly varying approaches to how UIs are
|
||||
displayed. Here's the philosophies that drive Cushy's design:
|
||||
|
||||
- Cushy retains information between redraws so that many events can be handled
|
||||
without redrawing the user interface.
|
||||
- Everything is a widget. The "root" of a user interface/window is a widget, and
|
||||
widgets can contain other widgets.
|
||||
- Composition is powerful and easy to reason about. The built-in widget library
|
||||
is aimed at providing a suite of libraries each with an individual purpose to
|
||||
aide in developers being able to compose more complex user interfaces from
|
||||
more basic widgets.
|
||||
- If a developer dislikes a built-in widget's behavior, they should be empowered
|
||||
to create their own that behaves the way they desire. To ensure developers
|
||||
have this flexibility, all provided widgets must only utilize functionality
|
||||
that is publicly available.
|
||||
- Widgets should be flexible in the types they support, prefering trait
|
||||
implementations instead of hard-coded types. For example, the Label widget
|
||||
supports any type that implements `Display`.
|
||||
- Cushy needs both physical pixel and resolution independent measurement types.
|
||||
UI designers want to use real-world measurements that scale based on the DPI
|
||||
resolution of the device it is being rendered on. Widget authors and game
|
||||
developers want to work with pixel-perfect measurements to ensure perfect
|
||||
alignment.
|
||||
|
||||
From an implementation standpoint, Cushy has these goals:
|
||||
|
||||
- For graphics, provide a wgpu-centric library that exposes a rendering API
|
||||
inspired by wgpu's Encapsulating Graphics Work article.
|
||||
- For windowing, embrace winit and route input events to the correct widgets.
|
||||
This allows widgets to support any features that winit can support.
|
||||
- Cushy should be able to idle at close to 0% CPU. Cushy should not redraw
|
||||
unless needed.
|
||||
|
|
@ -1,33 +0,0 @@
|
|||
# Aligning Widgets
|
||||
|
||||

|
||||
|
||||
## Align a widget to the left
|
||||
|
||||
```rust,no_run,no_playground
|
||||
{{#include ../guide-examples/examples/align.rs:align-left}}
|
||||
```
|
||||
|
||||
## Align a widget to the left, with padding
|
||||
|
||||
```rust,no_run,no_playground
|
||||
{{#include ../guide-examples/examples/align.rs:align-left-pad}}
|
||||
```
|
||||
|
||||
## Align a widget to the center
|
||||
|
||||
```rust,no_run,no_playground
|
||||
{{#include ../guide-examples/examples/align.rs:centered}}
|
||||
```
|
||||
|
||||
## Align a widget to the right, with padding
|
||||
|
||||
```rust,no_run,no_playground
|
||||
{{#include ../guide-examples/examples/align.rs:align-right-pad}}
|
||||
```
|
||||
|
||||
## Align a widget to the right
|
||||
|
||||
```rust,no_run,no_playground
|
||||
{{#include ../guide-examples/examples/align.rs:align-right}}
|
||||
```
|
||||
Binary file not shown.
|
Before Width: | Height: | Size: 33 KiB |
BIN
guide/src/examples/align.png
Normal file
BIN
guide/src/examples/align.png
Normal file
Binary file not shown.
|
After Width: | Height: | Size: 39 KiB |
1
guide/src/intro.md
Normal file
1
guide/src/intro.md
Normal file
|
|
@ -0,0 +1 @@
|
|||
# Welcome
|
||||
4
guide/src/widgets/controls.md
Normal file
4
guide/src/widgets/controls.md
Normal file
|
|
@ -0,0 +1,4 @@
|
|||
# Controls
|
||||
|
||||
This section contains interactive widgets that read and/or write data through
|
||||
the reactive data model.
|
||||
4
guide/src/widgets/layout.md
Normal file
4
guide/src/widgets/layout.md
Normal file
|
|
@ -0,0 +1,4 @@
|
|||
# Layout
|
||||
|
||||
Widgets in this section have a primary purpose of performing some layout
|
||||
functionality on one or more child widgets.
|
||||
96
guide/src/widgets/layout/align.md
Normal file
96
guide/src/widgets/layout/align.md
Normal file
|
|
@ -0,0 +1,96 @@
|
|||
# Aligning Widgets
|
||||
|
||||
{{#title Align - Layout Widgets - Cushy User's Guide}}
|
||||
|
||||
The [`Align`][align] widget positions a child widget within its parent. It
|
||||
supports both horizontal and vertical alignment.
|
||||
|
||||
It accomplishes this by requesting the child measure itself using
|
||||
[`SizeToFit`][sizetofit] for the child's width and/or height, and then positions
|
||||
the child to align it.
|
||||
|
||||
The align widget uses [`Edges`][edges][`<FlexibleDimension>`][flexibledimension]
|
||||
to specify the alignment of each edge. If an edge is
|
||||
[`FlexibleDimension::Dimension`][flexexact], that edge of the child will be
|
||||
placed the exact measurement from the parent's matching edge. If an edge is
|
||||
[`FlexibleDimension::Auto`][flexauto], that edge will not be positioned relative
|
||||
to the parent's matching edge.
|
||||
|
||||
## Examples
|
||||
|
||||

|
||||
|
||||
The `content()` function in each of these snippets is a [`Space`][space] widget
|
||||
occupying at least 32px squared:
|
||||
|
||||
```rust,no_run,no_playground
|
||||
{{#include ../../../guide-examples/examples/align.rs:content}}
|
||||
```
|
||||
|
||||
### Align a widget to the left
|
||||
|
||||
Any widget can be aligned to the left using
|
||||
[`MakeWidget::align_left()`][align-left]:
|
||||
|
||||
```rust,no_run,no_playground
|
||||
{{#include ../../../guide-examples/examples/align.rs:align-left}}
|
||||
```
|
||||
|
||||
### Align a widget to the center
|
||||
|
||||
Any widget can be centered using
|
||||
[`MakeWidget::centered()`][align-center]:
|
||||
|
||||
```rust,no_run,no_playground
|
||||
{{#include ../../../guide-examples/examples/align.rs:horizontal-center}}
|
||||
```
|
||||
|
||||
`centered()` works in both axis. To center only in one direction, "fit" the
|
||||
other direction:
|
||||
|
||||
- To center vertically but occupy the parent's width, use
|
||||
[`MakeWidget::fit_horizontally()`][fit-vert].
|
||||
- To center horizontally but occupy the parent's height, use
|
||||
[`MakeWidget::fit_vertically()`][fit-horiz].
|
||||
|
||||
### Align a widget to the right
|
||||
|
||||
Any widget can be aligned to the right using
|
||||
[`MakeWidget::align_right()`][align-right]:
|
||||
|
||||
```rust,no_run,no_playground
|
||||
{{#include ../../../guide-examples/examples/align.rs:align-right}}
|
||||
```
|
||||
|
||||
### Align a widget to the top
|
||||
|
||||
Any widget can be aligned to the top using
|
||||
[`MakeWidget::align_top()`][align-top]:
|
||||
|
||||
```rust,no_run,no_playground
|
||||
{{#include ../../../guide-examples/examples/align.rs:align-top}}
|
||||
```
|
||||
|
||||
### Align a widget to the bottom
|
||||
|
||||
Any widget can be aligned to the bottom using
|
||||
[`MakeWidget::align_bottom()`][align-bottom]:
|
||||
|
||||
```rust,no_run,no_playground
|
||||
{{#include ../../../guide-examples/examples/align.rs:align-bottom}}
|
||||
```
|
||||
|
||||
[align]: <{{ docs }}/widgets/struct.Align.html>
|
||||
[align-left]: <{{ docs }}/widget/trait.MakeWidget.html#method.align_left>
|
||||
[align-center]: <{{ docs }}/widget/trait.MakeWidget.html#method.centered>
|
||||
[align-right]: <{{ docs }}/widget/trait.MakeWidget.html#method.align_right>
|
||||
[align-top]: <{{ docs }}/widget/trait.MakeWidget.html#method.align_top>
|
||||
[align-bottom]: <{{ docs }}/widget/trait.MakeWidget.html#method.align_bottom>
|
||||
[sizetofit]: <{{ docs }}/enum.ConstraintLimit.html#variant.SizeToFit>
|
||||
[edges]: <{{ docs }}/styles/struct.Edges.html>
|
||||
[flexibledimension]: <{{ docs }}/styles/enum.FlexibleDimension.html>
|
||||
[flexexact]: <{{ docs }}/styles/enum.FlexibleDimension.html#variant.Dimension>
|
||||
[flexauto]: <{{ docs }}/styles/enum.FlexibleDimension.html#variant.Auto>
|
||||
[fit-vert]: <https://cushy.rs/main/docs/cushy/widget/trait.MakeWidget.html#method.fit_vertically>
|
||||
[fit-horiz]: <https://cushy.rs/main/docs/cushy/widget/trait.MakeWidget.html#method.fit_horizontally>
|
||||
[space]: ../utility/space.md
|
||||
1
guide/src/widgets/layout/layout.md
Normal file
1
guide/src/widgets/layout/layout.md
Normal file
|
|
@ -0,0 +1 @@
|
|||
# Layout Widgets
|
||||
4
guide/src/widgets/utility.md
Normal file
4
guide/src/widgets/utility.md
Normal file
|
|
@ -0,0 +1,4 @@
|
|||
# Utility Widgets
|
||||
|
||||
The widgets in this section are non-interactive widgets that do not directly
|
||||
impact the layout of other widgets.
|
||||
5
guide/src/widgets/utility/space.md
Normal file
5
guide/src/widgets/utility/space.md
Normal file
|
|
@ -0,0 +1,5 @@
|
|||
# Space Widget
|
||||
|
||||
The [`Space`][space]
|
||||
|
||||
[space]: <{{ docs }}/widgets/struct.Space.html>
|
||||
Loading…
Reference in a new issue