From cd8be60b789c7ab4ccfc2abac2044e659441f054 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Maciej=20Miko=C5=82ajek?= Date: Fri, 21 Aug 2020 11:16:54 +0200 Subject: [PATCH] Documentation View (https://github.com/enso-org/ide/pull/702) Original commit: https://github.com/enso-org/ide/commit/d7fabd103b334fc914a47a0fe8d29f1030be0c3d --- gui/docs/product/shortcuts.md | 7 +- gui/src/rust/Cargo.lock | 1 + gui/src/rust/ide/lib/view/Cargo.toml | 1 + gui/src/rust/ide/lib/view/src/graph_editor.rs | 110 +++-- .../builtin/visualization/native.rs | 2 + .../visualization/native/documentation.rs | 256 +++++++++++ .../native/documentation/style.css | 431 ++++++++++++++++++ .../component/visualization/data.rs | 29 ++ .../component/visualization/path.rs | 2 +- 9 files changed, 809 insertions(+), 30 deletions(-) create mode 100644 gui/src/rust/ide/lib/view/src/graph_editor/builtin/visualization/native/documentation.rs create mode 100644 gui/src/rust/ide/lib/view/src/graph_editor/builtin/visualization/native/documentation/style.css diff --git a/gui/docs/product/shortcuts.md b/gui/docs/product/shortcuts.md index 8b97d4b958b..4ec00cb5d81 100644 --- a/gui/docs/product/shortcuts.md +++ b/gui/docs/product/shortcuts.md @@ -54,12 +54,13 @@ tags: [product,ui] | Shortcut | Action | | -------- | ------ | -| cmd / ctrl + space | Toggle visualization visibility of the selected node. | -| cmd / ctrl + f | Cycle visualizations of the selected node. | +| cmd / ctrl + space | Toggle visualization visibility of the selected node. | +| cmd / ctrl + f | Cycle visualizations of the selected node. | +| cmd / ctrl + \\ | Toggle documentation view visibility | ### Debug | Shortcut | Action | | -------- | ------ | -| cmd / ctrl + d | Send test data to the selected node. | +| cmd / ctrl + d | Send test data to the selected node. | | cmd / ctrl + shift + enter | Push a hardcoded breadcrumb without navigating. | | cmd / ctrl + shift + arrow up | Pop a breadcrumb without navigating. | diff --git a/gui/src/rust/Cargo.lock b/gui/src/rust/Cargo.lock index cf53f556c02..08d5b51fc29 100644 --- a/gui/src/rust/Cargo.lock +++ b/gui/src/rust/Cargo.lock @@ -1197,6 +1197,7 @@ dependencies = [ "js-sys 0.3.35 (registry+https://github.com/rust-lang/crates.io-index)", "logger 0.1.0", "nalgebra 0.21.1 (registry+https://github.com/rust-lang/crates.io-index)", + "parser 0.1.0", "serde 1.0.114 (registry+https://github.com/rust-lang/crates.io-index)", "serde_json 1.0.56 (registry+https://github.com/rust-lang/crates.io-index)", "span-tree 0.1.0", diff --git a/gui/src/rust/ide/lib/view/Cargo.toml b/gui/src/rust/ide/lib/view/Cargo.toml index cf19ae51bf1..2228849698b 100644 --- a/gui/src/rust/ide/lib/view/Cargo.toml +++ b/gui/src/rust/ide/lib/view/Cargo.toml @@ -15,6 +15,7 @@ ensogl = { version = "0.1.0", path = "../../../ensogl" ensogl-text = { version = "0.1.0", path = "../../../ensogl/lib/text" } ensogl-text-msdf-sys = { version = "0.1.0", path = "../../../ensogl/lib/text/msdf-sys" } enso-shapely = { version = "0.1.0", path = "../../../lib/enso-shapely/impl" } +parser = { version = "0.1.0", path = "../parser" } span-tree = { version = "0.1.0", path = "../span-tree" } logger = { version = "0.1.0", path = "../../../lib/logger" } enso-protocol = { version = "0.1.0", path = "../../../ide/lib/enso-protocol" } diff --git a/gui/src/rust/ide/lib/view/src/graph_editor.rs b/gui/src/rust/ide/lib/view/src/graph_editor.rs index e8ced2040c3..2855dc1b9f0 100644 --- a/gui/src/rust/ide/lib/view/src/graph_editor.rs +++ b/gui/src/rust/ide/lib/view/src/graph_editor.rs @@ -18,10 +18,12 @@ pub mod component; pub mod builtin; pub mod data; +use crate::graph_editor::builtin::visualization::native::documentation; use crate::graph_editor::component::node; use crate::graph_editor::component::type_coloring::MISSING_TYPE_COLOR; -use crate::graph_editor::component::visualization::MockDataGenerator3D; use crate::graph_editor::component::visualization; +use crate::graph_editor::component::visualization::MockDataGenerator3D; +use crate::graph_editor::component::visualization::MockDocGenerator; use enso_frp as frp; use ensogl::application::Application; @@ -314,6 +316,13 @@ ensogl::def_command_api! { Commands /// Disable mode in which the pressed node will be edited. edit_mode_off, + + /// Documentation open press event. In case the event will be shortly followed by `release_documentation_view_visibility`, the documentation will be shown permanently. In other case, it will be disabled as soon as the `release_documentation_view_visibility` is emitted. + press_documentation_view_visibility, + /// Documentation open release event. See `press_documentation_view_visibility` to learn more. + release_documentation_view_visibility, + + /// Enable nodes multi selection mode. It works like inverse mode for single node selection and like merge mode for multi node selection mode. enable_node_multi_select, /// Disable nodes multi selection mode. It works like inverse mode for single node selection and like merge mode for multi node selection mode. @@ -387,6 +396,7 @@ pub struct FrpInputs { pub set_visualization : frp::Source<(NodeId,Option)>, pub register_visualization : frp::Source>, pub set_visualization_data : frp::Source<(NodeId,visualization::Data)>, + pub set_documentation_data : frp::Source, hover_node_input : frp::Source>, hover_node_output : frp::Source>, @@ -425,6 +435,7 @@ impl FrpInputs { cycle_visualization <- source(); set_visualization <- source(); register_visualization <- source(); + set_documentation_data <- source(); hover_node_input <- source(); hover_node_output <- source(); @@ -441,9 +452,9 @@ impl FrpInputs { ,unset_edge_source,unset_edge_target ,set_node_position,set_expression_type,set_method_pointer,select_node,remove_node ,set_node_expression,connect_nodes,deselect_all_nodes,cycle_visualization - ,set_visualization,register_visualization,some_edge_targets_detached - ,some_edge_sources_detached,all_edge_targets_attached,hover_node_input - ,all_edge_sources_attached,hover_node_output,press_node_output + ,set_visualization,register_visualization,set_documentation_data + ,some_edge_targets_detached,some_edge_sources_detached,all_edge_targets_attached + ,hover_node_input,all_edge_sources_attached,hover_node_output,press_node_output ,set_detached_edge_sources,all_edges_attached } } @@ -543,11 +554,12 @@ generate_frp_outputs! { connection_added : EdgeId, connection_removed : EdgeId, - visualization_enabled : NodeId, - visualization_disabled : NodeId, + visualization_enabled : NodeId, + visualization_disabled : NodeId, visualization_enable_fullscreen : NodeId, visualization_set_preprocessor : (NodeId,data::EnsoCode), + documentation_visible : bool, } @@ -1094,15 +1106,16 @@ impl GraphEditorModelWithNetwork { #[derive(Debug,Clone,CloneRef)] pub struct GraphEditorModel { - pub logger : Logger, - pub display_object : display::object::Instance, - pub app : Application, - pub breadcrumbs : component::Breadcrumbs, - pub cursor : cursor::Cursor, - pub nodes : Nodes, - pub edges : Edges, - touch_state : TouchState, - frp : FrpInputs, + pub logger : Logger, + pub display_object : display::object::Instance, + pub app : Application, + pub breadcrumbs : component::Breadcrumbs, + pub cursor : cursor::Cursor, + pub nodes : Nodes, + pub edges : Edges, + pub documentation_view : documentation::View, + touch_state : TouchState, + frp : FrpInputs, } @@ -1115,17 +1128,20 @@ impl GraphEditorModel { , network : &frp::Network , focus_manager : &FocusManager ) -> Self { - let scene = app.display.scene(); - let logger = Logger::new("GraphEditor"); - let display_object = display::object::Instance::new(&logger); - let nodes = Nodes::new(&logger); -// let visualizations = Stage::new(scene.clone_ref(), Logger::new("VisualisationCollection")); - let edges = default(); - let frp = FrpInputs::new(network); - let touch_state = TouchState::new(network,&scene.mouse.frp); - let breadcrumbs = component::Breadcrumbs::new(scene,focus_manager); - let app = app.clone_ref(); - Self {logger,display_object,app,cursor,nodes,edges,touch_state,frp,breadcrumbs}.init()//visualizations } + let scene = app.display.scene(); + let logger = Logger::new("GraphEditor"); + let display_object = display::object::Instance::new(&logger); + let nodes = Nodes::new(&logger); + let documentation_view = documentation::View::new(&scene); + let edges = default(); + let frp = FrpInputs::new(network); + let touch_state = TouchState::new(network,&scene.mouse.frp); + let breadcrumbs = component::Breadcrumbs::new(scene,focus_manager); + display_object.add_child(&documentation_view); + display_object.remove_child(&documentation_view); + let app = app.clone_ref(); + Self {logger,display_object,app,cursor,nodes,edges,touch_state,frp,breadcrumbs, + documentation_view}.init() } fn init(self) -> Self { @@ -1215,6 +1231,15 @@ impl GraphEditorModel { } } + fn set_documentation_visibility(&self, is_visible:bool) { + if is_visible { self.app.remove_child(&self.documentation_view) } + else { self.app.add_child(&self.documentation_view) } + } + + fn is_documentation_visible(&self) -> bool { + self.documentation_view.has_parent() + } + /// Warning! This function does not remove connected edges. It needs to be handled by the /// implementation. fn remove_node(&self, node_id:impl Into) { @@ -1571,6 +1596,8 @@ impl application::shortcut::DefaultShortcutProvider for GraphEditor { , Self::self_shortcut(shortcut::Action::press (&[Key::Control,Key::Character(" ".into())],&[]) , "press_visualization_visibility") , Self::self_shortcut(shortcut::Action::double_press (&[Key::Control,Key::Character(" ".into())],&[]) , "double_press_visualization_visibility") , Self::self_shortcut(shortcut::Action::release (&[Key::Control,Key::Character(" ".into())],&[]) , "release_visualization_visibility") + , Self::self_shortcut(shortcut::Action::press (&[Key::Control,Key::Character("\\".into())],&[]) , "press_documentation_view_visibility") + , Self::self_shortcut(shortcut::Action::release (&[Key::Control,Key::Character("\\".into())],&[]) , "release_documentation_view_visibility") , Self::self_shortcut(shortcut::Action::press (&[Key::Meta],&[]) , "toggle_node_multi_select") , Self::self_shortcut(shortcut::Action::release (&[Key::Meta],&[]) , "toggle_node_multi_select") , Self::self_shortcut(shortcut::Action::press (&[Key::Control],&[]) , "toggle_node_multi_select") @@ -2284,6 +2311,12 @@ fn new_graph_editor(app:&Application) -> GraphEditor { let data = visualization::Data::from(content); inputs.set_visualization_data.emit((*node_id,data)); } + + let mock_documentaion = MockDocGenerator::default(); + let data = mock_documentaion.generate_data(); + let content = serde_json::to_value(data).unwrap_or_default(); + let data = visualization::Data::from(content); + inputs.set_documentation_data.emit(data); })); def _set_data = inputs.set_visualization_data.map(f!([nodes]((node_id,data)) { @@ -2413,6 +2446,31 @@ fn new_graph_editor(app:&Application) -> GraphEditor { } + // === Documentation Set === + + frp::extend! { network + + eval inputs.set_documentation_data ((data) model.documentation_view.frp.send_data.emit(data)); + + + // === Documentation toggle === + + let documentation_press_ev = inputs.press_documentation_view_visibility.clone_ref(); + let documentation_release = inputs.release_documentation_view_visibility.clone_ref(); + documentation_pressed <- bool(&documentation_release,&documentation_press_ev); + documentation_was_pressed <- documentation_pressed.previous(); + documentation_press <- documentation_press_ev.gate_not(&documentation_was_pressed); + documentation_press_on_off <- documentation_press.map(f_!(model.is_documentation_visible())); + outputs.documentation_visible <+ documentation_press_on_off; + + + // === OUTPUTS REBIND === + + eval outputs.documentation_visible ((vis) model.set_documentation_visibility(*vis)); + + } + + // === Remove Edge === frp::extend! { network diff --git a/gui/src/rust/ide/lib/view/src/graph_editor/builtin/visualization/native.rs b/gui/src/rust/ide/lib/view/src/graph_editor/builtin/visualization/native.rs index d2acc43370b..7919895c333 100644 --- a/gui/src/rust/ide/lib/view/src/graph_editor/builtin/visualization/native.rs +++ b/gui/src/rust/ide/lib/view/src/graph_editor/builtin/visualization/native.rs @@ -1,7 +1,9 @@ //! Examples of defining visualization in Rust using web_sys or ensogl. pub mod bubble_chart; +pub mod documentation; pub mod raw_text; pub use bubble_chart::*; +pub use documentation::*; pub use raw_text::*; diff --git a/gui/src/rust/ide/lib/view/src/graph_editor/builtin/visualization/native/documentation.rs b/gui/src/rust/ide/lib/view/src/graph_editor/builtin/visualization/native/documentation.rs new file mode 100644 index 00000000000..246d3423413 --- /dev/null +++ b/gui/src/rust/ide/lib/view/src/graph_editor/builtin/visualization/native/documentation.rs @@ -0,0 +1,256 @@ +//! Documentation view visualization generating and presenting Enso Documentation under +//! the documented node. + +use crate::prelude::*; + +use crate::graph_editor::component::visualization; + +use ast::prelude::FallibleResult; +use enso_frp as frp; +use ensogl::display; +use ensogl::display::DomSymbol; +use ensogl::display::scene::Scene; +use ensogl::system::web; +use ensogl::system::web::StyleSetter; + + + +// ================= +// === Constants === +// ================= + +pub const VIEW_WIDTH : f32 = 300.0; +pub const VIEW_MARGIN : f32 = 15.0; + +/// Content in the documentation view when there is no data available. +const PLACEHOLDER_STR : &str = "

Documentation Viewer

No documentation available

"; +const CORNER_RADIUS : f32 = crate::graph_editor::component::node::CORNER_RADIUS; + +/// Get documentation view stylesheet from a CSS file. +/// +/// TODO [MM] : This file is generated currently from SASS file, and generated code should never +/// be included in a codebase, so it will be moved to rust-based generator to achieve +/// compatibility with IDE's theme manager. +/// Expect them to land with https://github.com/enso-org/ide/issues/709 +fn documentation_style() -> String { + format!("", include_str!("documentation/style.css")) +} + + + +// ================= +// === ViewModel === +// ================= + +/// Model of Native visualization that generates documentation for given Enso code and embeds +/// it in a HTML container. +#[derive(Clone,CloneRef,Debug)] +#[allow(missing_docs)] +pub struct ViewModel { + logger : Logger, + dom : DomSymbol, + size : Rc>, +} + +impl ViewModel { + /// Constructor. + fn new(scene:&Scene) -> Self { + let logger = Logger::new("DocumentationView"); + let div = web::create_div(); + let dom = DomSymbol::new(&div); + let screen = scene.camera().screen(); + let view_height = screen.height - (VIEW_MARGIN * 2.0); + let size_vec = Vector2(VIEW_WIDTH, view_height); + let size = Rc::new(Cell::new(size_vec)); + + dom.dom().set_style_or_warn("white-space" ,"normal" ,&logger); + dom.dom().set_style_or_warn("overflow-y" ,"auto" ,&logger); + dom.dom().set_style_or_warn("overflow-x" ,"auto" ,&logger); + dom.dom().set_style_or_warn("background-color","rgba(255, 255, 255, 0.85)" ,&logger); + dom.dom().set_style_or_warn("padding" ,"5px" ,&logger); + dom.dom().set_style_or_warn("pointer-events" ,"auto" ,&logger); + dom.dom().set_style_or_warn("border-radius" ,format!("{}px",CORNER_RADIUS),&logger); + dom.dom().set_style_or_warn("width" ,format!("{}px",VIEW_WIDTH) ,&logger); + dom.dom().set_style_or_warn("height" ,format!("{}px",view_height) ,&logger); + + scene.dom.layers.main.manage(&dom); + ViewModel {logger,dom,size}.init() + } + + fn init(self) -> Self { + self.reload_style(); + self + } + + /// Set size of the documentation view. + fn set_size(&self, size:Vector2) { + self.size.set(size); + self.reload_style(); + } + + /// Generate HTML documentation from documented Enso code. + fn gen_html_from(program:String) -> FallibleResult { + let parser = parser::DocParser::new()?; + let output = parser.generate_html_docs(program); + Ok(output?) + } + + /// Prepare data string for Doc Parser to work with after deserialization. + /// FIXME [MM]: Removes characters that are not supported by Doc Parser yet. + /// https://github.com/enso-org/enso/issues/1063 + fn prepare_data_string(data_inner:&visualization::Json) -> String { + let data_str = serde_json::to_string_pretty(&**data_inner); + let data_str = data_str.unwrap_or_else(|e| format!("",e)); + let data_str = data_str.replace("\\n", "\n"); + data_str.replace("\"", "") + } + + /// Create a container for generated content and embed it with stylesheet. + fn push_to_dom(&self, content:String) { + let data_str = format!(r#"
{}{}
"#,documentation_style(),content); + self.dom.dom().set_inner_html(&data_str) + } + + /// Receive data, process and present it in the documentation view. + fn receive_data(&self, data:&visualization::Data) -> Result<(),visualization::DataError> { + let data_inner = match data { + visualization::Data::Json {content} => content, + _ => todo!(), + }; + + let data_str = ViewModel::prepare_data_string(data_inner); + let output = ViewModel::gen_html_from(data_str); + let mut output = output.unwrap_or_else(|_| String::from(PLACEHOLDER_STR)); + if output == "" { output = String::from(PLACEHOLDER_STR) } + // FIXME [MM] : Because of how Doc Parser was implemented in Engine repo, there is need to + // remove stylesheet link from generated code, that would otherwise point to + // non-existing file, as now stylesheet is connected by include_str! macro, and + // soon will be replaced by a style generator. + // This hack will be removed when https://github.com/enso-org/enso/issues/1063 + // will land in Engine's repo, also fixing non-existent character bug. + let import_css = r#""#; + let output = output.replace(import_css, ""); + + self.push_to_dom(output); + Ok(()) + } + + /// Load an HTML file into the documentation view when user is waiting for data to be received. + /// TODO [MM] : This should be replaced with a EnsoGL spinner in the next PR. + fn load_waiting_screen(&self) { + let spinner = r#" +
+ +
+
+
+
+
+
+ "#; + self.push_to_dom(String::from(spinner)) + } + + fn reload_style(&self) { + self.dom.set_size(self.size.get()); + } +} + + + +// ============ +// === View === +// ============ + +/// View of the visualization that renders the given documentation as a HTML page. +#[derive(Clone,CloneRef,Debug,Shrinkwrap)] +#[allow(missing_docs)] +pub struct View { + #[shrinkwrap(main_field)] + pub model : ViewModel, + pub frp : visualization::instance::Frp, + network : frp::Network, +} + +impl View { + /// Definition of this visualization. + pub fn definition() -> visualization::Definition { + let path = visualization::Path::builtin("Documentation View"); + visualization::Definition::new( + visualization::Signature::new_for_any_type(path,visualization::Format::Json), + |scene| { Ok(Self::new(scene).into()) } + ) + } + + /// Constructor. + pub fn new(scene:&Scene) -> Self { + let network = default(); + let frp = visualization::instance::Frp::new(&network); + let model = ViewModel::new(scene); + model.load_waiting_screen(); + Self {model,frp,network} . init(scene) + } + + fn init(self, scene:&Scene) -> Self { + let network = &self.network; + let model = &self.model; + let frp = &self.frp; + frp::extend! { network + eval frp.set_size ((size) model.set_size(*size)); + eval frp.send_data ([frp, model](data) { + if let Err(e) = model.receive_data(data) { + frp.data_receive_error.emit(Some(e)); + } + }); + eval scene.frp.shape([model,frp](shape) { + model.dom.set_position_x((shape.width - VIEW_WIDTH) / 2.0 - VIEW_MARGIN); + frp.set_size.emit(Vector2::new(VIEW_WIDTH,shape.height - (VIEW_MARGIN * 2.0))); + }); + } + self + } +} + +impl From for visualization::Instance { + fn from(t: View) -> Self { + Self::new(&t,&t.frp,&t.network) + } +} + +impl display::Object for View { + fn display_object(&self) -> &display::object::Instance { + &self.dom.display_object() + } +} diff --git a/gui/src/rust/ide/lib/view/src/graph_editor/builtin/visualization/native/documentation/style.css b/gui/src/rust/ide/lib/view/src/graph_editor/builtin/visualization/native/documentation/style.css new file mode 100644 index 00000000000..3451d4c4dab --- /dev/null +++ b/gui/src/rust/ide/lib/view/src/graph_editor/builtin/visualization/native/documentation/style.css @@ -0,0 +1,431 @@ +/* + * TODO [MM] : This file is undergoing drastic changes. + * Expect them to land with https://github.com/enso-org/ide/issues/709 + * This file is currently generated from SASS file, and it is very + * temporary. It will be moved to rust - it will become css generator + * connected with the Theme manager to enable dark mode for documentation. +*/ + +.docVis { + -webkit-font-smoothing: antialiased; + font-style: normal; + word-wrap: break-word; + font-size: 17px; + line-height: 1.52947; + font-weight: 400; + letter-spacing: -0.021em; + font-family: "SF Pro Text", "SF Pro Icons", "Helvetica Neue", "Helvetica", "Arial", sans-serif; + color: #333333; + margin: 0; + padding: 0; +} + +.docVis p { + display: block; + margin-block-start: 1em; + margin-block-end: 1em; + margin-inline-start: 0; + margin-inline-end: 0; +} + +.docVis a:hover { + color: #0070c9 !important; + text-decoration: inherit; +} + +.docVis a { + color: #333333; + background-color: transparent; + text-decoration: inherit; + display: inline-block; + transition: all 0.3s ease; +} + +.docVis img { + display: block; +} + +.docVis code { + color: #0070c9; + background-color: transparent; + font-size: inherit; + font-family: "SF Pro Text", "SF Pro Icons", "Helvetica Neue", "Helvetica", "Arial", sans-serif; + line-height: inherit; + display: inline-block; + white-space: pre-wrap; +} + +.docVis button { + display: inline-block; + padding: 8px 30px; + margin: 10px 0; + outline: none; + background-color: transparent; + border: 1px solid #333333; + color: #333333; + border-radius: 5px; + font-size: 13px; + vertical-align: top; + transition: all 0.3s ease; +} + +.docVis button:hover { + background-color: #333333; + color: #e5e5e5; +} + +.docVis b { + font-weight: 600; +} + +.docVis h1 { + font-size: 34px; + line-height: 1.08824; + font-weight: 500; + letter-spacing: 0.01em; +} + +.docVis h2 { + font-size: 28px; + line-height: 1.1073; + font-weight: 500; + letter-spacing: 0.012em; +} + +.Body h2 { + margin: 0.65rem 0 0; +} + +.docVis li { + padding-left: 10px; +} + +.creator .Unclosed, +.creator .invalidIndent, +.creator .invalidLink { + display: inline; + color: orangered; +} +.creator .Tags .UNRECOGNIZED { + border: 2px solid; + color: orangered; +} + +.Unclosed, +.invalidIndent, +.invalidLink { + display: inline; +} + +.Header { + font-size: 19px; + font-weight: 500; +} + +.Important .Header, +.Info .Header, +.Example .Header { + margin-bottom: 0.7em; + font-weight: 600; + letter-spacing: -0.021em; + line-height: 17px; + font-synthesis: none; + font-family: "SF Pro Text", "SF Pro Icons", "Helvetica Neue", "Helvetica", "Arial", sans-serif; +} + +.Tags { + margin-left: auto; + margin-right: auto; + margin-bottom: 20px; + padding-top: 15px; +} +.Tags .DEPRECATED, +.Tags .MODIFIED, +.Tags .ADDED, +.Tags .UPCOMING, +.Tags .REMOVED, +.Tags .UNRECOGNIZED { + line-height: 1.5; + font-weight: 400; + border-radius: 4px; + font-size: 12px; + letter-spacing: -0.021em; + display: inline-flex; + padding: 5px 15px; + margin: 2px; + white-space: nowrap; + background: transparent; +} +.Tags .DEPRECATED { + border: 1px solid #d20606; + color: #d20606; +} +.Tags .MODIFIED { + border: 1px solid #003ec3; + color: #003ec3; +} +.Tags .ADDED { + border: 1px solid #79A129; + color: #79A129; +} +.Tags .UPCOMING, +.Tags .REMOVED, +.Tags .UNRECOGNIZED { + border: 1px solid #666666; + color: #666666; +} + +.ExtForTagDetails { + margin: 0 3px; + color: #999999; +} + +.Raw, +.Important, +.Info, +.CodeBlock, +.Example { + margin-top: 0; + margin-left: auto; + margin-right: auto; + position: relative; + text-decoration: inherit; +} + +.Body .Raw { + margin-bottom: 0.6rem; + font-size: 17px; + line-height: 1.52947; + font-weight: 400; + letter-spacing: -0.021em; + font-family: "SF Pro Text", "SF Pro Icons", "Helvetica Neue", "Helvetica", "Arial", sans-serif; + color: #333333; + font-style: normal; +} + +.Important, +.Info, +.CodeBlock, +.Example { + font-size: 17px; + padding: 15px 10px 15px 20px; + border: 0; + border-radius: 6px; + margin: 0.7em 0; +} + +.Important { + background-color: #FBECC2; +} + +.Info { + background-color: #D6E1CA; +} + +.Example { + background-color: #fafafa; +} + +.CodeBlock { + background-color: #fefefe; + margin: 10px 20px; + display: none; +} +.CodeBlock code { + font-family: monospace; +} + +.Def { + margin: 40px auto auto; + padding: 0 15px; + text-decoration: inherit; +} +.Def .Synopsis, +.Def .Body, +.Def .Tags, +.Def .ASTData { + padding-left: 0; + text-decoration: inherit; +} +.Def .Synopsis { + padding: 0; + margin-bottom: 15px; + font-size: 17px; + font-weight: 400; + color: #333333; + font-style: normal; +} +.Def .constr { + padding: 25px 0; + margin: 0; +} +.Def .DefDoc .Body { + display: none; +} +.Def .DefDoc .documentation { + display: inline-flex; + width: 100%; + margin-bottom: 10px; +} +.Def .DefDoc .documentation .ASTHead { + width: 30% !important; + margin: 10px 0; +} +.Def .DefDoc .documentation .ASTHead .DefTitle, +.Def .DefDoc .documentation .ASTHead .Infix { + padding: 0; + font-size: 17px; + font-weight: 400; + font-style: normal; + text-decoration: inherit; +} +.Def .DefDoc .documentation .ASTData { + width: 70% !important; +} +.Def .DefDoc .documentation .Doc { + text-decoration: inherit; +} +.Def .DefDoc .documentation .Doc .Synopsis { + text-decoration: inherit; + margin: 10px 0; +} +.Def .DefDoc .documentation .Tags { + margin: 2px 0 0 auto; + padding: 0; +} +.Def .DefNoDoc { + padding-bottom: 10px; +} + +.DefTitle { + display: inline-flex; + font-size: x-large; + font-weight: 400; + margin-bottom: 20px; +} + +.DefArgs { + margin-left: 5px; + font-weight: 400; + color: #0070c9; +} + +.Synopsis, +.Body { + margin: 0 auto; + padding: 5px; + text-align: left; +} + +.Synopsis { + margin-top: 35px; + font-size: 20px; +} + +.Documentation .ASTData, +.Documentation .ASTHead { + text-align: left; + line-height: 1.05; + border-radius: 6px; +} +.Documentation .ASTData { + width: 100%; + background-color: #fafafa; +} +.Documentation .ASTHead { + margin: 20px auto 5px; + /*background-color: #fafafa;*/ +} +.Documentation .ASTHead .DefTitle { + font-size: 42px; + margin: 0; +} +.Documentation .ASTData .ASTHead { + /*background-color: #fafafa;*/ +} +.Documentation .ASTData .ASTHead .DefTitle { + font-size: x-large; +} +.Documentation .Documented { + margin: 0; + width: 100%; + background-color: #ffffff; +} +.Documentation .DefNoBody { + text-decoration: inherit; +} + +@media (max-width: 500px) { + .Synopsis, + .Body, + .Tags, + .Documentation .ASTData .Def { + max-width: 380px; + } + + .Documentation .ASTHead, + .DefNoBody, + .DefBody { + max-width: 400px; + } + + .Def { + padding: 5px; + } +} +@media (min-width: 500px) { + .Synopsis, + .Body, + .Tags, + .Documentation .ASTData .Def { + max-width: 440px; + } + + .Documentation .ASTHead, + .DefNoBody, + .DefBody { + max-width: 470px; + } +} +@media (min-width: 600px) { + .Synopsis, + .Body, + .Tags, + .Documentation .ASTData .Def { + max-width: 490px; + } + + .Documentation .ASTHead, + .DefNoBody, + .DefBody { + max-width: 520px; + } +} +@media (min-width: 900px) { + .Synopsis, + .Body, + .Tags, + .Documentation .ASTData .Def { + max-width: 680px; + } + + .Documentation .ASTHead, + .DefNoBody, + .DefBody { + max-width: 710px; + } +} +@media (min-width: 1300px) { + .Synopsis, + .Body, + .Tags, + .Documentation .ASTData .Def { + max-width: 790px; + } + + .Documentation .ASTHead, + .DefNoBody, + .DefBody { + max-width: 820px; + } +} diff --git a/gui/src/rust/ide/lib/view/src/graph_editor/component/visualization/data.rs b/gui/src/rust/ide/lib/view/src/graph_editor/component/visualization/data.rs index 342af73cece..b396ae091f3 100644 --- a/gui/src/rust/ide/lib/view/src/graph_editor/component/visualization/data.rs +++ b/gui/src/rust/ide/lib/view/src/graph_editor/component/visualization/data.rs @@ -145,3 +145,32 @@ impl MockDataGenerator3D { ] } } + + +/// The `MockDocGenerator` creates sample documentation string in the format of `String`. +#[derive(Clone,CloneRef,Copy,Debug,Default)] +pub struct MockDocGenerator; + +impl MockDocGenerator { + /// Generate new data set. + pub fn generate_data(self) -> String { + let input = r#" +## + Optional values. + + Type `Option` represents an optional value: every `Option` is either `Some` + and contains a value, or `None`, and does not. + + ? Information + `Option`s are commonly paired with pattern matching to query the presence of + a value and take action, always accounting for the None case. +type Option a + ## The `Some` type indicates a presence of a value. + type Some a + + ## The `None` type indicates a lack of a value. + type None +"#; + input.to_string() + } +} diff --git a/gui/src/rust/ide/lib/view/src/graph_editor/component/visualization/path.rs b/gui/src/rust/ide/lib/view/src/graph_editor/component/visualization/path.rs index cf5acd1618e..54b8370592a 100644 --- a/gui/src/rust/ide/lib/view/src/graph_editor/component/visualization/path.rs +++ b/gui/src/rust/ide/lib/view/src/graph_editor/component/visualization/path.rs @@ -35,7 +35,7 @@ impl Path { /// Constructor. pub fn new(library:impl Into, name:impl Into) -> Self { let library = library.into(); - let name = name.into(); + let name = name.into(); Self {library,name} }