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 (lapce#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.