From de0f4d8750b45463f89f7e13c5db4d3ed0aa225b Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Martin=20Kav=C3=ADk?= Date: Sun, 16 Jun 2024 18:29:25 +0200 Subject: [PATCH] clear_variables --- backend/src/main.rs | 17 +++++---- frontend/src/controls_panel.rs | 62 +++++++++++++++++++++++++++++++- frontend/src/main.rs | 9 ++++- frontend/src/platform/browser.rs | 14 ++++---- frontend/src/script_bridge.rs | 18 ++++++---- frontend/src/waveform_panel.rs | 5 ++- 6 files changed, 98 insertions(+), 27 deletions(-) diff --git a/backend/src/main.rs b/backend/src/main.rs index 7043f81..fe6bfd7 100644 --- a/backend/src/main.rs +++ b/backend/src/main.rs @@ -1,15 +1,14 @@ use moon::*; async fn frontend() -> Frontend { - Frontend::new().title("FastWave").append_to_head(concat!( - "" - )).append_to_head(concat!( - "" - )) + Frontend::new() + .title("FastWave") + .append_to_head(concat!("")) + .append_to_head(concat!( + "" + )) } async fn up_msg_handler(_: UpMsgRequest<()>) {} diff --git a/frontend/src/controls_panel.rs b/frontend/src/controls_panel.rs index 69fff23..ad3e215 100644 --- a/frontend/src/controls_panel.rs +++ b/frontend/src/controls_panel.rs @@ -1,4 +1,4 @@ -use crate::{platform, Layout}; +use crate::{platform, script_bridge, Layout}; use std::cell::Cell; use std::mem; use std::ops::Not; @@ -108,6 +108,7 @@ impl ControlsPanel { .item(self.load_button()) .item(self.layout_switcher()), ) + .item(self.command_panel()) .item_signal( self.hierarchy .signal_cloned() @@ -256,6 +257,65 @@ impl ControlsPanel { }) } + fn command_panel(&self) -> impl Element { + let command_result: Mutable>> = <_>::default(); + Row::new() + .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 { + let (script, script_signal) = Mutable::new_and_signal_cloned(String::new()); + TextArea::new() + .placeholder(Placeholder::new("FW.say_hello()")) + .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(); + let result = script_bridge::strict_eval(&script.lock_ref()); + command_result.set(Some(result)); + } + } + }) + } + + fn command_result_panel( + &self, + command_result: ReadOnlyMutable>>, + ) -> impl Element { + El::new().child_signal( + command_result + .signal_cloned() + .map_some(|result| match result { + 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!("{js_value:?}") + } + } + Err(js_value) => { + format!("Error: {js_value:?}") + } + }), + ) + } + fn scopes_panel(&self, hierarchy: Rc) -> impl Element { Column::new() .s(Height::fill().min(150)) diff --git a/frontend/src/main.rs b/frontend/src/main.rs index 847d045..ef7859d 100644 --- a/frontend/src/main.rs +++ b/frontend/src/main.rs @@ -17,6 +17,13 @@ enum Layout { Columns, } +#[derive(Default)] +struct Store { + selected_var_refs: MutableVec, +} + +static STORE: Lazy = lazy::default(); + fn main() { start_app("app", root); Task::start(async { @@ -28,7 +35,7 @@ fn main() { fn root() -> impl Element { let hierarchy: Mutable>> = <_>::default(); - let selected_var_refs: MutableVec = <_>::default(); + let selected_var_refs = STORE.selected_var_refs.clone(); let layout: Mutable = <_>::default(); Column::new() .s(Height::fill()) diff --git a/frontend/src/platform/browser.rs b/frontend/src/platform/browser.rs index 09f94fb..8fcb001 100644 --- a/frontend/src/platform/browser.rs +++ b/frontend/src/platform/browser.rs @@ -4,11 +4,11 @@ use wellen::simple::Waveform; use zoon::*; #[derive(Default)] -struct Store { +struct BrowserPlatformStore { waveform: Mutex>, } -static STORE: Lazy = lazy::default(); +static BROWSER_PLATFORM_STORE: Lazy = lazy::default(); pub(super) async fn show_window() {} @@ -25,7 +25,7 @@ pub(super) async fn pick_and_load_waveform( let Ok(waveform) = waveform else { panic!("Waveform file reading failed") }; - *STORE.waveform.lock().unwrap_throw() = Some(waveform); + *BROWSER_PLATFORM_STORE.waveform.lock().unwrap_throw() = Some(waveform); Some(file.name()) } @@ -63,12 +63,12 @@ pub(super) async fn pick_and_load_waveform( // let Ok(waveform) = waveform else { // panic!("Waveform file reading failed") // }; -// *STORE.waveform.lock().unwrap_throw() = Some(waveform); +// *BROWSER_PLATFORM_STORE.waveform.lock().unwrap_throw() = Some(waveform); // Some(file.name()) // } pub(super) async fn get_hierarchy() -> wellen::Hierarchy { - let waveform = STORE.waveform.lock().unwrap_throw(); + let waveform = BROWSER_PLATFORM_STORE.waveform.lock().unwrap_throw(); let hierarchy = waveform.as_ref().unwrap_throw().hierarchy(); // @TODO Wrap `hierarchy` in `Waveform` with `Rc/Arc` or add the method `take` / `clone` or refactor? serde_json::from_value(serde_json::to_value(hierarchy).unwrap_throw()).unwrap_throw() @@ -82,7 +82,7 @@ pub(super) async fn load_signal_and_get_timeline( block_height: u32, var_format: shared::VarFormat, ) -> shared::Timeline { - let mut waveform_lock = STORE.waveform.lock().unwrap(); + let mut waveform_lock = BROWSER_PLATFORM_STORE.waveform.lock().unwrap(); let waveform = waveform_lock.as_mut().unwrap(); waveform.load_signals_multi_threaded(&[signal_ref]); let signal = waveform.get_signal(signal_ref).unwrap(); @@ -100,7 +100,7 @@ pub(super) async fn load_signal_and_get_timeline( } pub(super) async fn unload_signal(signal_ref: wellen::SignalRef) { - let mut waveform_lock = STORE.waveform.lock().unwrap_throw(); + let mut waveform_lock = BROWSER_PLATFORM_STORE.waveform.lock().unwrap_throw(); let waveform = waveform_lock.as_mut().unwrap_throw(); waveform.unload_signals(&[signal_ref]); } diff --git a/frontend/src/script_bridge.rs b/frontend/src/script_bridge.rs index 027524e..31d66bc 100644 --- a/frontend/src/script_bridge.rs +++ b/frontend/src/script_bridge.rs @@ -1,6 +1,9 @@ -use zoon::{*, println}; +use crate::STORE; +use zoon::*; -#[wasm_bindgen(inline_js = r#"export function strict_eval(code) { return eval?.(`"use strict"; ${code};`) }"#)] +#[wasm_bindgen( + inline_js = r#"export function strict_eval(code) { "use strict"; return eval?.(`${code}`) }"# +)] extern "C" { #[wasm_bindgen(catch)] pub fn strict_eval(code: &str) -> Result; @@ -11,11 +14,14 @@ pub struct FW; #[wasm_bindgen] impl FW { - pub fn do_something() { - println!("Command result: {:#?}", strict_eval("FW.do_something_else();")); + pub fn say_hello() -> String { + "Hello!".to_owned() } - pub fn do_something_else() { - println!("ELSE!"); + pub fn clear_variables() -> String { + let mut vars = STORE.selected_var_refs.lock_mut(); + let var_count = vars.len(); + vars.clear(); + format!("{var_count} variables cleared") } } diff --git a/frontend/src/waveform_panel.rs b/frontend/src/waveform_panel.rs index db09a44..2493ea9 100644 --- a/frontend/src/waveform_panel.rs +++ b/frontend/src/waveform_panel.rs @@ -130,9 +130,8 @@ impl WaveformPanel { ) .await; - let timescale = hierarchy.timescale(); - // @TODO remove - zoon::println!("{timescale:?}"); + // @TODO render timeline with time units + // let timescale = hierarchy.timescale(); // Note: Sync `timeline`'s type with the `Timeline` in `frontend/typescript/pixi_canvas/pixi_canvas.ts' let timeline = serde_wasm_bindgen::to_value(&timeline).unwrap_throw();