diff --git a/frontend/src/controls_panel.rs b/frontend/src/controls_panel.rs index ad3e215..c2734ba 100644 --- a/frontend/src/controls_panel.rs +++ b/frontend/src/controls_panel.rs @@ -260,6 +260,7 @@ impl ControlsPanel { fn command_panel(&self) -> impl Element { let command_result: Mutable>> = <_>::default(); Row::new() + .s(Gap::both(30)) .item(self.command_editor_panel(command_result.clone())) .item(self.command_result_panel(command_result.read_only())) } @@ -267,10 +268,36 @@ impl ControlsPanel { fn command_editor_panel( &self, command_result: Mutable>>, + ) -> impl Element { + Column::new() + .s(Gap::new().y(10)) + .item( + Row::new() + .s(Gap::new().x(15)) + .s(Padding::new().x(5)) + .item(El::new().child("Javascript command")) + .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() - .placeholder(Placeholder::new("FW.say_hello()")) + .s(Background::new().color(color!("SlateBlue"))) + .s(Padding::new().x(10).y(8)) + .s(RoundedCorners::all(15)) + .s(Height::default().min(50)) + .s(Width::default().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 to MZ API? (together with autocomplete and others?) + .update_raw_el(|raw_el| raw_el.attr("spellcheck", "false")) + .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| { @@ -294,11 +321,28 @@ impl ControlsPanel { &self, command_result: ReadOnlyMutable>>, ) -> impl Element { - El::new().child_signal( - command_result - .signal_cloned() - .map_some(|result| match result { - Ok(js_value) => { + Column::new() + .s(Gap::new().y(10)) + .s(Align::new().top()) + .s(Scrollbars::both()) + .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| 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() { @@ -309,9 +353,10 @@ impl ControlsPanel { format!("{js_value:?}") } } - Err(js_value) => { + Some(Err(js_value)) => { format!("Error: {js_value:?}") } + None => "-".to_owned() }), ) } diff --git a/frontend/src/waveform_panel/pixi_canvas.rs b/frontend/src/waveform_panel/pixi_canvas.rs index 532eded..f43d00f 100644 --- a/frontend/src/waveform_panel/pixi_canvas.rs +++ b/frontend/src/waveform_panel/pixi_canvas.rs @@ -89,8 +89,9 @@ impl PixiCanvas { })) .update_raw_el(|raw_el| { // @TODO rewrite to a native Zoon API - raw_el.event_handler( + raw_el.event_handler_with_options(EventOptions::new().preventable(), clone!((controller) move |event: events_extra::WheelEvent| { + event.prevent_default(); if let Some(controller) = controller.lock_ref().as_ref() { controller.zoom_or_pan( event.delta_y(),