Skip to content

Commit

Permalink
Make style changes which alter inherited style properties request lay…
Browse files Browse the repository at this point in the history
…out for all children (#140)

* Add an example with theme toggle using style classes

* Make style changes which alter inherited style properties request layout for all children
  • Loading branch information
Zoxc authored Nov 3, 2023
1 parent e903531 commit ff0b075
Show file tree
Hide file tree
Showing 8 changed files with 191 additions and 22 deletions.
7 changes: 7 additions & 0 deletions examples/themes/Cargo.toml
Original file line number Diff line number Diff line change
@@ -0,0 +1,7 @@
[package]
name = "themes"
version = "0.1.0"
edition = "2021"

[dependencies]
floem = { path = "../.." }
138 changes: 138 additions & 0 deletions examples/themes/src/main.rs
Original file line number Diff line number Diff line change
@@ -0,0 +1,138 @@
use floem::{
event::{Event, EventListener},
keyboard::{Key, NamedKey},
peniko::Color,
reactive::create_signal,
style::Style,
style_class,
view::View,
views::{label, stack, text, Decorators},
};

style_class!(pub Button);
style_class!(pub Label);
style_class!(pub Frame);

fn app_view() -> impl View {
let blue_button = Style::new()
.background(Color::rgb8(137, 145, 160))
.color(Color::WHITE)
.border(1.0)
.border_color(Color::rgb8(109, 121, 135))
.hover(|s| s.background(Color::rgb8(170, 175, 187)))
.disabled(|s| {
s.background(Color::DARK_GRAY.with_alpha_factor(0.1))
.border_color(Color::BLACK.with_alpha_factor(0.2))
})
.active(|s| s.background(Color::BLACK.with_alpha_factor(0.4)))
.padding(5.0)
.margin(3.0)
.border_radius(5.0);
let blue_theme = Style::new()
.background(Color::rgb8(95, 102, 118))
.color(Color::WHITE)
.class(Button, move |_| blue_button)
.class(Label, |s| s.margin(4.0))
.font_size(12.0);

let green_button = Style::new()
.background(Color::rgb8(180, 188, 175))
.disabled(|s| {
s.background(Color::rgb8(180, 188, 175).with_alpha_factor(0.3))
.border_color(Color::rgb8(131, 145, 123).with_alpha_factor(0.3))
})
.active(|s| s.background(Color::rgb8(95, 105, 88)).color(Color::WHITE))
.color(Color::BLACK.with_alpha_factor(0.7))
.border(2.0)
.border_color(Color::rgb8(131, 145, 123))
.hover(|s| s.background(Color::rgb8(204, 209, 201)))
.padding(8.0)
.border_radius(8.0)
.margin(6.0);
let green_theme = Style::new()
.background(Color::rgb8(227, 231, 226))
.class(Button, move |_| green_button)
.class(Label, |s| s.margin(4.0))
.class(Frame, |s| {
s.border(2.0)
.border_color(Color::rgb8(131, 145, 123).with_alpha_factor(0.2))
.border_radius(8.0)
.background(Color::WHITE.with_alpha_factor(0.1))
.padding(12.0)
})
.color(Color::BLACK.with_alpha_factor(0.5))
.font_size(16.0);

let (counter, set_counter) = create_signal(0);
let (theme, set_theme) = create_signal(true);
let view = stack((stack((
text("Toggle Theme")
.class(Button)
.on_click({
move |_| {
set_theme.update(|theme| *theme = !*theme);
true
}
})
.keyboard_navigatable(),
stack((
label(move || format!("Value: {}", counter.get())).class(Label),
text("Increment")
.class(Button)
.on_click({
move |_| {
set_counter.update(|value| *value += 1);
true
}
})
.keyboard_navigatable(),
text("Decrement")
.class(Button)
.on_click({
move |_| {
set_counter.update(|value| *value -= 1);
true
}
})
.keyboard_navigatable(),
text("Reset to 0")
.class(Button)
.on_click(move |_| {
println!("Reset counter pressed"); // will not fire if button is disabled
set_counter.update(|value| *value = 0);
true
})
.disabled(move || counter.get() == 0)
.keyboard_navigatable(),
))
.class(Frame)
.style(|s| s.items_center()),
))
.style(|s| s.items_center()),))
.style(move |_| {
if theme.get() {
blue_theme.clone()
} else {
green_theme.clone()
}
.width_full()
.height_full()
.flex_col()
.items_center()
.justify_center()
});

let id = view.id();
view.on_event(EventListener::KeyUp, move |e| {
if let Event::KeyUp(e) = e {
if e.key.logical_key == Key::Named(NamedKey::F11) {
id.inspect();
}
}
true
})
}

fn main() {
floem::launch(app_view);
}
10 changes: 10 additions & 0 deletions src/context.rs
Original file line number Diff line number Diff line change
Expand Up @@ -51,6 +51,8 @@ pub struct ViewState {
pub(crate) node: Node,
pub(crate) children_nodes: Vec<Node>,
pub(crate) request_layout: bool,
/// Layout is requested on all direct and indirect children.
pub(crate) request_layout_recursive: bool,
pub(crate) has_style_selectors: StyleSelectors,
pub(crate) viewport: Option<Rect>,
pub(crate) layout_rect: Rect,
Expand Down Expand Up @@ -78,6 +80,7 @@ impl ViewState {
layout_rect: Rect::ZERO,
layout_props: Default::default(),
request_layout: true,
request_layout_recursive: false,
has_style_selectors: StyleSelectors::default(),
animation: None,
base_style: None,
Expand Down Expand Up @@ -370,6 +373,13 @@ impl AppState {
}
}

/// Requests layout for a view and all direct and indirect children.
pub(crate) fn request_layout_recursive(&mut self, id: Id) {
let view = self.view_state(id);
view.request_layout_recursive = true;
self.request_layout(id);
}

pub fn request_layout(&mut self, id: Id) {
let view = self.view_state(id);
if view.request_layout {
Expand Down
8 changes: 5 additions & 3 deletions src/style.rs
Original file line number Diff line number Diff line change
Expand Up @@ -556,10 +556,12 @@ impl Style {
}
}

pub(crate) fn apply_only_inherited(this: &mut Rc<Style>, over: &Style) {
let any_inherited = over.map.iter().any(|(p, _)| p.info.inherited);
pub(crate) fn any_inherited(&self) -> bool {
!self.classes.is_empty() || self.map.iter().any(|(p, _)| p.info.inherited)
}

if any_inherited || !over.classes.is_empty() {
pub(crate) fn apply_only_inherited(this: &mut Rc<Style>, over: &Style) {
if over.any_inherited() {
let inherited = over
.map
.iter()
Expand Down
19 changes: 15 additions & 4 deletions src/view.rs
Original file line number Diff line number Diff line change
Expand Up @@ -197,16 +197,30 @@ pub trait View {
fn layout_main(&mut self, cx: &mut LayoutCx) -> Node {
cx.save();

let view_state = cx.app_state_mut().view_state(self.id());

let view_style = self.view_style();
let view_class = self.view_class();
let class = cx.app_state_mut().view_state(self.id()).class;
let class = view_state.class;
let class_array;
let classes = if let Some(class) = class {
class_array = [class];
&class_array[..]
} else {
&[]
};

// Propagate layout requests to children if needed.
if view_state.request_layout_recursive {
view_state.request_layout_recursive = false;
view_state.request_layout = true;
for child in self.children() {
cx.app_state_mut()
.view_state(child.id())
.request_layout_recursive = true;
}
}

cx.app_state.compute_style(
self.id(),
view_style,
Expand Down Expand Up @@ -253,9 +267,6 @@ pub trait View {

cx.save();

cx.style.direct = cx.app_state_mut().get_computed_style(self.id()).clone();
Style::apply_only_inherited(&mut cx.style.current, &cx.style.direct);

let layout = cx
.app_state()
.get_layout(self.id())
Expand Down
9 changes: 0 additions & 9 deletions src/views/label.rs
Original file line number Diff line number Diff line change
Expand Up @@ -196,15 +196,6 @@ impl View for Label {
return None;
}

if self.font.read(cx) | self.style.read(cx) {
self.text_layout = None;
self.available_text = None;
self.available_width = None;
self.available_text_layout = None;
self.set_text_layout();
cx.app_state_mut().request_layout(self.id());
}

let layout = cx.get_layout(self.id()).unwrap();
let style = cx.app_state_mut().get_builtin_style(self.id);
let text_overflow = style.text_overflow();
Expand Down
6 changes: 3 additions & 3 deletions src/views/scroll.rs
Original file line number Diff line number Diff line change
Expand Up @@ -44,9 +44,9 @@ enum BarHeldState {
style_class!(pub Handle);
style_class!(pub Track);

prop!(pub Rounded: bool { inherited } = cfg!(target_os = "macos"));
prop!(pub Thickness: Px { inherited } = Px(10.0));
prop!(pub Border: Px { inherited } = Px(0.0));
prop!(pub Rounded: bool {} = cfg!(target_os = "macos"));
prop!(pub Thickness: Px {} = Px(10.0));
prop!(pub Border: Px {} = Px(0.0));

prop_extracter! {
ScrollStyle {
Expand Down
16 changes: 13 additions & 3 deletions src/window_handle.rs
Original file line number Diff line number Diff line change
Expand Up @@ -709,18 +709,28 @@ impl WindowHandle {
}
UpdateMessage::BaseStyle { id, style } => {
let state = cx.app_state.view_state(id);
let old_any_inherited = state.style.any_inherited();
state.base_style = Some(style);
cx.request_layout(id);
if state.style.any_inherited() || old_any_inherited {
cx.app_state.request_layout_recursive(id);
} else {
cx.request_layout(id);
}
}
UpdateMessage::Style { id, style } => {
let state = cx.app_state.view_state(id);
let old_any_inherited = state.style.any_inherited();
state.style = style;
cx.request_layout(id);
if state.style.any_inherited() || old_any_inherited {
cx.app_state.request_layout_recursive(id);
} else {
cx.request_layout(id);
}
}
UpdateMessage::Class { id, class } => {
let state = cx.app_state.view_state(id);
state.class = Some(class);
cx.request_layout(id);
cx.app_state.request_layout_recursive(id);
}
UpdateMessage::StyleSelector {
id,
Expand Down

0 comments on commit ff0b075

Please sign in to comment.