Skip to content

Commit

Permalink
Additional flex view options (#285)
Browse files Browse the repository at this point in the history
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.
  • Loading branch information
keeslinp committed May 9, 2024
1 parent 43bd4ef commit aaeeadb
Show file tree
Hide file tree
Showing 2 changed files with 67 additions and 2 deletions.
30 changes: 30 additions & 0 deletions crates/xilem_masonry/examples/flex.rs
Original file line number Diff line number Diff line change
@@ -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(())
}
39 changes: 37 additions & 2 deletions crates/xilem_masonry/src/view/flex.rs
Original file line number Diff line number Diff line change
Expand Up @@ -4,7 +4,7 @@
use std::marker::PhantomData;

use masonry::{
widget::{self, Axis, WidgetMut},
widget::{self, Axis, CrossAxisAlignment, MainAxisAlignment, WidgetMut},
Widget, WidgetPod,
};

Expand All @@ -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>,
}

Expand All @@ -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>
Expand All @@ -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
Expand Down Expand Up @@ -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);
Expand Down

0 comments on commit aaeeadb

Please sign in to comment.