diff --git a/Cargo.toml b/Cargo.toml index 6063687f..c5d35f92 100644 --- a/Cargo.toml +++ b/Cargo.toml @@ -12,7 +12,9 @@ rustc-hash = "1.1.0" smallvec = "1.10.0" educe = "0.4.20" taffy = "0.3.13" -rfd = { version = "0.11.4", default-features = false, features = ["xdg-portal"] } +rfd = { version = "0.11.4", default-features = false, features = [ + "xdg-portal", +] } raw-window-handle = "0.5.1" kurbo = { version = "0.9.5", features = ["serde"] } unicode-segmentation = "1.10.0" @@ -21,6 +23,7 @@ crossbeam-channel = "0.5.6" once_cell = "1.17.1" im = "15.1.0" parking_lot = { version = "0.12.1" } +dyn-clone = "1.0.14" floem_renderer = { path = "renderer" } floem_vger = { path = "vger" } floem_reactive = { path = "reactive" } diff --git a/examples/animations/src/main.rs b/examples/animations/src/main.rs index 0edd83d6..07eb64c0 100644 --- a/examples/animations/src/main.rs +++ b/examples/animations/src/main.rs @@ -31,9 +31,9 @@ fn app_view() -> impl View { s.border(1.0) .background(Color::RED) .color(Color::BLACK) - .padding_px(10.0) - .margin_px(20.0) - .size_px(120.0, 120.0) + .padding(10.0) + .margin(20.0) + .size(120.0, 120.0) }) .active_style(|s| s.color(Color::BLACK)) .animation( @@ -56,8 +56,8 @@ fn app_view() -> impl View { .style(|s| { s.border(5.0) .background(Color::BLUE) - .padding_px(10.0) - .size_px(400.0, 400.0) + .padding(10.0) + .size(400.0, 400.0) .color(Color::BLACK) }) .animation( diff --git a/examples/counter/src/main.rs b/examples/counter/src/main.rs index fa9d9c02..324e71a1 100644 --- a/examples/counter/src/main.rs +++ b/examples/counter/src/main.rs @@ -1,22 +1,25 @@ use floem::{ peniko::Color, reactive::create_signal, + style::{box_shadow, Style}, + unit::Pct, view::View, views::{label, stack, text, Decorators}, }; fn app_view() -> impl View { + let button_style = |s: Style| { + s.p(10) + .border_radius(8) + .box_shadow(box_shadow(10, 10, 8, 2, Color::rgb(0.6, 0.6, 0.6))) + }; + let (counter, set_counter) = create_signal(0); stack(( - label(move || format!("Value: {}", counter.get())).style(|s| s.padding_px(10.0)), + label(move || format!("Value: {}", counter.get())).style(|s| s.p(10)), stack(( text("Increment") - .style(|s| { - s.border_radius(10.0) - .padding_px(10.0) - .background(Color::WHITE) - .box_shadow_blur(5.0) - }) + .style(move |s| button_style(s).background(Color::WHITE)) .on_click({ move |_| { set_counter.update(|value| *value += 1); @@ -34,13 +37,7 @@ fn app_view() -> impl View { true } }) - .style(|s| { - s.box_shadow_blur(5.0) - .background(Color::WHITE) - .border_radius(10.0) - .padding_px(10.0) - .margin_left_px(10.0) - }) + .style(move |s| button_style(s).background(Color::WHITE).ml(16.0)) .hover_style(|s| s.background(Color::rgb8(244, 67, 54))) .active_style(|s| s.color(Color::WHITE).background(Color::RED)) .keyboard_navigatable() @@ -52,13 +49,7 @@ fn app_view() -> impl View { true }) .disabled(move || counter.get() == 0) - .style(|s| { - s.box_shadow_blur(5.0) - .border_radius(10.0) - .padding_px(10.0) - .margin_left_px(10.0) - .background(Color::LIGHT_BLUE) - }) + .style(move |s| button_style(s).ml(16).background(Color::LIGHT_BLUE)) .disabled_style(|s| s.background(Color::LIGHT_GRAY)) .hover_style(|s| s.background(Color::LIGHT_YELLOW)) .active_style(|s| s.color(Color::WHITE).background(Color::YELLOW_GREEN)) @@ -67,7 +58,7 @@ fn app_view() -> impl View { )), )) .style(|s| { - s.size_pct(100.0, 100.0) + s.size(Pct(100.0), Pct(100.0)) .flex_col() .items_center() .justify_center() diff --git a/examples/draggable/src/main.rs b/examples/draggable/src/main.rs index f4031651..edd7c9e0 100644 --- a/examples/draggable/src/main.rs +++ b/examples/draggable/src/main.rs @@ -9,8 +9,8 @@ fn app_view() -> impl View { .style(|s| { s.border(1.0) .border_radius(2.0) - .padding_px(10.0) - .margin_left_px(10.0) + .padding(10.0) + .margin_left(10.0) }) .hover_style(|s| { s.background(Color::rgb8(244, 67, 54)) diff --git a/examples/responsive/src/main.rs b/examples/responsive/src/main.rs index e0fd768d..bf8627b8 100644 --- a/examples/responsive/src/main.rs +++ b/examples/responsive/src/main.rs @@ -1,6 +1,7 @@ use floem::{ peniko::Color, responsive::{range, ScreenSize}, + unit::Pct, view::View, views::{label, stack, Decorators}, }; @@ -11,8 +12,8 @@ fn app_view() -> impl View { .style(|s| { s.border(1.0) .border_radius(10.0) - .padding_px(10.0) - .margin_horiz_px(10.0) + .padding(10.0) + .margin_horiz(10.0) }) .responsive_style(ScreenSize::XS, |s| s.background(Color::CYAN)) .responsive_style(ScreenSize::SM, |s| s.background(Color::PURPLE)) @@ -21,16 +22,16 @@ fn app_view() -> impl View { .responsive_style(ScreenSize::XL, |s| s.background(Color::PINK)) .responsive_style(ScreenSize::XXL, |s| s.background(Color::RED)) .responsive_style(range(ScreenSize::XS..ScreenSize::LG), |s| { - s.width_pct(90.0).max_width_px(500.0) + s.width(Pct(90.0)).max_width(500.0) }) .responsive_style( // equivalent to: range(ScreenSize::LG..) ScreenSize::LG | ScreenSize::XL | ScreenSize::XXL, - |s| s.width_px(300.0), + |s| s.width(300.0), ),) }) .style(|s| { - s.size_pct(100.0, 100.0) + s.size(Pct(100.0), Pct(100.0)) .flex_col() .justify_center() .items_center() diff --git a/examples/virtual_list/src/main.rs b/examples/virtual_list/src/main.rs index f49a2ded..533c0f4c 100644 --- a/examples/virtual_list/src/main.rs +++ b/examples/virtual_list/src/main.rs @@ -3,7 +3,7 @@ use floem::{ view::View, views::virtual_list, views::Decorators, - views::{container, label, scroll, VirtualListDirection, VirtualListItemSize}, + views::{container, label, scroll, VirtualListDirection, VirtualListItemSize}, unit::Pct, }; fn app_view() -> impl View { @@ -17,15 +17,15 @@ fn app_view() -> impl View { VirtualListItemSize::Fixed(Box::new(|| 20.0)), move || long_list.get(), move |item| *item, - move |item| label(move || item.to_string()).style(|s| s.height_px(20.0)), + move |item| label(move || item.to_string()).style(|s| s.height(20.0)), ) .style(|s| s.flex_col()), ) - .style(|s| s.width_px(100.0).height_pct(100.0).border(1.0)), + .style(|s| s.width(100.0).height(Pct(100.0)).border(1.0)), ) .style(|s| { - s.size_pct(100.0, 100.0) - .padding_vert_px(20.0) + s.size(Pct(100.0), Pct(100.0)) + .padding_vert(20.0) .flex_col() .items_center() }) diff --git a/examples/widget-gallery/src/buttons.rs b/examples/widget-gallery/src/buttons.rs index 9aaa298f..953f04fb 100644 --- a/examples/widget-gallery/src/buttons.rs +++ b/examples/widget-gallery/src/buttons.rs @@ -18,7 +18,7 @@ pub fn button_view() -> impl View { }) .keyboard_navigatable() .focus_visible_style(|s| s.border(2.).border_color(Color::BLUE)) - .style(|s| s.border(1.0).border_radius(10.0).padding_px(10.0)) + .style(|s| s.border(1.0).border_radius(10.0).padding(10.0)) }), form_item("Styled Button:".to_string(), 120.0, || { label(|| "Click me") @@ -31,8 +31,8 @@ pub fn button_view() -> impl View { .style(|s| { s.border(1.0) .border_radius(10.0) - .padding_px(10.0) - .margin_left_px(10.0) + .padding(10.0) + .margin_left(10.0) .background(Color::YELLOW_GREEN) .color(Color::DARK_GREEN) .cursor(CursorStyle::Pointer) @@ -52,7 +52,7 @@ pub fn button_view() -> impl View { .style(|s| { s.border(1.0) .border_radius(10.0) - .padding_px(10.0) + .padding(10.0) .color(Color::GRAY) }) .hover_style(|s| s.background(Color::rgb8(224, 224, 224))) @@ -65,7 +65,7 @@ pub fn button_view() -> impl View { }) .keyboard_navigatable() .focus_visible_style(|s| s.border(2.).border_color(Color::BLUE)) - .style(|s| s.border(1.0).border_radius(10.0).padding_px(10.0)) + .style(|s| s.border(1.0).border_radius(10.0).padding(10.0)) }), ) }) diff --git a/examples/widget-gallery/src/context_menu.rs b/examples/widget-gallery/src/context_menu.rs index 5d0b7f70..0fc182d2 100644 --- a/examples/widget-gallery/src/context_menu.rs +++ b/examples/widget-gallery/src/context_menu.rs @@ -8,7 +8,7 @@ pub fn menu_view() -> impl View { stack({ ( label(|| "Click me (Popout menu)") - .base_style(|s| s.padding_px(10.0).margin_bottom_px(10.0).border(1.0)) + .base_style(|s| s.padding(10.0).margin_bottom(10.0).border(1.0)) .popout_menu(|| { Menu::new("") .entry(MenuItem::new("I am a menu item!")) @@ -16,7 +16,7 @@ pub fn menu_view() -> impl View { .entry(MenuItem::new("I am another menu item")) }), label(|| "Right click me (Context menu)") - .base_style(|s| s.padding_px(10.0).border(1.0)) + .base_style(|s| s.padding(10.0).border(1.0)) .context_menu(|| { Menu::new("") .entry(MenuItem::new("Menu item")) diff --git a/examples/widget-gallery/src/form.rs b/examples/widget-gallery/src/form.rs index 96fd96ae..7a01814e 100644 --- a/examples/widget-gallery/src/form.rs +++ b/examples/widget-gallery/src/form.rs @@ -1,5 +1,6 @@ use floem::{ cosmic_text::Weight, + unit::Pct, view::View, view_tuple::ViewTuple, views::{container, label, stack, Decorators}, @@ -9,9 +10,9 @@ pub fn form(children: VT) -> impl View { stack(children).style(|s| { s.flex_col() .items_start() - .margin_px(10.0) - .padding_px(10.0) - .width_pct(100.0) + .margin(10.0) + .padding(10.0) + .width(Pct(100.0)) }) } @@ -23,7 +24,7 @@ pub fn form_item( container( stack(( container(label(move || item_label.clone()).style(|s| s.font_weight(Weight::BOLD))) - .style(move |s| s.width_px(label_width).justify_end().margin_right_px(10.0)), + .style(move |s| s.width(label_width).justify_end().margin_right(10.0)), view_fn(), )) .style(|s| s.flex_row().items_start()), @@ -31,9 +32,9 @@ pub fn form_item( .style(|s| { s.flex_row() .items_center() - .margin_bottom_px(10.0) - .padding_px(10.0) - .width_pct(100.0) - .min_height_px(32.0) + .margin_bottom(10.0) + .padding(10.0) + .width(Pct(100.0)) + .min_height(32.0) }) } diff --git a/examples/widget-gallery/src/inputs.rs b/examples/widget-gallery/src/inputs.rs index cfb4a4a8..f12beaec 100644 --- a/examples/widget-gallery/src/inputs.rs +++ b/examples/widget-gallery/src/inputs.rs @@ -15,7 +15,7 @@ pub fn text_input_view() -> impl View { ( form_item("Simple Input:".to_string(), 120.0, move || { text_input(text) - .style(|s| s.border(1.0).height_px(32.0)) + .style(|s| s.border(1.0).height(32.0)) .keyboard_navigatable() }), form_item("Styled Input:".to_string(), 120.0, move || { @@ -25,7 +25,7 @@ pub fn text_input_view() -> impl View { .background(Color::rgb8(224, 224, 224)) .border_radius(15.0) .border_color(Color::rgb8(189, 189, 189)) - .padding_px(10.0) + .padding(10.0) .cursor(CursorStyle::Text) }) .hover_style(|s| s.border_color(Color::rgb8(66, 66, 66))) @@ -39,7 +39,7 @@ pub fn text_input_view() -> impl View { .background(Color::rgb8(224, 224, 224)) .border_radius(15.0) .border_color(Color::rgb8(189, 189, 189)) - .padding_px(10.0) + .padding(10.0) .cursor(CursorStyle::Text) }) .hover_style(|s| s.border_color(Color::rgb8(66, 66, 66))) diff --git a/examples/widget-gallery/src/labels.rs b/examples/widget-gallery/src/labels.rs index ebb76062..c6809378 100644 --- a/examples/widget-gallery/src/labels.rs +++ b/examples/widget-gallery/src/labels.rs @@ -16,7 +16,7 @@ pub fn label_view() -> impl View { form_item("Styled Label:".to_string(), 120.0, || { label(move || "This is a styled label".to_owned()).style(|s| { s.background(Color::YELLOW) - .padding_px(10.0) + .padding(10.0) .color(Color::GREEN) .font_weight(Weight::BOLD) .font_style(FontStyle::Italic) diff --git a/examples/widget-gallery/src/lists.rs b/examples/widget-gallery/src/lists.rs index 689172e3..7e52ed5c 100644 --- a/examples/widget-gallery/src/lists.rs +++ b/examples/widget-gallery/src/lists.rs @@ -4,7 +4,8 @@ use floem::{ keyboard::Key, peniko::Color, reactive::create_signal, - style::{CursorStyle, Dimension, JustifyContent}, + style::{CursorStyle, JustifyContent}, + unit::Pct, view::View, views::{ checkbox, container, label, scroll, stack, virtual_list, Decorators, VirtualListDirection, @@ -32,11 +33,11 @@ fn simple_list() -> impl View { VirtualListItemSize::Fixed(Box::new(|| 20.0)), move || long_list.get(), move |item| *item, - move |item| label(move || item.to_string()).style(|s| s.height_px(24.0)), + move |item| label(move || item.to_string()).style(|s| s.height(24.0)), ) .style(|s| s.flex_col()), ) - .style(|s| s.width_px(100.0).height_px(300.0).border(1.0)) + .style(|s| s.width(100.0).height(300.0).border(1.0)) } fn enhanced_list() -> impl View { @@ -67,7 +68,7 @@ fn enhanced_list() -> impl View { true }), label(move || item.to_string()) - .style(|s| s.height_px(32.0).font_size(32.0)), + .style(|s| s.height(32.0).font_size(32.0)), container({ label(move || " X ") .on_click(move |_| { @@ -78,24 +79,24 @@ fn enhanced_list() -> impl View { true }) .style(|s| { - s.height_px(18.0) + s.height(18.0) .font_weight(Weight::BOLD) .color(Color::RED) .border(1.0) .border_color(Color::RED) .border_radius(16.0) - .margin_right_px(5.0) + .margin_right(5.0) }) .hover_style(|s| s.color(Color::WHITE).background(Color::RED)) }) .style(|s| { - s.flex_basis(Dimension::Points(0.0)) + s.flex_basis(0.0) .flex_grow(1.0) .justify_content(Some(JustifyContent::FlexEnd)) }), ) }) - .style(move |s| s.height_px(item_height).width_px(list_width).items_center()) + .style(move |s| s.height(item_height).width(list_width).items_center()) }) .on_click(move |_| { set_selected.update(|v: &mut usize| { @@ -129,8 +130,8 @@ fn enhanced_list() -> impl View { .focus_visible_style(|s| s.border(2.).border_color(Color::BLUE)) .style(move |s| { s.flex_row() - .width_pct(list_width) - .height_px(item_height) + .width(Pct(list_width)) + .height(item_height) .apply_if(index == selected.get(), |s| s.background(Color::GRAY)) .apply_if(index != 0, |s| { s.border_top(1.0).border_color(Color::LIGHT_GRAY) @@ -139,7 +140,7 @@ fn enhanced_list() -> impl View { .hover_style(|s| s.background(Color::LIGHT_GRAY).cursor(CursorStyle::Pointer)) }, ) - .style(move |s| s.flex_col().width_px(list_width)), + .style(move |s| s.flex_col().width(list_width)), ) - .style(move |s| s.width_px(list_width).height_px(300.0).border(1.0)) + .style(move |s| s.width(list_width).height(300.0).border(1.0)) } diff --git a/examples/widget-gallery/src/main.rs b/examples/widget-gallery/src/main.rs index 80a6030c..52774848 100644 --- a/examples/widget-gallery/src/main.rs +++ b/examples/widget-gallery/src/main.rs @@ -13,6 +13,7 @@ use floem::{ peniko::Color, reactive::create_signal, style::CursorStyle, + unit::Pct, view::View, views::{ container, container_box, label, scroll, stack, tab, virtual_list, Decorators, @@ -82,8 +83,8 @@ fn app_view() -> impl View { .focus_visible_style(|s| s.border(2.).border_color(Color::BLUE)) .style(move |s| { s.flex_row() - .width_pct(100.0) - .height_px(32.0) + .width(Pct(100.0)) + .height(32.0) .border_bottom(1.0) .border_color(Color::LIGHT_GRAY) .apply_if(index == active_tab.get(), |s| { @@ -95,21 +96,21 @@ fn app_view() -> impl View { }) }, ) - .style(|s| s.flex_col().width_px(140.0)) + .style(|s| s.flex_col().width(140.0)) }) .style(|s| { s.flex_col() - .width_px(140.0) - .height_pct(100.0) + .width(140.0) + .height(Pct(100.0)) .border(1.0) .border_color(Color::GRAY) }) }) .style(|s| { - s.height_pct(100.0) - .width_px(150.0) - .padding_vert_px(5.0) - .padding_horiz_px(5.0) + s.height(Pct(100.0)) + .width(150.0) + .padding_vert(5.0) + .padding_horiz(5.0) .flex_col() .items_center() }), @@ -129,18 +130,18 @@ fn app_view() -> impl View { _ => container_box(label(|| "Not implemented".to_owned())), }, ) - .style(|s| s.size_pct(100.0, 100.0)) + .style(|s| s.size(Pct(100.0), Pct(100.0))) }) .style(|s| { - s.size_pct(100.0, 100.0) - .padding_vert_px(5.0) - .padding_horiz_px(5.0) + s.size(Pct(100.0), Pct(100.0)) + .padding_vert(5.0) + .padding_horiz(5.0) .flex_col() .items_center() }), ) }) - .style(|s| s.size_pct(100.0, 100.0)) + .style(|s| s.size(Pct(100.0), Pct(100.0))) } fn main() { diff --git a/examples/window-scale/src/main.rs b/examples/window-scale/src/main.rs index ee437ce8..50ba0618 100644 --- a/examples/window-scale/src/main.rs +++ b/examples/window-scale/src/main.rs @@ -2,18 +2,18 @@ use floem::{ peniko::Color, reactive::{create_rw_signal, create_signal}, view::View, - views::{label, stack, Decorators}, + views::{label, stack, Decorators}, unit::Pct, }; fn app_view() -> impl View { let (counter, set_counter) = create_signal(0); let window_scale = create_rw_signal(1.0); stack(( - label(move || format!("Value: {}", counter.get())).style(|s| s.padding_px(10.0)), + label(move || format!("Value: {}", counter.get())).style(|s| s.padding(10.0)), stack({ ( label(|| "Increment") - .style(|s| s.border(1.0).border_radius(10.0).padding_px(10.0)) + .style(|s| s.border(1.0).border_radius(10.0).padding(10.0)) .on_click(move |_| { set_counter.update(|value| *value += 1); true @@ -30,8 +30,8 @@ fn app_view() -> impl View { .style(|s| { s.border(1.0) .border_radius(10.0) - .padding_px(10.0) - .margin_left_px(10.0) + .padding(10.0) + .margin_left(10.0) }) .hover_style(|s| s.background(Color::rgb8(244, 67, 54))) .active_style(|s| s.color(Color::WHITE).background(Color::RED)) @@ -47,8 +47,8 @@ fn app_view() -> impl View { .style(|s| { s.border(1.0) .border_radius(10.0) - .padding_px(10.0) - .margin_left_px(10.0) + .padding(10.0) + .margin_left(10.0) .background(Color::LIGHT_BLUE) }) .disabled_style(|s| s.background(Color::LIGHT_GRAY)) @@ -68,9 +68,9 @@ fn app_view() -> impl View { .style(|s| { s.border(1.0) .border_radius(10.0) - .margin_top_px(10.0) - .margin_right_px(10.0) - .padding_px(10.0) + .margin_top(10.0) + .margin_right(10.0) + .padding(10.0) }) .hover_style(|s| s.background(Color::LIGHT_GREEN)), label(|| "Zoom Out") @@ -81,9 +81,9 @@ fn app_view() -> impl View { .style(|s| { s.border(1.0) .border_radius(10.0) - .margin_top_px(10.0) - .margin_right_px(10.0) - .padding_px(10.0) + .margin_top(10.0) + .margin_right(10.0) + .padding(10.0) }) .hover_style(|s| s.background(Color::LIGHT_GREEN)), label(|| "Zoom Reset") @@ -95,9 +95,9 @@ fn app_view() -> impl View { .style(|s| { s.border(1.0) .border_radius(10.0) - .margin_top_px(10.0) - .margin_right_px(10.0) - .padding_px(10.0) + .margin_top(10.0) + .margin_right(10.0) + .padding(10.0) }) .hover_style(|s| s.background(Color::LIGHT_GREEN)) .disabled_style(|s| s.background(Color::LIGHT_GRAY)), @@ -105,14 +105,14 @@ fn app_view() -> impl View { }) .style(|s| { s.absolute() - .size_pct(100.0, 100.0) + .size(Pct(100.0), Pct(100.0)) .items_start() .justify_end() }), )) .window_scale(move || window_scale.get()) .style(|s| { - s.size_pct(100.0, 100.0) + s.size(Pct(100.0), Pct(100.0)) .flex_col() .items_center() .justify_center() diff --git a/src/context.rs b/src/context.rs index e2acf788..daaf7149 100644 --- a/src/context.rs +++ b/src/context.rs @@ -23,7 +23,7 @@ use crate::{ menu::Menu, pointer::PointerInputEvent, responsive::{GridBreakpoints, ScreenSize, ScreenSizeBp}, - style::{ComputedStyle, CursorStyle, Style, StyleSelector}, + style::{CursorStyle, Style, StyleFn, StyleSelector}, }; pub type EventCallback = dyn Fn(&Event) -> bool; @@ -48,17 +48,18 @@ pub struct ViewState { pub(crate) viewport: Option, pub(crate) layout_rect: Rect, pub(crate) animation: Option, - pub(crate) base_style: Option