Colors, Icons #16

Merged
MartinKavik merged 11 commits from colors_icons into main 2024-09-14 19:54:13 +00:00
79 changed files with 309 additions and 164 deletions

12
.vscode/settings.json vendored Normal file
View file

@ -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"
}

View file

@ -3,6 +3,27 @@
---
<p align="center">Default state - Dark (new design)</p>
<p align="center">
<img width="800" src="docs/home_dark.png" alt="Fastwave - Default state - Dark (not implemented yet)" />
</p>
<p align="center">Loaded files - Dark (new design)</p>
<p align="center">
<img width="800" src="docs/loaded_files_dark.png" alt="Fastwave - Loaded files - Dark (not implemented yet)" />
</p>
<p align="center">Default state - Light (new design)</p>
<p align="center">
<img width="800" src="docs/home_light.png" alt="Fastwave - Default state - Light (not implemented yet)" />
</p>
<p align="center">Loaded files - Light (new design)</p>
<p align="center">
<img width="800" src="docs/loaded_files_light.png" alt="Fastwave - Loaded files - Light (not implemented yet)" />
</p>
<p align="center">Browser (Firefox)</p>
<p align="center">
<img width="800" src="docs/screenshot_firefox.png" alt="Fastwave - Browser (Firefox)" />
@ -33,7 +54,7 @@
<img width="800" src="docs/video_load_save_selected_vars.gif" alt="Fastwave - Load and save selected variables" />
</p>
<p align="center">Decoders Demo</p>
<p align="center">Decoders (Plugins) Demo</p>
<p align="center">
<img width="800" src="docs/video_decoders.gif" alt="Fastwave - Decoders demo" />
</p>
@ -97,7 +118,13 @@ Troubleshooting:
1. `makers format`
---
### Rebuild Decoders:
See `test_files/components/[language]_decoder/README.md`
---
### Test files

8
backend/favicon.html Normal file
View file

@ -0,0 +1,8 @@
<link rel="apple-touch-icon" sizes="180x180" href="/_api/public/favicon/apple-touch-icon.png">
<link rel="icon" type="image/png" sizes="32x32" href="/_api/public/favicon/favicon-32x32.png">
<link rel="icon" type="image/png" sizes="16x16" href="/_api/public/favicon/favicon-16x16.png">
<link rel="manifest" href="/_api/public/favicon/site.webmanifest">
<link rel="shortcut icon" href="/_api/public/favicon/favicon.ico">
<meta name="msapplication-TileColor" content="#00a300">
<meta name="msapplication-config" content="/_api/public/favicon/browserconfig.xml">
<meta name="theme-color" content="#ffffff">

View file

@ -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!("<style>", include_str!("../style.css"), "</style>"))
.append_to_head(concat!(
"<script type=\"module\">",

View file

@ -1,3 +1,4 @@
html {
background-color: DarkSlateBlue;
}
/* background-color: DarkSlateBlue; */
background-color: oklch(41.43% 0.125 262.26);
}

BIN
docs/fastwave_logo.png Normal file

Binary file not shown.

After

Width:  |  Height:  |  Size: 546 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 378 KiB

BIN
docs/home_dark.png Normal file

Binary file not shown.

After

Width:  |  Height:  |  Size: 94 KiB

BIN
docs/home_light.png Normal file

Binary file not shown.

After

Width:  |  Height:  |  Size: 92 KiB

BIN
docs/loaded_files_dark.png Normal file

Binary file not shown.

After

Width:  |  Height:  |  Size: 168 KiB

BIN
docs/loaded_files_light.png Normal file

Binary file not shown.

After

Width:  |  Height:  |  Size: 166 KiB

View file

@ -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

View file

@ -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<Option<Result<JsValue, JsValue>>> = <_>::default();
Row::new()
.s(Align::new().top())
.s(Gap::both(30))
.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()))
}
fn command_editor_panel(
&self,
command_result: Mutable<Option<Result<JsValue, JsValue>>>,
) -> 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<Option<Result<JsValue, JsValue>>>,
) -> 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<Option<Result<JsValue, JsValue>>>,
) -> 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<Option<Result<JsValue, JsValue>>>,
) -> 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(),
}
}))
}
}

View file

@ -1,4 +1,4 @@
use crate::{Filename, Layout};
use crate::{theme::*, Filename, Layout};
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))

View file

@ -1,4 +1,4 @@
use crate::{platform, script_bridge, 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")]
@ -45,7 +44,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))
@ -85,8 +84,7 @@ impl HeaderPanel {
Label::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))
@ -154,7 +152,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 {
@ -169,137 +167,4 @@ impl HeaderPanel {
})
})
}
fn command_panel(&self) -> impl Element {
let command_result: Mutable<Option<Result<JsValue, JsValue>>> = <_>::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<Option<Result<JsValue, JsValue>>>,
) -> 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<Option<Result<JsValue, JsValue>>>,
) -> 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!("SlateBlue")))
.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!("DarkSlateBlue"))
.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!("LightBlue"))),
)
.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<Option<Result<JsValue, JsValue>>>,
) -> 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<Option<Result<JsValue, JsValue>>>,
) -> 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(),
}
}))
}
}

