diff --git a/Cargo.toml b/Cargo.toml index 518062a..4f76243 100644 --- a/Cargo.toml +++ b/Cargo.toml @@ -119,7 +119,7 @@ opt-level = 2 [profile.dev.package.puffin] opt-level = 2 -[profile.dev.package.puffin_server] +[profile.dev.package.puffin_http] opt-level = 2 [profile.dev.package.cosmic-text] @@ -129,4 +129,5 @@ opt-level = 2 palette = { git = "https://github.com/Ogeon/palette" } [profile.release] -debug = true +opt-level = 2 +# debug = true diff --git a/README.md b/README.md index c1f275d..2bbd393 100644 --- a/README.md +++ b/README.md @@ -10,8 +10,12 @@ useState hooks. ## [Live Demo](https://ten3roberts.github.io/violet/demo) ## Example + +![image](https://github.com/ten3roberts/violet/assets/25723553/b9882e28-9e4b-49be-8dcc-9c12d42e12b1) + ```rust let name = Mutable::new("".to_string()); +let quest = Mutable::new("".to_string()); let color = Mutable::new(Srgba::new(0.0, 0.61, 0.388, 1.0)); // Map a `Mutable` into a `StateDuplex` for each field @@ -23,8 +27,9 @@ let speed = Mutable::new(None as Option); col(( card(row((label("What is your name?"), TextInput::new(name)))), + card(row((label("What is your quest?"), TextInput::new(quest)))), card(col(( - label("What is your favorite color?"), + label("What is your favorite colour?"), SliderWithLabel::new(r, 0.0, 1.0).round(0.01), SliderWithLabel::new(g, 0.0, 1.0).round(0.01), SliderWithLabel::new(b, 0.0, 1.0).round(0.01), @@ -45,16 +50,16 @@ col(( StreamWidget(speed.stream().map(|v| { match v { Some(v) => pill(Text::new(format!("{v} m/s"))), - None => pill(Text::new("×".to_string())) - .with_background(Background::new(danger_background())), + None => pill(Text::rich([ + TextSegment::new("×").with_weight(violet::core::text::Weight::BOLD) + ])) + .with_background(danger_surface()), } })), ))), )) ``` -![image](https://github.com/ten3roberts/violet/assets/25723553/10e76b9a-8f2d-4b74-aaa7-b9faf04a22dc) - ## Features - Declarative Widgets and reactive state - Flexible layout system for responsive layouts diff --git a/colors.json b/colors.json index 35697ce..a1029c7 100644 --- a/colors.json +++ b/colors.json @@ -78,17 +78,17 @@ "950": "#28100e" }, "amber": { - "50": "#f5e7c6", - "100": "#ead9b2", - "200": "#d6bf86", - "300": "#c6a349", - "400": "#b88700", - "500": "#a46c00", - "600": "#865600", - "700": "#644400", - "800": "#463200", - "900": "#2c2000", - "950": "#211700" + "50": "#f7e6c3", + "100": "#ecd9af", + "200": "#d9be80", + "300": "#caa13e", + "400": "#be8400", + "500": "#aa6800", + "600": "#8b5300", + "700": "#684200", + "800": "#493100", + "900": "#2e1f00", + "950": "#221600" }, "rose": { "50": "#fddeeb", diff --git a/colors.save.json b/colors.save.json index 219338d..3a855d4 100644 --- a/colors.save.json +++ b/colors.save.json @@ -55,9 +55,9 @@ }, { "color": { - "l": 0.50735986, - "chroma": 0.185, - "hue": 88.0 + "l": 0.83, + "chroma": 0.2, + "hue": 86.046814 }, "falloff": 15.0, "name": "Amber" diff --git a/examples/basic.rs b/examples/basic.rs index 63feaa8..9ce221d 100644 --- a/examples/basic.rs +++ b/examples/basic.rs @@ -17,5 +17,5 @@ pub fn main() -> anyhow::Result<()> { violet_wgpu::AppBuilder::new() .with_renderer_config(RendererConfig { debug_mode: false }) - .run(violet_demo::basic::app()) + .run(violet_demo::bridge_of_death::app()) } diff --git a/examples/buttons.rs b/examples/buttons.rs index 7563ed0..be1f226 100644 --- a/examples/buttons.rs +++ b/examples/buttons.rs @@ -15,7 +15,7 @@ use violet::core::{ Scope, Widget, }; use violet_core::{ - style::{self, primary_background, secondary_background, spacing_small, Background, SizeExt}, + style::{self, primary_surface, secondary_surface, spacing_small, Background, SizeExt}, text::Wrap, widget::{card, col, label, row, Button, ButtonStyle, SliderWithLabel, TextInput}, }; @@ -61,21 +61,21 @@ impl Widget for MainApp { col(( Button::label("Button"), Button::label("Button").with_style(ButtonStyle { - normal_color: style::success_item().into(), + normal_color: style::success_element().into(), ..Default::default() }), Button::label("Warning").with_style(ButtonStyle { - normal_color: style::warning_item().into(), + normal_color: style::warning_element().into(), ..Default::default() }), Button::label("Error").with_style(ButtonStyle { - normal_color: style::danger_item().into(), + normal_color: style::danger_element().into(), ..Default::default() }), )) .with_stretch(true), ), - Rectangle::new(secondary_background()) + Rectangle::new(secondary_surface()) .with_size(Unit::rel2(1.0, 0.0) + Unit::px2(0.0, 1.0)), card(col(( col(( @@ -103,7 +103,7 @@ impl Widget for MainApp { .map(|color| Tints { color }) .collect_vec()), )) - .with_background(Background::new(primary_background())) + .with_background(Background::new(primary_surface())) .contain_margins(true) .mount(scope) } diff --git a/examples/counter.rs b/examples/counter.rs index 1b49052..6bdec70 100644 --- a/examples/counter.rs +++ b/examples/counter.rs @@ -11,7 +11,7 @@ use violet::core::{ widget::{Button, List, SignalWidget, Stack, Text}, Scope, Widget, }; -use violet_core::style::{accent_item, secondary_background, spacing_small, Background, SizeExt}; +use violet_core::style::{accent_element, secondary_surface, spacing_small, Background, SizeExt}; macro_rules! srgba { ($color:literal) => {{ @@ -34,7 +34,7 @@ pub const CHILI_RED: Srgba = srgba!("#d34131"); fn pill(widget: impl Widget) -> impl Widget { Stack::new(widget) - .with_background(Background::new(secondary_background())) + .with_background(Background::new(secondary_surface())) .with_margin(spacing_small()) .with_padding(spacing_small()) } @@ -60,7 +60,7 @@ impl Widget for MainApp { "Please click the button to increment the counter", )), )) - .with_background(Background::new(accent_item())) + .with_background(Background::new(accent_element())) .with_cross_align(Alignment::Center) .mount(scope); } diff --git a/examples/flow.rs b/examples/flow.rs index e9dba00..e99931e 100644 --- a/examples/flow.rs +++ b/examples/flow.rs @@ -7,7 +7,6 @@ use violet::core::{ widget::{col, row, Button}, Edges, Widget, }; -use violet_core::unit::Unit; use violet_wgpu::renderer::RendererConfig; pub fn main() -> anyhow::Result<()> { diff --git a/examples/offset.rs b/examples/offset.rs index 4f4aa85..408fe6a 100644 --- a/examples/offset.rs +++ b/examples/offset.rs @@ -3,7 +3,7 @@ use tracing_subscriber::{ }; use tracing_tree::HierarchicalLayer; use violet::core::{ - style::{colors::EMERALD_500, secondary_background, spacing_medium, Background, SizeExt}, + style::{colors::EMERALD_500, secondary_surface, spacing_medium, Background, SizeExt}, unit::Unit, widget::{Positioned, Rectangle, Stack}, Widget, @@ -33,5 +33,5 @@ fn app() -> impl Widget { .with_offset(Unit::px2(10.0, 10.0)), ) .with_padding(spacing_medium()) - .with_background(Background::new(secondary_background())) + .with_background(Background::new(secondary_surface())) } diff --git a/examples/row.rs b/examples/row.rs index 86643a4..9a5820c 100644 --- a/examples/row.rs +++ b/examples/row.rs @@ -5,7 +5,7 @@ use tracing_tree::HierarchicalLayer; use violet::core::{style::Background, unit::Unit, widget::Rectangle, Scope, Widget}; use violet_core::{ - style::{accent_item, primary_background, spacing_small, SizeExt}, + style::{accent_element, primary_surface, spacing_small, SizeExt}, widget::{centered, col, row, Image, Stack}, }; use violet_wgpu::renderer::RendererConfig; @@ -57,7 +57,7 @@ impl Widget for MainApp { row((0..4) .map(|_| Box::new(Stack::new(Item)) as Box) .chain([Box::new( - centered((Rectangle::new(accent_item()) + centered((Rectangle::new(accent_element()) .with_maximize(vec2(1.0, 0.0)) .with_size(Unit::px2(0.0, 50.0)) .with_max_size(Unit::px2(1000.0, 100.0)),)) @@ -69,7 +69,7 @@ impl Widget for MainApp { // .with_padding(spacing_medium()) .contain_margins(true), ) - .with_background(Background::new(primary_background())) + .with_background(Background::new(primary_surface())) .mount(scope) } } diff --git a/examples/scroll.rs b/examples/scroll.rs index 7a73c92..3471aca 100644 --- a/examples/scroll.rs +++ b/examples/scroll.rs @@ -2,7 +2,7 @@ use futures::StreamExt; use futures_signals::signal::Mutable; use glam::{BVec2, Vec2}; use itertools::Itertools; -use palette::{Hsl, Hsv, IntoColor, Oklcha, Srgba}; +use palette::{Hsv, IntoColor, Oklcha, Srgba}; use tracing_subscriber::{ prelude::__tracing_subscriber_SubscriberExt, registry, util::SubscriberInitExt, EnvFilter, }; @@ -15,7 +15,7 @@ use violet::core::{ }; use violet_core::{ state::{State, StateStream}, - style::{secondary_background, spacing_medium, Background}, + style::{secondary_surface, spacing_medium, Background}, utils::zip_latest, widget::{label, Button, Checkbox, ScrollArea, SliderWithLabel, StreamWidget, WidgetExt}, }; @@ -88,6 +88,6 @@ fn app() -> impl Widget { Button::label("Button"), )) .with_padding(spacing_medium()) - .with_background(Background::new(secondary_background())) + .with_background(Background::new(secondary_surface())) // .with_padding(spacing_medium()) } diff --git a/examples/sizing.rs b/examples/sizing.rs index de34b85..81527b2 100644 --- a/examples/sizing.rs +++ b/examples/sizing.rs @@ -13,16 +13,14 @@ use violet::core::{ text::Wrap, unit::Unit, widget::{card, centered, col, label, row, Rectangle, SignalWidget, Slider, Text, WidgetExt}, - Edges, Scope, Widget, + Scope, Widget, }; use violet_core::style::{ colors::{AMBER_500, EMERALD_500, EMERALD_800, REDWOOD_500, TEAL_500}, - primary_background, + primary_surface, }; use violet_wgpu::renderer::RendererConfig; -const MARGIN_SM: Edges = Edges::even(4.0); - pub fn main() -> anyhow::Result<()> { registry() .with( @@ -86,7 +84,7 @@ impl Widget for MainApp { // AnimatedSize, )) .contain_margins(true) - .with_background(Background::new(primary_background())) + .with_background(Background::new(primary_surface())) .mount(scope) } } diff --git a/violet-core/src/components.rs b/violet-core/src/components.rs index 41fd0fe..0a10153 100644 --- a/violet-core/src/components.rs +++ b/violet-core/src/components.rs @@ -1,6 +1,5 @@ use std::time::Duration; -use cosmic_text::LayoutLine; use flax::{component, Debuggable, Entity, EntityRef, Exclusive}; use glam::{Mat4, Vec2}; use image::DynamicImage; @@ -8,7 +7,7 @@ use palette::Srgba; use crate::{ assets::Asset, - layout::{Layout, LayoutArgs, LayoutLimits, SizeResolver}, + layout::{Layout, LayoutArgs, SizeResolver}, stored::UntypedHandle, text::{LayoutGlyphs, TextSegment, Wrap}, unit::Unit, diff --git a/violet-core/src/layout/flow.rs b/violet-core/src/layout/flow.rs index fd48fd9..1b09e8c 100644 --- a/violet-core/src/layout/flow.rs +++ b/violet-core/src/layout/flow.rs @@ -2,7 +2,6 @@ use std::sync::Arc; use flax::{Entity, EntityRef, World}; use glam::{vec2, BVec2, Vec2}; -use image::flat::NormalForm; use itertools::Itertools; use crate::{ @@ -100,21 +99,6 @@ impl QueryCursor { (placement_pos, cross_size) } - fn rect(&self) -> Rect { - let cross_cursor = self.cross_cursor + self.cross_size; - - let main_cursor = if self.contain_margins { - self.main_cursor + self.pending_margin - } else { - self.main_cursor - }; - - Rect::from_two_points( - self.start, - main_cursor * self.axis + cross_cursor * self.cross_axis, - ) - } - /// Finishes the current line and moves the cursor to the next fn finish(&mut self) -> Rect { self.cross_cursor += self.cross_size; @@ -203,7 +187,7 @@ impl AlignCursor { self.main_cursor += advance; // + block.rect.support(-self.axis); // Cross axis margin calculation - let (start_margin, end_margin) = block.margin.in_axis(self.cross_axis); + let (start_margin, _) = block.margin.in_axis(self.cross_axis); let placement_pos; @@ -259,21 +243,6 @@ impl AlignCursor { placement_pos } - fn rect(&self) -> Rect { - let cross_cursor = self.cross_cursor + self.cross_size; - - let main_cursor = if self.contain_margins { - self.main_cursor + self.pending_margin - } else { - self.main_cursor - }; - - Rect::from_two_points( - self.start, - main_cursor * self.axis + cross_cursor * self.cross_axis, - ) - } - /// Finishes the current line and moves the cursor to the next fn finish(&mut self) -> Rect { self.cross_cursor += self.cross_size; @@ -702,7 +671,6 @@ impl FlowLayout { min_cursor.put(&Block::new(sizing.min, sizing.margin, sizing.hints.can_grow)); cursor.put(&Block::new(sizing.preferred, sizing.margin, sizing.hints.can_grow)); - tracing::debug!(min_cursor=%min_cursor.rect().size(), cursor=%cursor.rect().size(), "cursor"); sizing }).collect_vec(); @@ -753,7 +721,7 @@ impl FlowLayout { puffin::profile_function!(); if let Some(value) = cache.query_row.as_ref() { if validate_cached_row(value, args.limits, args.content_area) { - // return value.value.clone(); + return value.value.clone(); } } diff --git a/violet-core/src/layout/mod.rs b/violet-core/src/layout/mod.rs index 84b8eef..1804aeb 100644 --- a/violet-core/src/layout/mod.rs +++ b/violet-core/src/layout/mod.rs @@ -13,7 +13,7 @@ use crate::{ self, anchor, aspect_ratio, children, layout, max_size, maximize, min_size, offset, padding, size, size_resolver, }, - layout::cache::{validate_cached_layout, validate_cached_query, CachedValue}, + layout::cache::{validate_cached_layout, validate_cached_query, CachedValue, LAYOUT_TOLERANCE}, Edges, Rect, }; @@ -484,7 +484,7 @@ pub(crate) fn apply_layout(world: &World, entity: &EntityRef, args: LayoutArgs) let resolved_size = resolved_size.clamp(limits.min_size, limits.max_size); let mut block = if let Some(layout) = layout { - let mut block = layout.apply( + let block = layout.apply( world, entity, cache, @@ -554,7 +554,9 @@ pub(crate) fn apply_layout(world: &World, entity: &EntityRef, args: LayoutArgs) .update_dedup(components::layout_args(), args) .unwrap(); - if args.overflow_limit.x < block.rect.size().x || args.overflow_limit.y < block.rect.size().y { + if block.rect.size().x > args.overflow_limit.x + LAYOUT_TOLERANCE + || block.rect.size().y > args.overflow_limit.y + LAYOUT_TOLERANCE + { tracing::warn!( %entity, size=%block.rect.size(), diff --git a/violet-core/src/style/colors.rs b/violet-core/src/style/colors.rs index 0dfad56..758d08e 100644 --- a/violet-core/src/style/colors.rs +++ b/violet-core/src/style/colors.rs @@ -67,17 +67,17 @@ pub const REDWOOD_700: Srgba = srgba!("#79302a"); pub const REDWOOD_800: Srgba = srgba!("#542521"); pub const REDWOOD_900: Srgba = srgba!("#361815"); pub const REDWOOD_950: Srgba = srgba!("#28100e"); -pub const AMBER_50: Srgba = srgba!("#f5e7c6"); -pub const AMBER_100: Srgba = srgba!("#ead9b2"); -pub const AMBER_200: Srgba = srgba!("#d6bf86"); -pub const AMBER_300: Srgba = srgba!("#c6a349"); -pub const AMBER_400: Srgba = srgba!("#b88700"); -pub const AMBER_500: Srgba = srgba!("#a46c00"); -pub const AMBER_600: Srgba = srgba!("#865600"); -pub const AMBER_700: Srgba = srgba!("#644400"); -pub const AMBER_800: Srgba = srgba!("#463200"); -pub const AMBER_900: Srgba = srgba!("#2c2000"); -pub const AMBER_950: Srgba = srgba!("#211700"); +pub const AMBER_50: Srgba = srgba!("#f7e6c3"); +pub const AMBER_100: Srgba = srgba!("#ecd9af"); +pub const AMBER_200: Srgba = srgba!("#d9be80"); +pub const AMBER_300: Srgba = srgba!("#caa13e"); +pub const AMBER_400: Srgba = srgba!("#be8400"); +pub const AMBER_500: Srgba = srgba!("#aa6800"); +pub const AMBER_600: Srgba = srgba!("#8b5300"); +pub const AMBER_700: Srgba = srgba!("#684200"); +pub const AMBER_800: Srgba = srgba!("#493100"); +pub const AMBER_900: Srgba = srgba!("#2e1f00"); +pub const AMBER_950: Srgba = srgba!("#221600"); pub const ROSE_50: Srgba = srgba!("#fddeeb"); pub const ROSE_100: Srgba = srgba!("#f3cfde"); pub const ROSE_200: Srgba = srgba!("#e2b1c6"); diff --git a/violet-core/src/style/mod.rs b/violet-core/src/style/mod.rs index c625e5c..ffc33f1 100644 --- a/violet-core/src/style/mod.rs +++ b/violet-core/src/style/mod.rs @@ -278,17 +278,17 @@ pub fn setup_stylesheet() -> EntityBuilder { builder // colors - .set(primary_background(), STONE_950) - .set(primary_item(), PLATINUM_100) - .set(secondary_background(), STONE_900) - .set(accent_background(), PLATINUM_800) - .set(accent_item(), EMERALD_500) - .set(success_background(), EMERALD_800) - .set(success_item(), EMERALD_500) - .set(warning_background(), AMBER_800) - .set(warning_item(), AMBER_500) - .set(danger_background(), REDWOOD_800) - .set(danger_item(), REDWOOD_400) + .set(primary_surface(), STONE_950) + .set(primary_element(), PLATINUM_100) + .set(secondary_surface(), STONE_900) + .set(accent_surface(), PLATINUM_800) + .set(accent_element(), EMERALD_500) + .set(success_surface(), EMERALD_800) + .set(success_element(), EMERALD_500) + .set(warning_surface(), AMBER_800) + .set(warning_element(), AMBER_500) + .set(danger_surface(), REDWOOD_800) + .set(danger_element(), REDWOOD_500) .set(interactive_active(), EMERALD_500) .set(interactive_passive(), ZINC_800) .set(interactive_hover(), EMERALD_400) @@ -309,24 +309,24 @@ pub fn setup_stylesheet() -> EntityBuilder { flax::component! { pub stylesheet(id): () => [ Exclusive ], /// The primary surface color - pub primary_background: Srgba, - pub primary_item: Srgba, + pub primary_surface: Srgba, + pub primary_element: Srgba, /// Used for secondary surfaces, such as card backgrounds - pub secondary_background: Srgba, + pub secondary_surface: Srgba, pub secondary_item: Srgba, - pub accent_background: Srgba, - pub accent_item: Srgba, + pub accent_surface: Srgba, + pub accent_element: Srgba, - pub success_background: Srgba, - pub success_item: Srgba, + pub success_surface: Srgba, + pub success_element: Srgba, - pub warning_background: Srgba, - pub warning_item: Srgba, + pub warning_surface: Srgba, + pub warning_element: Srgba, - pub danger_background: Srgba, - pub danger_item: Srgba, + pub danger_surface: Srgba, + pub danger_element: Srgba, /// Used for the main parts of interactive elements diff --git a/violet-core/src/systems.rs b/violet-core/src/systems.rs index 520766b..ed7b8c6 100644 --- a/violet-core/src/systems.rs +++ b/violet-core/src/systems.rs @@ -10,10 +10,9 @@ use flax::{ components::child_of, entity_ids, events::{EventData, EventSubscriber}, - fetch::entity_refs, filter::Or, - BoxedSystem, CommandBuffer, Dfs, DfsBorrow, Entity, EntityBuilder, EntityRef, Fetch, FetchExt, - FetchItem, Query, QueryBorrow, System, World, + BoxedSystem, CommandBuffer, Dfs, DfsBorrow, Entity, EntityBuilder, Fetch, FetchExt, FetchItem, + Query, QueryBorrow, System, World, }; use glam::{Mat4, Vec2, Vec3, Vec3Swizzles}; @@ -194,7 +193,6 @@ pub fn transform_system(root: Entity) -> BoxedSystem { System::builder() .with_query( Query::new(( - entity_refs(), screen_transform().as_mut(), screen_clip_mask().as_mut(), clip_mask(), @@ -207,8 +205,7 @@ pub fn transform_system(root: Entity) -> BoxedSystem { query.traverse_from( root, &(Mat4::IDENTITY, Rect::new(Vec2::MIN, Vec2::MAX)), - |(entity, screen_trans, screen_mask, &mask, &local_pos, &trans): ( - EntityRef, + |(screen_trans, screen_mask, &mask, &local_pos, &trans): ( &mut Mat4, &mut Rect, &Rect, @@ -222,8 +219,6 @@ pub fn transform_system(root: Entity) -> BoxedSystem { let mask_offset = parent.transform_point3(Vec3::ZERO).xy(); *screen_mask = mask.translate(mask_offset).intersect(parent_mask); - // tracing::info!(%entity, %screen_mask); - *screen_trans = parent * local_transform; (*screen_trans, *screen_mask) diff --git a/violet-core/src/widget/container.rs b/violet-core/src/widget/container.rs index f51fac1..4ace295 100644 --- a/violet-core/src/widget/container.rs +++ b/violet-core/src/widget/container.rs @@ -8,7 +8,7 @@ use crate::{ layout::{Alignment, Direction, FloatLayout, FlowLayout, Layout, StackLayout}, scope::ScopeRef, style::{ - primary_background, secondary_background, spacing_medium, spacing_small, Background, + primary_surface, secondary_surface, spacing_medium, spacing_small, Background, SizeExt, StyleExt, WidgetSize, }, unit::Unit, @@ -282,7 +282,7 @@ pub fn centered(widget: W) -> Stack { pub fn card(widget: W) -> Stack { Stack::new(widget) // TODO: semantic color and sizing increment - .with_background(Background::new(secondary_background())) + .with_background(Background::new(secondary_surface())) .with_padding(spacing_medium()) .with_margin(spacing_medium()) } @@ -290,7 +290,7 @@ pub fn card(widget: W) -> Stack { pub fn pill(widget: W) -> Stack { Stack::new(widget) // TODO: semantic color and sizing increment - .with_background(Background::new(primary_background())) + .with_background(Background::new(primary_surface())) .with_padding(spacing_small()) .with_margin(spacing_small()) } diff --git a/violet-core/src/widget/interactive/button.rs b/violet-core/src/widget/interactive/button.rs index ab81b39..7d91b97 100644 --- a/violet-core/src/widget/interactive/button.rs +++ b/violet-core/src/widget/interactive/button.rs @@ -8,8 +8,8 @@ use crate::{ scope::ScopeRef, state::{StateDuplex, StateStream, WatchState}, style::{ - danger_item, interactive_passive, interactive_pressed, spacing_medium, success_item, - warning_item, Background, SizeExt, StyleExt, ValueOrRef, WidgetSize, + danger_element, interactive_passive, interactive_pressed, spacing_medium, success_element, + warning_element, Background, SizeExt, StyleExt, ValueOrRef, WidgetSize, }, unit::Unit, widget::{ContainerStyle, Stack, Text}, @@ -67,17 +67,17 @@ impl Button { } pub fn success(mut self) -> Self { - self.style.normal_color = success_item().into(); + self.style.normal_color = success_element().into(); self } pub fn danger(mut self) -> Self { - self.style.normal_color = danger_item().into(); + self.style.normal_color = danger_element().into(); self } pub fn warning(mut self) -> Self { - self.style.normal_color = warning_item().into(); + self.style.normal_color = warning_element().into(); self } } diff --git a/violet-demo/Cargo.toml b/violet-demo/Cargo.toml index 0213a45..d829f45 100644 --- a/violet-demo/Cargo.toml +++ b/violet-demo/Cargo.toml @@ -40,3 +40,7 @@ heck.workspace = true [package.metadata.wasm-pack.profile.profiling] wasm-opt = false + + +[package.metadata.wasm-pack.profile.release] +wasm-opt = ['-O4'] diff --git a/violet-demo/src/basic.rs b/violet-demo/src/bridge_of_death.rs similarity index 87% rename from violet-demo/src/basic.rs rename to violet-demo/src/bridge_of_death.rs index 8d42b48..3814edc 100644 --- a/violet-demo/src/basic.rs +++ b/violet-demo/src/bridge_of_death.rs @@ -3,7 +3,8 @@ use glam::Vec2; use violet::{ core::{ state::{State, StateStream}, - style::{danger_background, Background, SizeExt}, + style::{danger_surface, SizeExt}, + text::TextSegment, unit::Unit, widget::{ card, col, label, pill, row, Rectangle, SliderWithLabel, StreamWidget, Text, TextInput, @@ -51,8 +52,10 @@ pub fn app() -> impl Widget { StreamWidget(speed.stream().map(|v| { match v { Some(v) => pill(Text::new(format!("{v} m/s"))), - None => pill(Text::new("×".to_string())) - .with_background(Background::new(danger_background())), + None => pill(Text::rich([ + TextSegment::new("×").with_weight(violet::core::text::Weight::BOLD) + ])) + .with_background(danger_surface()), } })), ))), diff --git a/violet-demo/src/lib.rs b/violet-demo/src/lib.rs index 216d219..c4af1ef 100644 --- a/violet-demo/src/lib.rs +++ b/violet-demo/src/lib.rs @@ -3,7 +3,7 @@ use glam::Vec2; use violet::{ core::{ state::{State, StateStream}, - style::{accent_background, spacing_small, SizeExt}, + style::{accent_surface, SizeExt}, widget::{col, row, Radio, StreamWidget, WidgetExt}, Widget, }, @@ -12,7 +12,7 @@ use violet::{ }; use wasm_bindgen_futures::wasm_bindgen; -pub mod basic; +pub mod bridge_of_death; mod palettes; #[cfg(target_arch = "wasm32")] @@ -41,6 +41,8 @@ fn setup() { #[cfg(not(target_arch = "wasm32"))] fn setup() { + use tracing_subscriber::{layer::SubscriberExt, util::SubscriberInitExt}; + tracing_subscriber::registry() .with( tracing_tree::HierarchicalLayer::default() @@ -88,11 +90,10 @@ fn app() -> impl Widget { ), ), )) - .with_background(accent_background())) - .with_maximize(Vec2::X) - .with_padding(spacing_small()), + .with_background(accent_surface())) + .with_maximize(Vec2::X), StreamWidget(state.stream().map(|v| match v { - DemoState::Basic => basic::app().boxed(), + DemoState::Basic => bridge_of_death::app().boxed(), DemoState::PaletteEditor => palettes::App.boxed(), })), )) diff --git a/violet-demo/src/palettes/mod.rs b/violet-demo/src/palettes/mod.rs index b0aff94..9a1bcfb 100644 --- a/violet-demo/src/palettes/mod.rs +++ b/violet-demo/src/palettes/mod.rs @@ -11,7 +11,7 @@ use violet::{ layout::Alignment, state::{State, StateMut, StateStream, StateStreamRef}, style::{ - danger_item, primary_background, success_item, warning_item, Background, SizeExt, + danger_element, primary_surface, success_element, warning_element, Background, SizeExt, ValueOrRef, }, time::{interval, sleep}, @@ -63,7 +63,7 @@ impl Widget for App { .with_horizontal_alignment(Alignment::End), )) .with_size(Unit::rel2(1.0, 1.0)) - .with_background(Background::new(primary_background())) + .with_background(Background::new(primary_surface())) .mount(scope); } } @@ -241,6 +241,7 @@ struct Notification { kind: NotificationKind, } +#[allow(dead_code)] pub enum NotificationKind { Info, Warning, @@ -251,12 +252,6 @@ pub struct Notifications { items: S, } -impl Notifications { - pub fn new(items: S) -> Self { - Self { items } - } -} - impl Widget for Notifications where S: 'static + Stream, @@ -269,9 +264,9 @@ where .iter() .map(|(_, v): &(f32, Notification)| { let color = match v.kind { - NotificationKind::Info => success_item(), - NotificationKind::Warning => warning_item(), - NotificationKind::Error => danger_item(), + NotificationKind::Info => success_element(), + NotificationKind::Warning => warning_element(), + NotificationKind::Error => danger_element(), }; card(label(v.message.clone())).with_background(Background::new(color)) }) diff --git a/violet-wgpu/src/app.rs b/violet-wgpu/src/app.rs index 9e066eb..1be4a8c 100644 --- a/violet-wgpu/src/app.rs +++ b/violet-wgpu/src/app.rs @@ -19,14 +19,14 @@ use violet_core::{ executor::Executor, input::InputState, io::{self, Clipboard}, - style::{primary_background, setup_stylesheet, stylesheet, Background, SizeExt}, + style::{primary_surface, setup_stylesheet, stylesheet, Background, SizeExt}, systems::{ hydrate_text, invalidate_cached_layout_system, layout_system, templating_system, transform_system, }, to_owned, unit::Unit, - widget::{col, Stack}, + widget::{col, WidgetExt}, Frame, FutureEffect, Rect, Scope, Widget, }; @@ -51,12 +51,13 @@ impl Widget for Canvas { .set(max_size(), Unit::px(self.size)) .set(size(), Unit::px(self.size)); - scope.attach(Stack::new( + scope.attach( col(self.root) .contain_margins(true) .with_maximize(Vec2::ONE) - .with_background(Background::new(primary_background())), - )); + .with_background(Background::new(primary_surface())) + .with_name("CanvasColumn"), + ); } } @@ -211,7 +212,7 @@ impl AppBuilder { renderer: None, root, scale_factor: window.scale_factor(), - stats: AppStats::new(60), + stats: AppStats::new(16), current_time: start_time, start_time, executor, @@ -436,7 +437,7 @@ impl Default for AppBuilder { } } -struct AppStats { +pub struct AppStats { frames: Vec, max_frames: usize, } @@ -456,7 +457,7 @@ impl AppStats { self.frames.push(AppFrame { frame_time }); } - fn report(&self) -> StatsReport { + pub fn report(&self) -> StatsReport { let average = self .frames .iter() diff --git a/violet-wgpu/src/renderer/debug_renderer.rs b/violet-wgpu/src/renderer/debug_renderer.rs index 3dcd4bc..459ffee 100644 --- a/violet-wgpu/src/renderer/debug_renderer.rs +++ b/violet-wgpu/src/renderer/debug_renderer.rs @@ -2,10 +2,8 @@ use std::{collections::BTreeMap, sync::Arc}; use flax::{fetch::entity_refs, Entity, Query}; use glam::{vec2, vec3, vec4, Mat4, Quat, Vec2, Vec3, Vec4}; -use image::DynamicImage; use itertools::Itertools; use violet_core::{ - assets::Asset, components::{layout_args, rect, screen_clip_mask, screen_transform}, layout::{ cache::{layout_cache, LayoutUpdate}, @@ -28,10 +26,7 @@ use crate::{ use super::{rect_renderer::ImageFromColor, DrawCommand, ObjectData, RendererProps, RendererStore}; pub struct DebugRenderer { - white_image: Asset, - layout: BindGroupLayout, bind_group: Handle, - sampler: wgpu::Sampler, mesh: Arc, @@ -121,10 +116,7 @@ impl DebugRenderer { )); Self { - white_image, - layout, bind_group, - sampler, mesh, corner_shader, border_shader, diff --git a/violet-wgpu/src/renderer/rect_renderer.rs b/violet-wgpu/src/renderer/rect_renderer.rs index 080c54e..8621cfc 100644 --- a/violet-wgpu/src/renderer/rect_renderer.rs +++ b/violet-wgpu/src/renderer/rect_renderer.rs @@ -8,7 +8,7 @@ use flax::{ use glam::{vec2, vec3, Mat4, Quat, Vec2, Vec4}; use image::{DynamicImage, ImageBuffer}; use palette::Srgba; -use wgpu::{BindGroup, BindGroupLayout, SamplerDescriptor, ShaderStages, TextureFormat}; +use wgpu::{BindGroup, BindGroupLayout, SamplerDescriptor, ShaderStages}; use violet_core::{ assets::{map::HandleMap, Asset, AssetCache, AssetKey}, diff --git a/violet-wgpu/src/renderer/window_renderer.rs b/violet-wgpu/src/renderer/window_renderer.rs index 20a526d..3a76e61 100644 --- a/violet-wgpu/src/renderer/window_renderer.rs +++ b/violet-wgpu/src/renderer/window_renderer.rs @@ -5,7 +5,7 @@ use flax::Entity; use glam::Mat4; use parking_lot::Mutex; use puffin::profile_scope; -use wgpu::{BindGroupLayout, Operations, RenderPassDescriptor, StoreOp, SurfaceError}; +use wgpu::{Operations, RenderPassDescriptor, StoreOp, SurfaceError}; use winit::dpi::{LogicalSize, PhysicalSize}; use violet_core::{layout::cache::LayoutUpdate, Frame}; diff --git a/violet-wgpu/src/text.rs b/violet-wgpu/src/text.rs index 4d79102..f645f9d 100644 --- a/violet-wgpu/src/text.rs +++ b/violet-wgpu/src/text.rs @@ -237,14 +237,6 @@ impl TextBufferState { ); } - fn text(&self) -> Vec { - self.buffer - .lines - .iter() - .map(|v| v.text().to_owned()) - .collect::>() - } - pub(crate) fn to_layout_lines(&self) -> impl Iterator + '_ { puffin::profile_function!(); let lh = self.buffer.metrics().line_height;