use codespan_reporting::term::{emit, termcolor::NoColor, Config}; use g_code::parse::{into_diagnostic, snippet_parser}; use gloo_file::futures::read_as_text; use gloo_timers::callback::Timeout; use paste::paste; use roxmltree::Document; use std::num::ParseFloatError; use web_sys::{FileList, HtmlElement}; use yew::prelude::*; use yewdux::prelude::{BasicStore, Dispatcher}; use yewdux_functional::use_store; use yewdux_input::*; use crate::{ spectre::*, state::{AppState, AppStore, FormState, FormStore, Svg}, }; // TODO: make a nice, syntax highlighting editor for g-code. // I started on this but it quickly got too complex. // pub struct GCodeEditor { // props: GCodeEditorProps, // dispatch: AppDispatch, // state: Rc, // validation_task: Option, // link: ComponentLink, // parsed: Option>, // node_ref: NodeRef, // } // pub enum InputMessage { // Validate(String), // State(Rc), // Change(InputData), // } // impl Component for GCodeEditor { // type Message = InputMessage; // type Properties = GCodeEditorProps; // fn create(props: Self::Properties, link: ComponentLink) -> Self { // Self { // props, // dispatch: Dispatch::bridge_state(link.callback(InputMessage::State)), // state: Default::default(), // validation_task: None, // link, // parsed: None, // node_ref: NodeRef::default(), // } // } // fn update(&mut self, msg: Self::Message) -> ShouldRender { // match msg { // InputMessage::State(state) => { // self.state = state; // true // } // InputMessage::Validate(value) => { // self.parsed = Some(snippet_parser(&value).map(|snippet| { // html! { // <> // { // for snippet.iter_emit_tokens().flat_map(|token| { // if let Token::Field(field) = &token { // vec![ // html! { // {field.letters.to_string()} // }, // { // let class = match &field.value { // Value::Rational(_) | Value::Integer(_) | Value::Float(_) => "hljs-number", // Value::String(_) => "hljs-string", // }; // html! { // {field.value.to_string()} // } // } // ] // } else if let Token::Newline{..} = &token { // vec![ // html! { // "\r\n" // } // ] // } // else { // let class = match &token { // Token::Comment{..} => "hljs-comment", // Token::Checksum(..) => "hljs-number", // Token::Whitespace(..) => "whitespace", // Token::Newline{..} => "newline", // Token::Percent => "hljs-keyword", // _ => unreachable!(), // }; // vec![html!{ // // { token.to_string() } // // }] // } // }) // } // // } // }).map_err(|err| { // let mut buf = Buffer::no_color(); // let config = Config::default(); // emit( // &mut buf, // &config, // &codespan_reporting::files::SimpleFile::new("", value), // &into_diagnostic(&err), // ) // .unwrap(); // String::from_utf8_lossy(buf.as_slice()).to_string() // })); // true // } // InputMessage::Change(InputData { value, .. }) => { // self.parsed = None; // self.validation_task = None; // self.validation_task = Some(TimeoutService::spawn( // self.props.validation_timeout, // self.link // .callback(move |_| InputMessage::Validate(value.clone())), // )); // true // } // } // } // fn change(&mut self, props: Self::Properties) -> ShouldRender { // self.props.neq_assign(props) // } // fn view(&self) -> Html { // let oninput = self.link.callback(|x: InputData| InputMessage::Change(x)); // html! { // <> //
//