From ed38f24f03220272ea578a4e2c0e6b5fe3854b9e Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Martin=20Kav=C3=ADk?= Date: Sat, 14 Sep 2024 14:32:03 +0200 Subject: [PATCH 01/11] settings.json --- .vscode/settings.json | 12 ++++++++++++ .../components/rust_decoder/.vscode/settings.json | 10 ++++++++++ 2 files changed, 22 insertions(+) create mode 100644 .vscode/settings.json create mode 100644 test_files/components/rust_decoder/.vscode/settings.json diff --git a/.vscode/settings.json b/.vscode/settings.json new file mode 100644 index 0000000..fab9b7a --- /dev/null +++ b/.vscode/settings.json @@ -0,0 +1,12 @@ +{ + "rust-analyzer.cargo.cfgs": { + "FASTWAVE_PLATFORM": "TAURI", + // "FASTWAVE_PLATFORM": "BROWSER", + }, + // https://github.com/rustwasm/wasm-bindgen/issues/2339#issuecomment-2147636233 + "rust-analyzer.cargo.extraEnv": { + "RUSTFLAGS": "--cfg=web_sys_unstable_apis" + }, + // to prevent rebuilding from scratch on each change + "rust-analyzer.cargo.target": "wasm32-unknown-unknown" +} diff --git a/test_files/components/rust_decoder/.vscode/settings.json b/test_files/components/rust_decoder/.vscode/settings.json new file mode 100644 index 0000000..b945667 --- /dev/null +++ b/test_files/components/rust_decoder/.vscode/settings.json @@ -0,0 +1,10 @@ +{ + "rust-analyzer.check.overrideCommand": [ + "cargo", + "component", + "check", + "--workspace", + "--all-targets", + "--message-format=json" + ], +} -- 2.47.1 From 842341309a21ee9942c5f90ab1fea76f55d02ace Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Martin=20Kav=C3=ADk?= Date: Sat, 14 Sep 2024 16:31:46 +0200 Subject: [PATCH 02/11] theme.rs, lints.rust --- frontend/Cargo.toml | 3 +++ frontend/src/main.rs | 3 +++ frontend/src/theme.rs | 24 ++++++++++++++++++++++++ 3 files changed, 30 insertions(+) create mode 100644 frontend/src/theme.rs diff --git a/frontend/Cargo.toml b/frontend/Cargo.toml index 930650e..f463636 100644 --- a/frontend/Cargo.toml +++ b/frontend/Cargo.toml @@ -10,6 +10,9 @@ publish.workspace = true [dev-dependencies] wasm-bindgen-test = "0.3.19" +[lints.rust] +unexpected_cfgs = { level = "allow", check-cfg = ['cfg(FASTWAVE_PLATFORM)'] } + [dependencies] zoon.workspace = true wellen.workspace = true diff --git a/frontend/src/main.rs b/frontend/src/main.rs index 8c45559..839cd8f 100644 --- a/frontend/src/main.rs +++ b/frontend/src/main.rs @@ -13,6 +13,9 @@ use waveform_panel::{PixiController, WaveformPanel}; mod header_panel; use header_panel::HeaderPanel; +mod theme; +use theme::*; + #[derive(Clone, Copy, Default)] enum Layout { Tree, diff --git a/frontend/src/theme.rs b/frontend/src/theme.rs new file mode 100644 index 0000000..d8fcd63 --- /dev/null +++ b/frontend/src/theme.rs @@ -0,0 +1,24 @@ +use zoon::*; + +// https://oklch.com/ + +// const COLOR_BLUE_VIOLET: Rgba = color!("BlueViolet"); // oklch(53.38% 0.25 301.37) +const COLOR_BLUE_VIOLET: Oklch = color!("oklch(53.38% 0.25 262.59)"); + +// const COLOR_MEDIUM_SLATE_BLUE: Rgba = color!("MediumSlateBlue"); // oklch(60.45% 0.194 285.5) +const COLOR_MEDIUM_SLATE_BLUE: Oklch = color!("oklch(60.45% 0.194 262.26)"); + +// const COLOR_SLATE_BLUE: Rgba = color!("SlateBlue"); // oklch(54.36% 0.171 285.54) +const COLOR_SLATE_BLUE: Oklch = color!("oklch(54.36% 0.171 262.26)"); + +// const COLOR_LIGHT_BLUE: Rgba = color!("LightBlue"); // oklch(85.62% 0.049 219.65) +const COLOR_LIGHT_BLUE: Oklch = color!("oklch(85.62% 0.049 262.26)"); + +// const COLOR_WHITE: Rgba = color!("White"); // oklch(100% 3.5594404384177905e-8 106.37411429114086) +const COLOR_WHITE: Oklch = color!("oklch(100% 3.5594404384177905e-8 105.88)"); + +// const COLOR_DARK_SLATE_BLUE: Rgba = color!("DarkSlateBlue"); // oklch(41.43% 0.125 286.04) +const COLOR_DARK_SLATE_BLUE: Oklch = color!("oklch(41.43% 0.125 262.26)"); + +// const COLOR_LAVENDER: Rgba = color!("Lavender"); // oklch(93.09% 0.027 285.86) +const COLOR_LAVENDER: Oklch = color!("oklch(93.09% 0.027 262.26)"); -- 2.47.1 From ab15177a100cb11d334e6a1ac7c074f511010141 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Martin=20Kav=C3=ADk?= Date: Sat, 14 Sep 2024 18:51:03 +0200 Subject: [PATCH 03/11] HTML colors updated --- backend/style.css | 5 +++-- frontend/src/controls_panel.rs | 12 ++++++------ frontend/src/header_panel.rs | 18 +++++++++--------- frontend/src/main.rs | 4 ++-- frontend/src/theme.rs | 31 +++++++++++++++++-------------- frontend/src/waveform_panel.rs | 12 ++++++------ 6 files changed, 43 insertions(+), 39 deletions(-) diff --git a/backend/style.css b/backend/style.css index d78ea00..719f592 100644 --- a/backend/style.css +++ b/backend/style.css @@ -1,3 +1,4 @@ html { - background-color: DarkSlateBlue; -} \ No newline at end of file + /* background-color: DarkSlateBlue; */ + background-color: oklch(41.43% 0.125 262.26); +} diff --git a/frontend/src/controls_panel.rs b/frontend/src/controls_panel.rs index 521acdd..3fc8477 100644 --- a/frontend/src/controls_panel.rs +++ b/frontend/src/controls_panel.rs @@ -1,4 +1,4 @@ -use crate::{Filename, Layout}; +use crate::{Filename, Layout, theme::*}; use std::cell::Cell; use std::mem; use std::ops::Not; @@ -238,9 +238,9 @@ impl ControlsPanel { let background_color = map_ref! { let is_selected = is_selected, let is_hovered = button_hovered_signal => match (*is_selected, *is_hovered) { - (true, _) => color!("BlueViolet"), - (false, true) => color!("MediumSlateBlue"), - (false, false) => color!("SlateBlue"), + (true, _) => COLOR_BLUE_VIOLET, + (false, true) => COLOR_MEDIUM_SLATE_BLUE, + (false, false) => COLOR_SLATE_BLUE, } }; let task_collapse_on_parent_collapse = { @@ -332,7 +332,7 @@ impl ControlsPanel { .map_true(|| 10), )) .s(Height::fill()) - .s(Font::new().color_signal(hovered_signal.map_true(|| color!("LightBlue")))) + .s(Font::new().color_signal(hovered_signal.map_true(|| COLOR_LIGHT_BLUE))) .label( El::new() .s(Transform::with_signal_self(layout_and_expanded.map( @@ -488,7 +488,7 @@ impl ControlsPanel { Button::new() .s(Padding::new().x(15).y(5)) .s(Background::new().color_signal( - hovered_signal.map_bool(|| color!("MediumSlateBlue"), || color!("SlateBlue")), + hovered_signal.map_bool(|| COLOR_MEDIUM_SLATE_BLUE, || COLOR_SLATE_BLUE), )) .s(RoundedCorners::all(15)) .on_hovered_change(move |is_hovered| hovered.set_neq(is_hovered)) diff --git a/frontend/src/header_panel.rs b/frontend/src/header_panel.rs index 3becd90..08a5667 100644 --- a/frontend/src/header_panel.rs +++ b/frontend/src/header_panel.rs @@ -1,4 +1,4 @@ -use crate::{platform, script_bridge, Filename, Layout}; +use crate::{platform, script_bridge, Filename, Layout, theme::*}; use std::sync::Arc; use zoon::*; @@ -45,7 +45,7 @@ impl HeaderPanel { Button::new() .s(Padding::new().x(20).y(10)) .s(Background::new().color_signal( - hovered_signal.map_bool(|| color!("MediumSlateBlue"), || color!("SlateBlue")), + hovered_signal.map_bool(|| COLOR_MEDIUM_SLATE_BLUE, || COLOR_SLATE_BLUE), )) .s(Align::new().left()) .s(RoundedCorners::all(15)) @@ -86,7 +86,7 @@ impl HeaderPanel { .s(Padding::new().x(20).y(10)) .s(Background::new().color_signal( hovered_signal - .map_bool(|| color!("MediumSlateBlue"), || color!("SlateBlue")), + .map_bool(|| COLOR_MEDIUM_SLATE_BLUE, || COLOR_SLATE_BLUE), )) .s(Align::new().left()) .s(RoundedCorners::all(15)) @@ -154,7 +154,7 @@ impl HeaderPanel { Button::new() .s(Padding::new().x(20).y(10)) .s(Background::new().color_signal( - hovered_signal.map_bool(|| color!("MediumSlateBlue"), || color!("SlateBlue")), + hovered_signal.map_bool(|| COLOR_MEDIUM_SLATE_BLUE, || COLOR_SLATE_BLUE), )) .s(RoundedCorners::all(15)) .label_signal(layout.signal().map(|layout| match layout { @@ -206,7 +206,7 @@ impl HeaderPanel { let (script, script_signal) = Mutable::new_and_signal_cloned(String::new()); // @TODO perhaps replace with an element with syntax highlighter like https://github.com/WebCoder49/code-input later TextArea::new() - .s(Background::new().color(color!("SlateBlue"))) + .s(Background::new().color(COLOR_SLATE_BLUE)) .s(Padding::new().x(10).y(8)) .s(RoundedCorners::all(15)) .s(Height::default().min(50)) @@ -214,11 +214,11 @@ impl HeaderPanel { .s(Font::new() .tracking(1) .weight(FontWeight::Medium) - .color(color!("White")) + .color(COLOR_WHITE) .family([FontFamily::new("Courier New"), FontFamily::Monospace])) .s(Shadows::new([Shadow::new() .inner() - .color(color!("DarkSlateBlue")) + .color(COLOR_DARK_SLATE_BLUE) .blur(4)])) // @TODO `spellcheck` and `resize` to MZ API? (together with autocomplete and others?) .update_raw_el(|raw_el| { @@ -227,7 +227,7 @@ impl HeaderPanel { .style("resize", "vertical") }) .placeholder( - Placeholder::new("FW.say_hello()").s(Font::new().color(color!("LightBlue"))), + Placeholder::new("FW.say_hello()").s(Font::new().color(COLOR_LIGHT_BLUE)), ) .label_hidden("command editor panel") .text_signal(script_signal) @@ -272,7 +272,7 @@ impl HeaderPanel { .s(Font::new() .tracking(1) .weight(FontWeight::Medium) - .color(color!("White")) + .color(COLOR_WHITE) .family([FontFamily::new("Courier New"), FontFamily::Monospace])) .s(Scrollbars::both()) .s(Height::default().max(100)) diff --git a/frontend/src/main.rs b/frontend/src/main.rs index 839cd8f..a398435 100644 --- a/frontend/src/main.rs +++ b/frontend/src/main.rs @@ -13,7 +13,7 @@ use waveform_panel::{PixiController, WaveformPanel}; mod header_panel; use header_panel::HeaderPanel; -mod theme; +pub mod theme; use theme::*; #[derive(Clone, Copy, Default)] @@ -53,7 +53,7 @@ fn root() -> impl Element { Column::new() .s(Height::fill()) .s(Scrollbars::y_and_clip_x()) - .s(Font::new().color(color!("Lavender"))) + .s(Font::new().color(COLOR_LAVENDER)) .item(HeaderPanel::new( hierarchy.clone(), layout.clone(), diff --git a/frontend/src/theme.rs b/frontend/src/theme.rs index d8fcd63..93bd456 100644 --- a/frontend/src/theme.rs +++ b/frontend/src/theme.rs @@ -2,23 +2,26 @@ use zoon::*; // https://oklch.com/ -// const COLOR_BLUE_VIOLET: Rgba = color!("BlueViolet"); // oklch(53.38% 0.25 301.37) -const COLOR_BLUE_VIOLET: Oklch = color!("oklch(53.38% 0.25 262.59)"); +// pub const COLOR_BLUE_VIOLET: Rgba = color!("BlueViolet"); // oklch(53.38% 0.25 301.37) +pub const COLOR_BLUE_VIOLET: Oklch = color!("oklch(53.38% 0.25 262.59)"); -// const COLOR_MEDIUM_SLATE_BLUE: Rgba = color!("MediumSlateBlue"); // oklch(60.45% 0.194 285.5) -const COLOR_MEDIUM_SLATE_BLUE: Oklch = color!("oklch(60.45% 0.194 262.26)"); +// pub const COLOR_MEDIUM_SLATE_BLUE: Rgba = color!("MediumSlateBlue"); // oklch(60.45% 0.194 285.5) +pub const COLOR_MEDIUM_SLATE_BLUE: Oklch = color!("oklch(60.45% 0.194 262.26)"); -// const COLOR_SLATE_BLUE: Rgba = color!("SlateBlue"); // oklch(54.36% 0.171 285.54) -const COLOR_SLATE_BLUE: Oklch = color!("oklch(54.36% 0.171 262.26)"); +// pub const COLOR_SLATE_BLUE_WITH_ALPHA: Rgba = color!("SlateBlue", 0.8); // oklch(54.36% 0.171 285.54) +pub const COLOR_SLATE_BLUE_WITH_ALPHA: Oklch = color!("oklch(54.36% 0.171 262.26)", 0.8); -// const COLOR_LIGHT_BLUE: Rgba = color!("LightBlue"); // oklch(85.62% 0.049 219.65) -const COLOR_LIGHT_BLUE: Oklch = color!("oklch(85.62% 0.049 262.26)"); +// pub const COLOR_SLATE_BLUE: Rgba = color!("SlateBlue"); // oklch(54.36% 0.171 285.54) +pub const COLOR_SLATE_BLUE: Oklch = color!("oklch(54.36% 0.171 262.26)"); -// const COLOR_WHITE: Rgba = color!("White"); // oklch(100% 3.5594404384177905e-8 106.37411429114086) -const COLOR_WHITE: Oklch = color!("oklch(100% 3.5594404384177905e-8 105.88)"); +// pub const COLOR_LIGHT_BLUE: Rgba = color!("LightBlue"); // oklch(85.62% 0.049 219.65) +pub const COLOR_LIGHT_BLUE: Oklch = color!("oklch(85.62% 0.049 262.26)"); -// const COLOR_DARK_SLATE_BLUE: Rgba = color!("DarkSlateBlue"); // oklch(41.43% 0.125 286.04) -const COLOR_DARK_SLATE_BLUE: Oklch = color!("oklch(41.43% 0.125 262.26)"); +// pub const COLOR_WHITE: Rgba = color!("White"); // oklch(100% 3.5594404384177905e-8 106.37411429114086) +pub const COLOR_WHITE: Oklch = color!("oklch(100% 3.5594404384177905e-8 105.88)"); -// const COLOR_LAVENDER: Rgba = color!("Lavender"); // oklch(93.09% 0.027 285.86) -const COLOR_LAVENDER: Oklch = color!("oklch(93.09% 0.027 262.26)"); +// pub const COLOR_DARK_SLATE_BLUE: Rgba = color!("DarkSlateBlue"); // oklch(41.43% 0.125 286.04) +pub const COLOR_DARK_SLATE_BLUE: Oklch = color!("oklch(41.43% 0.125 262.26)"); + +// pub const COLOR_LAVENDER: Rgba = color!("Lavender"); // oklch(93.09% 0.027 285.86) +pub const COLOR_LAVENDER: Oklch = color!("oklch(93.09% 0.027 262.26)"); diff --git a/frontend/src/waveform_panel.rs b/frontend/src/waveform_panel.rs index e2ce51f..8d0bf58 100644 --- a/frontend/src/waveform_panel.rs +++ b/frontend/src/waveform_panel.rs @@ -1,4 +1,4 @@ -use crate::{platform, script_bridge, Filename}; +use crate::{platform, script_bridge, Filename, theme::*}; use std::sync::Arc; use wellen::GetItem; use zoon::*; @@ -87,7 +87,7 @@ impl WaveformPanel { Button::new() .s(Padding::new().x(20).y(10)) .s(Background::new().color_signal( - hovered_signal.map_bool(|| color!("MediumSlateBlue"), || color!("SlateBlue")), + hovered_signal.map_bool(|| COLOR_MEDIUM_SLATE_BLUE, || COLOR_SLATE_BLUE), )) .s(Align::new().left()) .s(RoundedCorners::all(15)) @@ -123,7 +123,7 @@ impl WaveformPanel { .s(Padding::new().x(20).y(10)) .s(Background::new().color_signal( hovered_signal - .map_bool(|| color!("MediumSlateBlue"), || color!("SlateBlue")), + .map_bool(|| COLOR_MEDIUM_SLATE_BLUE, || COLOR_SLATE_BLUE), )) .s(Align::new().left()) .s(RoundedCorners::all(15)) @@ -178,7 +178,7 @@ impl WaveformPanel { Button::new() .s(Padding::new().x(20).y(10)) .s(Background::new().color_signal( - hovered_signal.map_bool(|| color!("MediumSlateBlue"), || color!("SlateBlue")), + hovered_signal.map_bool(|| COLOR_MEDIUM_SLATE_BLUE, || COLOR_SLATE_BLUE), )) .s(RoundedCorners::all(15)) .label("Save") @@ -349,7 +349,7 @@ impl WaveformPanel { .s(Height::exact(ROW_HEIGHT)) .s(Width::growable()) .s(Background::new().color_signal( - hovered_signal.map_bool(|| color!("SlateBlue"), || color!("SlateBlue", 0.8)), + hovered_signal.map_bool(|| COLOR_SLATE_BLUE, || COLOR_SLATE_BLUE_WITH_ALPHA), )) .s(RoundedCorners::new().left(15).right(5)) .label( @@ -384,7 +384,7 @@ impl WaveformPanel { .s(Height::exact(ROW_HEIGHT)) .s(Width::exact(70)) .s(Background::new().color_signal( - hovered_signal.map_bool(|| color!("SlateBlue"), || color!("SlateBlue", 0.8)), + hovered_signal.map_bool(|| COLOR_SLATE_BLUE, || COLOR_SLATE_BLUE_WITH_ALPHA), )) .s(RoundedCorners::new().left(5)) .label( -- 2.47.1 From 4fac3e946cff986876a638da4816b91d36150c24 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Martin=20Kav=C3=ADk?= Date: Sat, 14 Sep 2024 19:11:35 +0200 Subject: [PATCH 04/11] canvas colors --- frontend/typescript/bundles/pixi_canvas.js | 12 +++++++---- .../typescript/pixi_canvas/pixi_canvas.ts | 20 +++++++++++++++---- 2 files changed, 24 insertions(+), 8 deletions(-) diff --git a/frontend/typescript/bundles/pixi_canvas.js b/frontend/typescript/bundles/pixi_canvas.js index 607cf53..92c922d 100644 --- a/frontend/typescript/bundles/pixi_canvas.js +++ b/frontend/typescript/bundles/pixi_canvas.js @@ -35128,6 +35128,10 @@ var import_earcut2 = __toESM(require_earcut(), 1); extensions.add(browserExt, webworkerExt); // pixi_canvas.ts +var color_dark_slate_blue = "#24478e"; +var color_white = "#ffffff"; +var color_slate_blue = "#3d7af3"; +var color_dark_violet_with_x = "0x002ca9"; var PixiController = class { app; // -- FastWave-specific -- @@ -35151,7 +35155,7 @@ var PixiController = class { this.timeline_getter = timeline_getter; } async init(parent_element) { - await this.app.init({ background: "DarkSlateBlue", antialias: true, resizeTo: parent_element }); + await this.app.init({ background: color_dark_slate_blue, antialias: true, resizeTo: parent_element }); parent_element.appendChild(this.app.canvas); } // Default automatic Pixi resizing according to the parent is not reliable @@ -35284,7 +35288,7 @@ var VarSignalRow = class { signal_blocks_container = new Container(); label_style = new TextStyle({ align: "center", - fill: "White", + fill: color_white, fontSize: 16, fontFamily: '"Courier New", monospace' }); @@ -35304,7 +35308,7 @@ var VarSignalRow = class { this.rows_container.addChild(this.row_container); this.row_container_background = new Sprite(); this.row_container_background.texture = Texture.WHITE; - this.row_container_background.tint = "0x550099"; + this.row_container_background.tint = color_dark_violet_with_x; this.row_container_background.height = this.row_height; this.row_container.addChild(this.row_container_background); this.row_container.addChild(this.signal_blocks_container); @@ -35330,7 +35334,7 @@ var VarSignalRow = class { signal_block.x = timeline_block.x; this.signal_blocks_container.addChild(signal_block); const gap_between_blocks = 2; - const background = new Graphics().rect(gap_between_blocks / 2, 0, timeline_block.width - gap_between_blocks, timeline_block.height).fill("SlateBlue"); + const background = new Graphics().rect(gap_between_blocks / 2, 0, timeline_block.width - gap_between_blocks, timeline_block.height).fill(color_slate_blue); signal_block.addChild(background); if (timeline_block.label !== void 0) { const label = new Text(); diff --git a/frontend/typescript/pixi_canvas/pixi_canvas.ts b/frontend/typescript/pixi_canvas/pixi_canvas.ts index ea1ea42..208875b 100644 --- a/frontend/typescript/pixi_canvas/pixi_canvas.ts +++ b/frontend/typescript/pixi_canvas/pixi_canvas.ts @@ -1,5 +1,17 @@ import { Application, Text, Graphics, Container, TextStyle, Sprite, Texture } from "pixi.js"; +// const color_dark_slate_blue = 'DarkSlateBlue' +const color_dark_slate_blue = '#24478e' // oklch(41.43% 0.125 262.26)' + +// const color_white = 'White' +const color_white = '#ffffff' // oklch(100% 3.5594404384177905e-8 105.88) + +// const color_slate_blue = 'SlateBlue' +const color_slate_blue = '#3d7af3' // oklch(60.45% 0.194 262.26) + +// const color_dark_violet_with_x = '0x550099' // oklch(37.6% 0.201 299.56) +const color_dark_violet_with_x = '0x002ca9' // oklch(37.6% 0.201 263.53) + // @TODO sync with Rust and `tauri_glue.ts` type Timeline = { blocks: Array @@ -69,7 +81,7 @@ export class PixiController { } async init(parent_element: HTMLElement) { - await this.app.init({ background: 'DarkSlateBlue', antialias: true, resizeTo: parent_element }); + await this.app.init({ background: color_dark_slate_blue, antialias: true, resizeTo: parent_element }); parent_element.appendChild(this.app.canvas); } @@ -221,7 +233,7 @@ class VarSignalRow { signal_blocks_container = new Container(); label_style = new TextStyle({ align: "center", - fill: "White", + fill: color_white, fontSize: 16, fontFamily: '"Courier New", monospace', }); @@ -258,7 +270,7 @@ class VarSignalRow { // row background this.row_container_background = new Sprite(); this.row_container_background.texture = Texture.WHITE; - this.row_container_background.tint = '0x550099'; + this.row_container_background.tint = color_dark_violet_with_x; this.row_container_background.height = this.row_height; this.row_container.addChild(this.row_container_background); @@ -300,7 +312,7 @@ class VarSignalRow { const gap_between_blocks = 2; const background = new Graphics() .rect(gap_between_blocks / 2, 0, timeline_block.width - gap_between_blocks, timeline_block.height) - .fill('SlateBlue'); + .fill(color_slate_blue); signal_block.addChild(background); // label -- 2.47.1 From dbf826d2f40d0379c64f5786de8a84118ea4d0d0 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Martin=20Kav=C3=ADk?= Date: Sat, 14 Sep 2024 19:12:04 +0200 Subject: [PATCH 05/11] fmt --- frontend/src/controls_panel.rs | 2 +- frontend/src/header_panel.rs | 9 +++------ frontend/src/theme.rs | 16 ++++++++-------- frontend/src/waveform_panel.rs | 5 ++--- 4 files changed, 14 insertions(+), 18 deletions(-) diff --git a/frontend/src/controls_panel.rs b/frontend/src/controls_panel.rs index 3fc8477..aa3a205 100644 --- a/frontend/src/controls_panel.rs +++ b/frontend/src/controls_panel.rs @@ -1,4 +1,4 @@ -use crate::{Filename, Layout, theme::*}; +use crate::{theme::*, Filename, Layout}; use std::cell::Cell; use std::mem; use std::ops::Not; diff --git a/frontend/src/header_panel.rs b/frontend/src/header_panel.rs index 08a5667..cb534bc 100644 --- a/frontend/src/header_panel.rs +++ b/frontend/src/header_panel.rs @@ -1,4 +1,4 @@ -use crate::{platform, script_bridge, Filename, Layout, theme::*}; +use crate::{platform, script_bridge, theme::*, Filename, Layout}; use std::sync::Arc; use zoon::*; @@ -85,8 +85,7 @@ impl HeaderPanel { Label::new() .s(Padding::new().x(20).y(10)) .s(Background::new().color_signal( - hovered_signal - .map_bool(|| COLOR_MEDIUM_SLATE_BLUE, || COLOR_SLATE_BLUE), + hovered_signal.map_bool(|| COLOR_MEDIUM_SLATE_BLUE, || COLOR_SLATE_BLUE), )) .s(Align::new().left()) .s(RoundedCorners::all(15)) @@ -226,9 +225,7 @@ impl HeaderPanel { .attr("spellcheck", "false") .style("resize", "vertical") }) - .placeholder( - Placeholder::new("FW.say_hello()").s(Font::new().color(COLOR_LIGHT_BLUE)), - ) + .placeholder(Placeholder::new("FW.say_hello()").s(Font::new().color(COLOR_LIGHT_BLUE))) .label_hidden("command editor panel") .text_signal(script_signal) .on_change(clone!((script, command_result) move |text| { diff --git a/frontend/src/theme.rs b/frontend/src/theme.rs index 93bd456..8d04a66 100644 --- a/frontend/src/theme.rs +++ b/frontend/src/theme.rs @@ -3,25 +3,25 @@ use zoon::*; // https://oklch.com/ // pub const COLOR_BLUE_VIOLET: Rgba = color!("BlueViolet"); // oklch(53.38% 0.25 301.37) -pub const COLOR_BLUE_VIOLET: Oklch = color!("oklch(53.38% 0.25 262.59)"); +pub const COLOR_BLUE_VIOLET: Oklch = color!("oklch(53.38% 0.25 262.59)"); // pub const COLOR_MEDIUM_SLATE_BLUE: Rgba = color!("MediumSlateBlue"); // oklch(60.45% 0.194 285.5) -pub const COLOR_MEDIUM_SLATE_BLUE: Oklch = color!("oklch(60.45% 0.194 262.26)"); +pub const COLOR_MEDIUM_SLATE_BLUE: Oklch = color!("oklch(60.45% 0.194 262.26)"); // pub const COLOR_SLATE_BLUE_WITH_ALPHA: Rgba = color!("SlateBlue", 0.8); // oklch(54.36% 0.171 285.54) pub const COLOR_SLATE_BLUE_WITH_ALPHA: Oklch = color!("oklch(54.36% 0.171 262.26)", 0.8); // pub const COLOR_SLATE_BLUE: Rgba = color!("SlateBlue"); // oklch(54.36% 0.171 285.54) -pub const COLOR_SLATE_BLUE: Oklch = color!("oklch(54.36% 0.171 262.26)"); +pub const COLOR_SLATE_BLUE: Oklch = color!("oklch(54.36% 0.171 262.26)"); -// pub const COLOR_LIGHT_BLUE: Rgba = color!("LightBlue"); // oklch(85.62% 0.049 219.65) -pub const COLOR_LIGHT_BLUE: Oklch = color!("oklch(85.62% 0.049 262.26)"); +// pub const COLOR_LIGHT_BLUE: Rgba = color!("LightBlue"); // oklch(85.62% 0.049 219.65) +pub const COLOR_LIGHT_BLUE: Oklch = color!("oklch(85.62% 0.049 262.26)"); // pub const COLOR_WHITE: Rgba = color!("White"); // oklch(100% 3.5594404384177905e-8 106.37411429114086) -pub const COLOR_WHITE: Oklch = color!("oklch(100% 3.5594404384177905e-8 105.88)"); +pub const COLOR_WHITE: Oklch = color!("oklch(100% 3.5594404384177905e-8 105.88)"); // pub const COLOR_DARK_SLATE_BLUE: Rgba = color!("DarkSlateBlue"); // oklch(41.43% 0.125 286.04) -pub const COLOR_DARK_SLATE_BLUE: Oklch = color!("oklch(41.43% 0.125 262.26)"); +pub const COLOR_DARK_SLATE_BLUE: Oklch = color!("oklch(41.43% 0.125 262.26)"); // pub const COLOR_LAVENDER: Rgba = color!("Lavender"); // oklch(93.09% 0.027 285.86) -pub const COLOR_LAVENDER: Oklch = color!("oklch(93.09% 0.027 262.26)"); +pub const COLOR_LAVENDER: Oklch = color!("oklch(93.09% 0.027 262.26)"); diff --git a/frontend/src/waveform_panel.rs b/frontend/src/waveform_panel.rs index 8d0bf58..6ec20af 100644 --- a/frontend/src/waveform_panel.rs +++ b/frontend/src/waveform_panel.rs @@ -1,4 +1,4 @@ -use crate::{platform, script_bridge, Filename, theme::*}; +use crate::{platform, script_bridge, theme::*, Filename}; use std::sync::Arc; use wellen::GetItem; use zoon::*; @@ -122,8 +122,7 @@ impl WaveformPanel { Label::new() .s(Padding::new().x(20).y(10)) .s(Background::new().color_signal( - hovered_signal - .map_bool(|| COLOR_MEDIUM_SLATE_BLUE, || COLOR_SLATE_BLUE), + hovered_signal.map_bool(|| COLOR_MEDIUM_SLATE_BLUE, || COLOR_SLATE_BLUE), )) .s(Align::new().left()) .s(RoundedCorners::all(15)) -- 2.47.1 From f2a87a12ee9ac05c4f1b99c4b5976c69185dcfd8 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Martin=20Kav=C3=ADk?= Date: Sat, 14 Sep 2024 19:48:09 +0200 Subject: [PATCH 06/11] command_panel.rs --- frontend/src/command_panel.rs | 141 ++++++++++++++++++++++++++++++++++ frontend/src/header_panel.rs | 134 +------------------------------- frontend/src/main.rs | 4 + 3 files changed, 146 insertions(+), 133 deletions(-) create mode 100644 frontend/src/command_panel.rs diff --git a/frontend/src/command_panel.rs b/frontend/src/command_panel.rs new file mode 100644 index 0000000..5e61df7 --- /dev/null +++ b/frontend/src/command_panel.rs @@ -0,0 +1,141 @@ +use crate::{script_bridge, theme::*}; +use zoon::*; + +pub struct CommandPanel {} + +impl CommandPanel { + pub fn new() -> impl Element { + Self {}.root() + } + + fn root(&self) -> impl Element { + let command_result: Mutable>> = <_>::default(); + Row::new() + .s(Align::new().top()) + .s(Gap::both(30)) + .s(Scrollbars::both()) + .s(Width::fill()) + .item(self.command_editor_panel(command_result.clone())) + .item(self.command_result_panel(command_result.read_only())) + } + + fn command_editor_panel( + &self, + command_result: Mutable>>, + ) -> impl Element { + Column::new() + .s(Align::new().top()) + .s(Gap::new().y(10)) + .s(Width::growable()) + .item( + Row::new() + .s(Gap::new().x(15)) + .s(Padding::new().x(5)) + .item(El::new().child("Javascript commands")) + .item(El::new().s(Align::new().right()).child("Shift + Enter")), + ) + .item(self.command_editor(command_result)) + } + + fn command_editor( + &self, + command_result: Mutable>>, + ) -> impl Element { + let (script, script_signal) = Mutable::new_and_signal_cloned(String::new()); + // @TODO perhaps replace with an element with syntax highlighter like https://github.com/WebCoder49/code-input later + TextArea::new() + .s(Background::new().color(COLOR_SLATE_BLUE)) + .s(Padding::new().x(10).y(8)) + .s(RoundedCorners::all(15)) + .s(Height::default().min(50)) + .s(Width::fill().min(300)) + .s(Font::new() + .tracking(1) + .weight(FontWeight::Medium) + .color(COLOR_WHITE) + .family([FontFamily::new("Courier New"), FontFamily::Monospace])) + .s(Shadows::new([Shadow::new() + .inner() + .color(COLOR_DARK_SLATE_BLUE) + .blur(4)])) + // @TODO `spellcheck` and `resize` to MZ API? (together with autocomplete and others?) + .update_raw_el(|raw_el| { + raw_el + .attr("spellcheck", "false") + .style("resize", "vertical") + }) + .placeholder(Placeholder::new("FW.say_hello()").s(Font::new().color(COLOR_LIGHT_BLUE))) + .label_hidden("command editor panel") + .text_signal(script_signal) + .on_change(clone!((script, command_result) move |text| { + script.set_neq(text); + command_result.set_neq(None); + })) + .on_key_down_event_with_options(EventOptions::new().preventable(), move |event| { + if event.key() == &Key::Enter { + let RawKeyboardEvent::KeyDown(raw_event) = event.raw_event.clone(); + if raw_event.shift_key() { + // @TODO move `prevent_default` to MZ API (next to the `pass_to_parent` method?) + raw_event.prevent_default(); + Task::start(clone!((script, command_result) async move { + let result = script_bridge::strict_eval(&script.lock_ref()).await; + command_result.set(Some(result)); + })); + } + } + }) + } + + fn command_result_panel( + &self, + command_result: ReadOnlyMutable>>, + ) -> impl Element { + Column::new() + .s(Gap::new().y(10)) + .s(Align::new().top()) + .s(Scrollbars::both()) + .s(Padding::new().x(5)) + .s(Width::growable().max(750)) + .item(El::new().child("Command result")) + .item(self.command_result_el(command_result)) + } + + fn command_result_el( + &self, + command_result: ReadOnlyMutable>>, + ) -> impl Element { + El::new() + .s(Font::new() + .tracking(1) + .weight(FontWeight::Medium) + .color(COLOR_WHITE) + .family([FontFamily::new("Courier New"), FontFamily::Monospace])) + .s(Scrollbars::both()) + .s(Height::default().max(100)) + .child_signal(command_result.signal_ref(|result| { + fn format_complex_js_value(js_value: &JsValue) -> String { + let value = format!("{js_value:?}"); + let value = value.strip_prefix("JsValue(").unwrap_throw(); + let value = value.strip_suffix(')').unwrap_throw(); + value.to_owned() + } + match result { + Some(Ok(js_value)) => { + if let Some(string_value) = js_value.as_string() { + string_value + } else if let Some(number_value) = js_value.as_f64() { + number_value.to_string() + } else if let Some(bool_value) = js_value.as_bool() { + bool_value.to_string() + } else { + format_complex_js_value(js_value) + } + } + Some(Err(js_value)) => { + format!("ERROR: {}", format_complex_js_value(js_value)) + } + None => "-".to_owned(), + } + })) + } +} diff --git a/frontend/src/header_panel.rs b/frontend/src/header_panel.rs index cb534bc..5007d73 100644 --- a/frontend/src/header_panel.rs +++ b/frontend/src/header_panel.rs @@ -1,4 +1,4 @@ -use crate::{platform, script_bridge, theme::*, Filename, Layout}; +use crate::{platform, theme::*, Filename, Layout}; use std::sync::Arc; use zoon::*; @@ -34,7 +34,6 @@ impl HeaderPanel { .item(self.load_button()) .item(self.layout_switcher()), ) - .item(self.command_panel()) } #[cfg(FASTWAVE_PLATFORM = "TAURI")] @@ -168,135 +167,4 @@ impl HeaderPanel { }) }) } - - fn command_panel(&self) -> impl Element { - let command_result: Mutable>> = <_>::default(); - Row::new() - .s(Align::new().top()) - .s(Gap::both(30)) - .s(Scrollbars::both()) - .s(Width::fill()) - .item(self.command_editor_panel(command_result.clone())) - .item(self.command_result_panel(command_result.read_only())) - } - - fn command_editor_panel( - &self, - command_result: Mutable>>, - ) -> impl Element { - Column::new() - .s(Align::new().top()) - .s(Gap::new().y(10)) - .s(Width::growable()) - .item( - Row::new() - .s(Gap::new().x(15)) - .s(Padding::new().x(5)) - .item(El::new().child("Javascript commands")) - .item(El::new().s(Align::new().right()).child("Shift + Enter")), - ) - .item(self.command_editor(command_result)) - } - - fn command_editor( - &self, - command_result: Mutable>>, - ) -> impl Element { - let (script, script_signal) = Mutable::new_and_signal_cloned(String::new()); - // @TODO perhaps replace with an element with syntax highlighter like https://github.com/WebCoder49/code-input later - TextArea::new() - .s(Background::new().color(COLOR_SLATE_BLUE)) - .s(Padding::new().x(10).y(8)) - .s(RoundedCorners::all(15)) - .s(Height::default().min(50)) - .s(Width::fill().min(300)) - .s(Font::new() - .tracking(1) - .weight(FontWeight::Medium) - .color(COLOR_WHITE) - .family([FontFamily::new("Courier New"), FontFamily::Monospace])) - .s(Shadows::new([Shadow::new() - .inner() - .color(COLOR_DARK_SLATE_BLUE) - .blur(4)])) - // @TODO `spellcheck` and `resize` to MZ API? (together with autocomplete and others?) - .update_raw_el(|raw_el| { - raw_el - .attr("spellcheck", "false") - .style("resize", "vertical") - }) - .placeholder(Placeholder::new("FW.say_hello()").s(Font::new().color(COLOR_LIGHT_BLUE))) - .label_hidden("command editor panel") - .text_signal(script_signal) - .on_change(clone!((script, command_result) move |text| { - script.set_neq(text); - command_result.set_neq(None); - })) - .on_key_down_event_with_options(EventOptions::new().preventable(), move |event| { - if event.key() == &Key::Enter { - let RawKeyboardEvent::KeyDown(raw_event) = event.raw_event.clone(); - if raw_event.shift_key() { - // @TODO move `prevent_default` to MZ API (next to the `pass_to_parent` method?) - raw_event.prevent_default(); - Task::start(clone!((script, command_result) async move { - let result = script_bridge::strict_eval(&script.lock_ref()).await; - command_result.set(Some(result)); - })); - } - } - }) - } - - fn command_result_panel( - &self, - command_result: ReadOnlyMutable>>, - ) -> impl Element { - Column::new() - .s(Gap::new().y(10)) - .s(Align::new().top()) - .s(Scrollbars::both()) - .s(Padding::new().x(5)) - .s(Width::growable().max(750)) - .item(El::new().child("Command result")) - .item(self.command_result_el(command_result)) - } - - fn command_result_el( - &self, - command_result: ReadOnlyMutable>>, - ) -> impl Element { - El::new() - .s(Font::new() - .tracking(1) - .weight(FontWeight::Medium) - .color(COLOR_WHITE) - .family([FontFamily::new("Courier New"), FontFamily::Monospace])) - .s(Scrollbars::both()) - .s(Height::default().max(100)) - .child_signal(command_result.signal_ref(|result| { - fn format_complex_js_value(js_value: &JsValue) -> String { - let value = format!("{js_value:?}"); - let value = value.strip_prefix("JsValue(").unwrap_throw(); - let value = value.strip_suffix(')').unwrap_throw(); - value.to_owned() - } - match result { - Some(Ok(js_value)) => { - if let Some(string_value) = js_value.as_string() { - string_value - } else if let Some(number_value) = js_value.as_f64() { - number_value.to_string() - } else if let Some(bool_value) = js_value.as_bool() { - bool_value.to_string() - } else { - format_complex_js_value(js_value) - } - } - Some(Err(js_value)) => { - format!("ERROR: {}", format_complex_js_value(js_value)) - } - None => "-".to_owned(), - } - })) - } } diff --git a/frontend/src/main.rs b/frontend/src/main.rs index a398435..b25c417 100644 --- a/frontend/src/main.rs +++ b/frontend/src/main.rs @@ -13,6 +13,9 @@ use waveform_panel::{PixiController, WaveformPanel}; mod header_panel; use header_panel::HeaderPanel; +mod command_panel; +use command_panel::CommandPanel; + pub mod theme; use theme::*; @@ -101,4 +104,5 @@ fn root() -> impl Element { } } ) + .item(CommandPanel::new()) } -- 2.47.1 From 48542523988c2e54fb4c6e7ca66043f480b3caa1 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Martin=20Kav=C3=ADk?= Date: Sat, 14 Sep 2024 19:50:43 +0200 Subject: [PATCH 07/11] command_panel layout --- frontend/src/command_panel.rs | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/frontend/src/command_panel.rs b/frontend/src/command_panel.rs index 5e61df7..863f4ed 100644 --- a/frontend/src/command_panel.rs +++ b/frontend/src/command_panel.rs @@ -13,8 +13,8 @@ impl CommandPanel { Row::new() .s(Align::new().top()) .s(Gap::both(30)) - .s(Scrollbars::both()) .s(Width::fill()) + .s(Padding::new().x(20).bottom(20)) .item(self.command_editor_panel(command_result.clone())) .item(self.command_result_panel(command_result.read_only())) } -- 2.47.1 From d74f4de199b0096a15a4f67a3c549a680af4b98e Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Martin=20Kav=C3=ADk?= Date: Sat, 14 Sep 2024 20:36:58 +0200 Subject: [PATCH 08/11] favicon.html --- backend/favicon.html | 8 ++++++++ backend/src/main.rs | 1 + public/favicon/android-chrome-192x192.png | Bin 0 -> 27768 bytes public/favicon/android-chrome-512x512.png | Bin 0 -> 115555 bytes public/favicon/apple-touch-icon.png | Bin 0 -> 20800 bytes public/favicon/browserconfig.xml | 9 +++++++++ public/favicon/favicon-16x16.png | Bin 0 -> 1355 bytes public/favicon/favicon-32x32.png | Bin 0 -> 2582 bytes public/favicon/favicon.ico | Bin 0 -> 15086 bytes public/favicon/mstile-150x150.png | Bin 0 -> 17222 bytes public/favicon/site.webmanifest | 19 +++++++++++++++++++ 11 files changed, 37 insertions(+) create mode 100644 backend/favicon.html create mode 100644 public/favicon/android-chrome-192x192.png create mode 100644 public/favicon/android-chrome-512x512.png create mode 100644 public/favicon/apple-touch-icon.png create mode 100644 public/favicon/browserconfig.xml create mode 100644 public/favicon/favicon-16x16.png create mode 100644 public/favicon/favicon-32x32.png create mode 100644 public/favicon/favicon.ico create mode 100644 public/favicon/mstile-150x150.png create mode 100644 public/favicon/site.webmanifest diff --git a/backend/favicon.html b/backend/favicon.html new file mode 100644 index 0000000..9ef415c --- /dev/null +++ b/backend/favicon.html @@ -0,0 +1,8 @@ + + + + + + + + diff --git a/backend/src/main.rs b/backend/src/main.rs index fe6bfd7..c9df718 100644 --- a/backend/src/main.rs +++ b/backend/src/main.rs @@ -3,6 +3,7 @@ use moon::*; async fn frontend() -> Frontend { Frontend::new() .title("FastWave") + .append_to_head(include_str!("../favicon.html")) // realfavicongenerator.net .append_to_head(concat!("")) .append_to_head(concat!( "