Skip to content

Commit

Permalink
Merge branch 'main' into virtual-list
Browse files Browse the repository at this point in the history
  • Loading branch information
ecton committed Nov 8, 2024
2 parents 11eb1c8 + 7da3f9f commit 933bdf2
Show file tree
Hide file tree
Showing 31 changed files with 1,529 additions and 303 deletions.
40 changes: 39 additions & 1 deletion CHANGELOG.md
Original file line number Diff line number Diff line change
Expand Up @@ -63,6 +63,31 @@ and this project adheres to [Semantic Versioning](https://semver.org/spec/v2.0.0
- `IntoReader::to_label` and `IntoReader::into_label` have been moved to their
own trait: `Displayable`. This allows more flexible acceptance of types.
- `MakeWidget::widget_ref` has been renamed to `MakeWidget::into_ref`.
- `Radio` and `Checkbox` are now powered by a new widget `Indicator<T>`. This
new implementation treats the indicators as independently focusable widgets
rather than how the `Button`-powered implementation shows focus around the
entire "label" of the button.

The `Button`-powered implementation can still be used by using the `kind`
function to pick the `ButtonKind` to use. Prior to this change,
`ButtonKind::Transparent` was the default.

Lastly, several APIs no longer accept a `label` parameter. Instead, the
widgets have new functions `labelled_by(label)` that can be used to attach a
clickable label to an indicator. The affected APIs are:

- `Radio::new`
- `Checkbox::new`
- `Checkable::into_checkbox`
- `Checkable::to_checkbox`
- `Dynamic::new_radio`
- `Dynamic::new_checkbox`
- `Space` no longer implements hit_test. If you need an area to intercept mouse
events, wrap the `Space` in a `Custom` widget:

```rust
Custom::new(Space::colored(Color::RED)).on_hit_test(|_, _| true)
```

### Changed

Expand All @@ -87,6 +112,8 @@ and this project adheres to [Semantic Versioning](https://semver.org/spec/v2.0.0
- If the root widget of a window is a `Resize` with an exact width and height,
the window will have its resizable attribute disabled. This will not update
the resizable `Dynamic<bool>` on `Window`.
- Transparent buttons' focus rings are now drawn using the same corner radius as
the button and have padding between the label and the focus ring.

### Fixed

Expand Down Expand Up @@ -273,12 +300,23 @@ and this project adheres to [Semantic Versioning](https://semver.org/spec/v2.0.0
that allows completely customizing a scroll view's behavior. Thanks to
@danbulant for helping with this change!
- `ScrollBar` is a new widget that renders a scroll bar meant to scroll through
a large container.
a large container. Additionally its appearance has been updated to be based on
the theme. Several new style components have been added to control how scroll
bars are rendered: `ScrollBarThumbColor`, `ScrollBarThumbOutlineColor`,
`ScrollBarThumbOutlineThickness`, `ScrollBarThumbCornerRadius`.
- `Label::overflow` allows customizing the behavior for a label when it cannot
be drawn on a single line.
- `ConstraintLimit::fill_or_fit` is a new function that will fill the available
space when being requested to fill, otherwise it return the minimum of the
measured size and the constraint limit.
- `OutlineWidth` is a new component that is used to control the width of most
outlines drawn in the user interface.
- `FocusColor` is a new component that controls the color of the keyboard focus
indicator.
- `Graphics::draw` and `Graphics::draw_with` are a new function that allows
performing arbitrary `wgpu` drawing operations when rendering. See the
`shaders.rs` example for an example on how to use this to render into a Canvas
with a custom shader.


[139]: https://github.com/khonsulabs/cushy/issues/139
Expand Down
26 changes: 13 additions & 13 deletions Cargo.lock

Some generated files are not rendered by default. Learn more about how customized files appear on GitHub.

3 changes: 2 additions & 1 deletion examples/checkbox.rs
Original file line number Diff line number Diff line change
Expand Up @@ -9,7 +9,8 @@ fn main() -> cushy::Result {

checkbox_state
.clone()
.to_checkbox(label)
.to_checkbox()
.labelled_by(label)
.and("Maybe".into_button().on_click(move |_| {
checkbox_state.set(CheckboxState::Indeterminant);
}))
Expand Down
3 changes: 2 additions & 1 deletion examples/collapse.rs
Original file line number Diff line number Diff line change
Expand Up @@ -10,7 +10,8 @@ fn main() -> cushy::Result {
let collapse = Dynamic::new(false);

collapse
.to_checkbox("Collapse")
.to_checkbox()
.labelled_by("Collapse")
.and(
"Content Above"
.contain()
Expand Down
26 changes: 20 additions & 6 deletions examples/file-picker.rs
Original file line number Diff line number Diff line change
Expand Up @@ -32,13 +32,27 @@ fn main(app: &mut App) -> cushy::Result {
pending
.with_root(
picker_mode
.new_radio(PickerMode::SaveFile, "Save File")
.and(picker_mode.new_radio(PickerMode::PickFile, "Pick File"))
.and(picker_mode.new_radio(PickerMode::PickFolder, "Pick Folder"))
.new_radio(PickerMode::SaveFile)
.labelled_by("Save File")
.and(
picker_mode
.new_radio(PickerMode::PickFile)
.labelled_by("Pick File"),
)
.and(
picker_mode
.new_radio(PickerMode::PickFolder)
.labelled_by("Pick Folder"),
)
.into_columns()
.and(pick_multiple.to_checkbox("Select Multiple").with_enabled(
picker_mode.map_each(|kind| !matches!(kind, PickerMode::SaveFile)),
))
.and(
pick_multiple
.to_checkbox()
.labelled_by("Select Multiple")
.with_enabled(
picker_mode.map_each(|kind| !matches!(kind, PickerMode::SaveFile)),
),
)
.and(picker_buttons(
&picker_mode,
&pick_multiple,
Expand Down
21 changes: 11 additions & 10 deletions examples/fullscreen.rs
Original file line number Diff line number Diff line change
Expand Up @@ -10,7 +10,8 @@ fn main(app: &mut App) -> cushy::Result {
let fullscreen = Dynamic::new(None);

fullscreen
.new_radio(None, "Not Fullscreen")
.new_radio(None)
.labelled_by("Not Fullscreen")
.and(
monitors
.available
Expand Down Expand Up @@ -38,20 +39,20 @@ fn monitor_modes(
let name = monitor.name().unwrap_or_else(|| format!("Monitor {index}"));

name.h1()
.and(fullscreen.new_radio(
Some(Fullscreen::Borderless(Some(monitor.handle().clone()))),
"Borderless Fullscreen",
))
.and(
fullscreen
.new_radio(Some(Fullscreen::Borderless(Some(monitor.handle().clone()))))
.labelled_by("Borderless Fullscreen"),
)
.chain(monitor.video_modes().map(|mode| {
fullscreen.new_radio(
Some(Fullscreen::Exclusive(mode.handle().clone())),
format!(
fullscreen
.new_radio(Some(Fullscreen::Exclusive(mode.handle().clone())))
.labelled_by(format!(
"{}x{} @ {}Hz ({}-bit color)",
mode.size().width,
mode.size().height,
mode.refresh_rate_millihertz() as f32 / 1_000.,
mode.bit_depth()
),
)
))
}))
}
23 changes: 16 additions & 7 deletions examples/image.rs
Original file line number Diff line number Diff line change
Expand Up @@ -64,8 +64,8 @@ fn main() -> cushy::Result {

let apsect_mode_select = "Mode"
.h3()
.and(aspect_mode.new_radio(Aspect::Fit, "Fit"))
.and(aspect_mode.new_radio(Aspect::Fill, "Fill"))
.and(aspect_mode.new_radio(Aspect::Fit).labelled_by("Fit"))
.and(aspect_mode.new_radio(Aspect::Fill).labelled_by("Fill"))
.into_rows();

let hide_aspect_editor = mode.map_each(|scale| !matches!(scale, ScalingMode::Aspect));
Expand All @@ -77,20 +77,29 @@ fn main() -> cushy::Result {

let filter_select = "Filter mode"
.h1()
.and(selected_filter.new_radio(FilterMode::Nearest, "Nearest"))
.and(selected_filter.new_radio(FilterMode::Linear, "Linear"))
.and(
selected_filter
.new_radio(FilterMode::Nearest)
.labelled_by("Nearest"),
)
.and(
selected_filter
.new_radio(FilterMode::Linear)
.labelled_by("Linear"),
)
.into_rows();

let mode_select = "Scaling Mode"
.h1()
.and(mode.new_radio(ScalingMode::Scale, "Scale"))
.and(mode.new_radio(ScalingMode::Scale).labelled_by("Scale"))
.and(scale_editor)
.and(
mode.new_radio(ScalingMode::Aspect, "Aspect")
mode.new_radio(ScalingMode::Aspect)
.labelled_by("Aspect")
.and(aspect_editor)
.into_rows(),
)
.and(mode.new_radio(ScalingMode::Stretch, "Stretch"))
.and(mode.new_radio(ScalingMode::Stretch).labelled_by("Stretch"))
.and(filter_select)
.into_rows();

Expand Down
6 changes: 5 additions & 1 deletion examples/list.rs
Original file line number Diff line number Diff line change
Expand Up @@ -7,7 +7,11 @@ fn list() -> impl MakeWidget {
let current_style: Dynamic<ListStyle> = Dynamic::default();
let options = ListStyle::provided()
.into_iter()
.map(|style| current_style.new_radio(style.clone(), format!("{style:?}")))
.map(|style| {
current_style
.new_radio(style.clone())
.labelled_by(format!("{style:?}"))
})
.collect::<WidgetList>();

let rows = (1..100).map(|i| i.to_string()).collect::<WidgetList>();
Expand Down
7 changes: 4 additions & 3 deletions examples/radio.rs
Original file line number Diff line number Diff line change
Expand Up @@ -14,9 +14,10 @@ fn main() -> cushy::Result {
let option = Dynamic::default();

option
.new_radio(Choice::A, "A")
.and(option.new_radio(Choice::B, "B"))
.and(option.new_radio(Choice::C, "C"))
.new_radio(Choice::A)
.labelled_by("A")
.and(option.new_radio(Choice::B).labelled_by("B"))
.and(option.new_radio(Choice::C).labelled_by("C"))
.into_rows()
.centered()
.run()
Expand Down
Loading

0 comments on commit 933bdf2

Please sign in to comment.