View file

@ -13,6 +13,12 @@ use waveform_panel::{PixiController, WaveformPanel};
mod header_panel;
use header_panel::HeaderPanel;
mod command_panel;
use command_panel::CommandPanel;
pub mod theme;
use theme::*;
#[derive(Clone, Copy, Default)]
enum Layout {
Tree,
@ -50,7 +56,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(),
@ -98,4 +104,5 @@ fn root() -> impl Element {
}
}
)
.item(CommandPanel::new())
}

27
frontend/src/theme.rs Normal file
View file

@ -0,0 +1,27 @@
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_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_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_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_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)");

View file

@ -1,4 +1,4 @@
use crate::{platform, script_bridge, Filename};
use crate::{platform, script_bridge, theme::*, Filename};
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))
@ -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!("MediumSlateBlue"), || color!("SlateBlue")),
hovered_signal.map_bool(|| COLOR_MEDIUM_SLATE_BLUE, || COLOR_SLATE_BLUE),
))
.s(Align::new().left())
.s(RoundedCorners::all(15))
@ -178,7 +177,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 +348,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 +383,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(

View file

@ -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();

View file

@ -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<TimelineBlock>
@ -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

Binary file not shown.

After

Width:  |  Height:  |  Size: 27 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 113 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 20 KiB

View file

@ -0,0 +1,9 @@
<?xml version="1.0" encoding="utf-8"?>
<browserconfig>
<msapplication>
<tile>
<square150x150logo src="/_api/public/favicon/mstile-150x150.png"/>
<TileColor>#00a300</TileColor>
</tile>
</msapplication>
</browserconfig>

Binary file not shown.

After

Width:  |  Height:  |  Size: 1.3 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 2.5 KiB

BIN
public/favicon/favicon.ico Normal file

Binary file not shown.

After

Width:  |  Height:  |  Size: 15 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 17 KiB

View file

@ -0,0 +1,19 @@
{
"name": "",
"short_name": "",
"icons": [
{
"src": "/_api/public/favicon/android-chrome-192x192.png",
"sizes": "192x192",
"type": "image/png"
},
{
"src": "/_api/public/favicon/android-chrome-512x512.png",
"sizes": "512x512",
"type": "image/png"
}
],
"theme_color": "#ffffff",
"background_color": "#ffffff",
"display": "standalone"
}

Binary file not shown.

Before

Width:  |  Height:  |  Size: 11 KiB

After

Width:  |  Height:  |  Size: 17 KiB

Binary file not shown.

Before

Width:  |  Height:  |  Size: 23 KiB

After

Width:  |  Height:  |  Size: 44 KiB

Binary file not shown.

Before

Width:  |  Height:  |  Size: 2.2 KiB

After

Width:  |  Height:  |  Size: 2.6 KiB

Binary file not shown.

Before

Width:  |  Height:  |  Size: 9 KiB

After

Width:  |  Height:  |  Size: 14 KiB

Binary file not shown.

Before

Width:  |  Height:  |  Size: 12 KiB

After

Width:  |  Height:  |  Size: 20 KiB

Binary file not shown.

Before

Width:  |  Height:  |  Size: 13 KiB

After

Width:  |  Height:  |  Size: 21 KiB

Binary file not shown.

Before

Width:  |  Height:  |  Size: 25 KiB

After

Width:  |  Height:  |  Size: 50 KiB

Binary file not shown.

Before

Width:  |  Height:  |  Size: 2 KiB

After

Width:  |  Height:  |  Size: 2.4 KiB

Binary file not shown.

Before

Width:  |  Height:  |  Size: 28 KiB

After

Width:  |  Height:  |  Size: 57 KiB

Binary file not shown.

Before

Width:  |  Height:  |  Size: 3.3 KiB

After

Width:  |  Height:  |  Size: 4.2 KiB

Binary file not shown.

Before

Width:  |  Height:  |  Size: 5.9 KiB

After

Width:  |  Height:  |  Size: 8.1 KiB

Binary file not shown.

Before

Width:  |  Height:  |  Size: 7.4 KiB

After

Width:  |  Height:  |  Size: 11 KiB

Binary file not shown.

Before

Width:  |  Height:  |  Size: 3.9 KiB

After

Width:  |  Height:  |  Size: 5.1 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 5 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 24 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 5 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 4.7 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 14 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 4.7 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 12 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 35 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 12 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 20 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 61 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 20 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 29 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 96 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 29 KiB

Binary file not shown.

Binary file not shown.

Before

Width:  |  Height:  |  Size: 37 KiB

After

Width:  |  Height:  |  Size: 62 KiB

Binary file not shown.

Before

Width:  |  Height:  |  Size: 49 KiB

After

Width:  |  Height:  |  Size: 128 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 1.2 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 3.3 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 3.3 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 5.8 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 2.1 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 5.5 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 5.5 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 9.5 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 3.3 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 8.4 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 8.4 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 14 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 427 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 14 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 24 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 8 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 19 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 22 KiB

View file

@ -0,0 +1,10 @@
{
"rust-analyzer.check.overrideCommand": [
"cargo",
"component",
"check",
"--workspace",
"--all-targets",
"--message-format=json"
],
}