mirror of https://github.com/linebender/xilem
Additional flex view options (#285)
Wired up some more existing masonry flex properties so they can be set on the flex view. I was messing around with a dummy example to try out the v0.1 and noticed I couldn't easily center something because flex was only exposing direction not alignment/cross-alignment. It looked like all the logic already exists in masonry so it was just a matter of wiring it up. This is my first contribution so sorry if I missed some steps. Sidenote: I didn't see any examples of testing that a view updates the underlying element so I am guessing that is still tbd. If someone has a suggestion for a good way to do that I am happy to try it out. I'm also not sure what the etiquette is on adding/editing examples so I just included the example I was using to verify it worked but no stress if you want to remove it.
This commit is contained in:
parent
43bd4ef090
commit
aaeeadbbd7
|
@ -0,0 +1,30 @@
|
|||
// Copyright 2024 the Xilem Authors
|
||||
// SPDX-License-Identifier: Apache-2.0
|
||||
|
||||
use masonry::widget::{CrossAxisAlignment, MainAxisAlignment};
|
||||
use winit::error::EventLoopError;
|
||||
use xilem::{
|
||||
view::{button, flex, label},
|
||||
MasonryView, Xilem,
|
||||
};
|
||||
|
||||
fn app_logic(data: &mut i32) -> impl MasonryView<i32> {
|
||||
flex((
|
||||
button("-", |data| {
|
||||
*data -= 1;
|
||||
}),
|
||||
label(format!("count: {}", data)),
|
||||
button("+", |data| {
|
||||
*data += 1;
|
||||
}),
|
||||
))
|
||||
.direction(xilem::Axis::Horizontal)
|
||||
.cross_axis_alignment(CrossAxisAlignment::Center)
|
||||
.main_axis_alignment(MainAxisAlignment::Center)
|
||||
}
|
||||
|
||||
fn main() -> Result<(), EventLoopError> {
|
||||
let app = Xilem::new(0, app_logic);
|
||||
app.run_windowed("Centered Flex".into())?;
|
||||
Ok(())
|
||||
}
|
|
@ -4,7 +4,7 @@
|
|||
use std::marker::PhantomData;
|
||||
|
||||
use masonry::{
|
||||
widget::{self, Axis, WidgetMut},
|
||||
widget::{self, Axis, CrossAxisAlignment, MainAxisAlignment, WidgetMut},
|
||||
Widget, WidgetPod,
|
||||
};
|
||||
|
||||
|
@ -16,12 +16,18 @@ pub fn flex<VT, Marker>(sequence: VT) -> Flex<VT, Marker> {
|
|||
phantom: PhantomData,
|
||||
sequence,
|
||||
axis: Axis::Vertical,
|
||||
cross_axis_alignment: CrossAxisAlignment::Center,
|
||||
main_axis_alignment: MainAxisAlignment::Start,
|
||||
fill_major_axis: false,
|
||||
}
|
||||
}
|
||||
|
||||
pub struct Flex<VT, Marker> {
|
||||
sequence: VT,
|
||||
axis: Axis,
|
||||
cross_axis_alignment: CrossAxisAlignment,
|
||||
main_axis_alignment: MainAxisAlignment,
|
||||
fill_major_axis: bool,
|
||||
phantom: PhantomData<fn() -> Marker>,
|
||||
}
|
||||
|
||||
|
@ -30,6 +36,20 @@ impl<VT, Marker> Flex<VT, Marker> {
|
|||
self.axis = axis;
|
||||
self
|
||||
}
|
||||
pub fn cross_axis_alignment(mut self, axis: CrossAxisAlignment) -> Self {
|
||||
self.cross_axis_alignment = axis;
|
||||
self
|
||||
}
|
||||
|
||||
pub fn main_axis_alignment(mut self, axis: MainAxisAlignment) -> Self {
|
||||
self.main_axis_alignment = axis;
|
||||
self
|
||||
}
|
||||
|
||||
pub fn must_fill_major_axis(mut self, fill_major_axis: bool) -> Self {
|
||||
self.fill_major_axis = fill_major_axis;
|
||||
self
|
||||
}
|
||||
}
|
||||
|
||||
impl<State, Action, Marker: 'static, Seq> MasonryView<State, Action> for Flex<Seq, Marker>
|
||||
|
@ -47,7 +67,10 @@ where
|
|||
let mut scratch = Vec::new();
|
||||
let mut splice = VecSplice::new(&mut elements, &mut scratch);
|
||||
let seq_state = self.sequence.build(cx, &mut splice);
|
||||
let mut view = widget::Flex::for_axis(self.axis);
|
||||
let mut view = widget::Flex::for_axis(self.axis)
|
||||
.cross_axis_alignment(self.cross_axis_alignment)
|
||||
.must_fill_main_axis(self.fill_major_axis)
|
||||
.main_axis_alignment(self.main_axis_alignment);
|
||||
debug_assert!(
|
||||
scratch.is_empty(),
|
||||
// TODO: Not at all confident about this, but linear_layout makes this assumption
|
||||
|
@ -81,6 +104,18 @@ where
|
|||
element.set_direction(self.axis);
|
||||
cx.mark_changed();
|
||||
}
|
||||
if prev.cross_axis_alignment != self.cross_axis_alignment {
|
||||
element.set_cross_axis_alignment(self.cross_axis_alignment);
|
||||
cx.mark_changed();
|
||||
}
|
||||
if prev.main_axis_alignment != self.main_axis_alignment {
|
||||
element.set_main_axis_alignment(self.main_axis_alignment);
|
||||
cx.mark_changed();
|
||||
}
|
||||
if prev.fill_major_axis != self.fill_major_axis {
|
||||
element.set_must_fill_main_axis(self.fill_major_axis);
|
||||
cx.mark_changed();
|
||||
}
|
||||
let mut splice = FlexSplice { ix: 0, element };
|
||||
self.sequence
|
||||
.rebuild(view_state, cx, &prev.sequence, &mut splice);
|
||||
|
|
Loading…
Reference in New Issue