mirror of
https://github.com/enso-org/enso.git
synced 2024-11-23 08:08:34 +03:00
No rendering after drop (#6911)
This commit is contained in:
parent
67821bf8df
commit
e9e90fe152
@ -81,7 +81,7 @@ impl Initializer {
|
|||||||
match self.initialize_ide_controller_with_retries().await {
|
match self.initialize_ide_controller_with_retries().await {
|
||||||
Ok(controller) => {
|
Ok(controller) => {
|
||||||
let can_manage_projects = controller.can_manage_projects();
|
let can_manage_projects = controller.can_manage_projects();
|
||||||
let ide = Ide::new(ensogl_app, view.clone_ref(), controller);
|
let ide = Ide::new(ensogl_app, view, controller);
|
||||||
if can_manage_projects {
|
if can_manage_projects {
|
||||||
if let Some(project) = &self.config.project_to_open {
|
if let Some(project) = &self.config.project_to_open {
|
||||||
ide.open_or_create_project(project.clone());
|
ide.open_or_create_project(project.clone());
|
||||||
|
@ -203,12 +203,20 @@ pub fn main() {
|
|||||||
#[wasm_bindgen]
|
#[wasm_bindgen]
|
||||||
pub fn drop() {
|
pub fn drop() {
|
||||||
let ide = IDE.with(RefCell::take);
|
let ide = IDE.with(RefCell::take);
|
||||||
if let Some(Ok(ide)) = &ide {
|
if let Some(Ok(ide)) = ide {
|
||||||
//TODO[ao] #6420 We should not do this, but somehow the `dom` field in the scene is
|
//TODO[ao] #6420 We should not do this, but somehow the `dom` field in the scene is
|
||||||
// leaking.
|
// leaking.
|
||||||
ide.ensogl_app.display.default_scene.dom.root.remove();
|
ide.ensogl_app.display.default_scene.dom.root.remove();
|
||||||
}
|
// The presenter need to be dropped first, so all visible components should hide themselves
|
||||||
mem::drop(ide);
|
// and be pushed to the garbage collector before we clear it.
|
||||||
|
mem::drop(ide.presenter);
|
||||||
|
//TODO[ao] As widgets which are garbage-collected may (and ofter do) keep references to
|
||||||
|
// [`Application`] or [`World`], we need to force dropping them. This is not an ideal
|
||||||
|
// solution, but the garbage collector will be removed soon anyway - see
|
||||||
|
// https://github.com/enso-org/enso/issues/6850#issuecomment-1576754037
|
||||||
|
ide.ensogl_app.display.force_garbage_drop();
|
||||||
|
mem::drop(ide.ensogl_app)
|
||||||
|
};
|
||||||
EXECUTOR.with(RefCell::take);
|
EXECUTOR.with(RefCell::take);
|
||||||
leak_detector::TRACKED_OBJECTS.with(|objects| {
|
leak_detector::TRACKED_OBJECTS.with(|objects| {
|
||||||
let objects = objects.borrow();
|
let objects = objects.borrow();
|
||||||
|
@ -12,7 +12,6 @@ use crate::presenter::graph::AstNodeId;
|
|||||||
use crate::presenter::graph::ViewNodeId;
|
use crate::presenter::graph::ViewNodeId;
|
||||||
|
|
||||||
use enso_frp as frp;
|
use enso_frp as frp;
|
||||||
use ensogl::application::View;
|
|
||||||
use ide_view as view;
|
use ide_view as view;
|
||||||
use ide_view::graph_editor::component::node as node_view;
|
use ide_view::graph_editor::component::node as node_view;
|
||||||
use ide_view::graph_editor::component::visualization as visualization_view;
|
use ide_view::graph_editor::component::visualization as visualization_view;
|
||||||
@ -181,7 +180,6 @@ impl Visualization {
|
|||||||
state,
|
state,
|
||||||
});
|
});
|
||||||
|
|
||||||
let app = &view.app().frp;
|
|
||||||
frp::extend! { network
|
frp::extend! { network
|
||||||
eval view.visualization_shown (((node, metadata)) model.visualization_shown(*node, metadata.clone()));
|
eval view.visualization_shown (((node, metadata)) model.visualization_shown(*node, metadata.clone()));
|
||||||
eval view.visualization_hidden ((node) model.visualization_hidden(*node));
|
eval view.visualization_hidden ((node) model.visualization_hidden(*node));
|
||||||
@ -196,8 +194,7 @@ impl Visualization {
|
|||||||
|
|
||||||
view.set_visualization_data <+ set_data;
|
view.set_visualization_data <+ set_data;
|
||||||
view.set_error_visualization_data <+ error_update;
|
view.set_error_visualization_data <+ error_update;
|
||||||
view.disable_visualization <+ visualization_failure._0();
|
view.visualization_update_failed <+ visualization_failure;
|
||||||
app.show_notification <+ visualization_failure._1();
|
|
||||||
|
|
||||||
eval_ view.visualization_registry_reload_requested (model.load_visualizations());
|
eval_ view.visualization_registry_reload_requested (model.load_visualizations());
|
||||||
}
|
}
|
||||||
|
@ -492,10 +492,6 @@ impl ensogl_core::application::View for Breadcrumbs {
|
|||||||
Self::new(app)
|
Self::new(app)
|
||||||
}
|
}
|
||||||
|
|
||||||
fn app(&self) -> &Application {
|
|
||||||
self.widget.app()
|
|
||||||
}
|
|
||||||
|
|
||||||
fn default_shortcuts() -> Vec<Shortcut> {
|
fn default_shortcuts() -> Vec<Shortcut> {
|
||||||
use ensogl_core::application::shortcut::ActionType::*;
|
use ensogl_core::application::shortcut::ActionType::*;
|
||||||
[(Press, "shift enter", "move_up"), (Press, "ctrl shift enter", "move_down")]
|
[(Press, "shift enter", "move_up"), (Press, "ctrl shift enter", "move_down")]
|
||||||
|
@ -246,7 +246,6 @@ pub struct Model {
|
|||||||
|
|
||||||
impl Model {
|
impl Model {
|
||||||
fn new(app: &Application) -> Self {
|
fn new(app: &Application) -> Self {
|
||||||
let app = app.clone_ref();
|
|
||||||
let scene = &app.display.default_scene;
|
let scene = &app.display.default_scene;
|
||||||
let display_object = display::object::Instance::new();
|
let display_object = display::object::Instance::new();
|
||||||
|
|
||||||
@ -256,7 +255,7 @@ impl Model {
|
|||||||
let grid = app.new_view::<grid::View>();
|
let grid = app.new_view::<grid::View>();
|
||||||
display_object.add_child(&grid);
|
display_object.add_child(&grid);
|
||||||
|
|
||||||
let section_navigator = SectionNavigator::new(&app);
|
let section_navigator = SectionNavigator::new(app);
|
||||||
display_object.add_child(§ion_navigator);
|
display_object.add_child(§ion_navigator);
|
||||||
|
|
||||||
let breadcrumbs = app.new_view::<breadcrumbs::Breadcrumbs>();
|
let breadcrumbs = app.new_view::<breadcrumbs::Breadcrumbs>();
|
||||||
|
@ -132,6 +132,7 @@ pub struct BreadcrumbsModel {
|
|||||||
/// A container for all the breadcrumbs after project name. This contained and all its
|
/// A container for all the breadcrumbs after project name. This contained and all its
|
||||||
/// breadcrumbs are moved when project name component is resized.
|
/// breadcrumbs are moved when project name component is resized.
|
||||||
breadcrumbs_container: display::object::Instance,
|
breadcrumbs_container: display::object::Instance,
|
||||||
|
// Required for creating new breadcrumbs
|
||||||
app: Application,
|
app: Application,
|
||||||
breadcrumbs: Rc<RefCell<Vec<Breadcrumb>>>,
|
breadcrumbs: Rc<RefCell<Vec<Breadcrumb>>>,
|
||||||
frp_inputs: FrpInputs,
|
frp_inputs: FrpInputs,
|
||||||
|
@ -127,7 +127,6 @@ impl Animations {
|
|||||||
#[derive(Debug, Clone, CloneRef)]
|
#[derive(Debug, Clone, CloneRef)]
|
||||||
#[allow(missing_docs)]
|
#[allow(missing_docs)]
|
||||||
struct ProjectNameModel {
|
struct ProjectNameModel {
|
||||||
app: Application,
|
|
||||||
display_object: display::object::Instance,
|
display_object: display::object::Instance,
|
||||||
view: background::View,
|
view: background::View,
|
||||||
style: StyleWatch,
|
style: StyleWatch,
|
||||||
@ -138,7 +137,6 @@ struct ProjectNameModel {
|
|||||||
impl ProjectNameModel {
|
impl ProjectNameModel {
|
||||||
/// Constructor.
|
/// Constructor.
|
||||||
fn new(app: &Application) -> Self {
|
fn new(app: &Application) -> Self {
|
||||||
let app = app.clone_ref();
|
|
||||||
let scene = &app.display.default_scene;
|
let scene = &app.display.default_scene;
|
||||||
let display_object = display::object::Instance::new();
|
let display_object = display::object::Instance::new();
|
||||||
// FIXME : StyleWatch is unsuitable here, as it was designed as an internal tool for shape
|
// FIXME : StyleWatch is unsuitable here, as it was designed as an internal tool for shape
|
||||||
@ -160,7 +158,7 @@ impl ProjectNameModel {
|
|||||||
scene.layers.panel.add(&view);
|
scene.layers.panel.add(&view);
|
||||||
|
|
||||||
let project_name = default();
|
let project_name = default();
|
||||||
Self { app, display_object, view, style, text_field, project_name }.init()
|
Self { display_object, view, style, text_field, project_name }.init()
|
||||||
}
|
}
|
||||||
|
|
||||||
/// Compute the width of the ProjectName view.
|
/// Compute the width of the ProjectName view.
|
||||||
@ -423,12 +421,10 @@ impl View for ProjectName {
|
|||||||
fn label() -> &'static str {
|
fn label() -> &'static str {
|
||||||
"ProjectName"
|
"ProjectName"
|
||||||
}
|
}
|
||||||
|
|
||||||
fn new(app: &Application) -> Self {
|
fn new(app: &Application) -> Self {
|
||||||
ProjectName::new(app)
|
ProjectName::new(app)
|
||||||
}
|
}
|
||||||
fn app(&self) -> &Application {
|
|
||||||
&self.model.app
|
|
||||||
}
|
|
||||||
|
|
||||||
fn default_shortcuts() -> Vec<shortcut::Shortcut> {
|
fn default_shortcuts() -> Vec<shortcut::Shortcut> {
|
||||||
use shortcut::ActionType::*;
|
use shortcut::ActionType::*;
|
||||||
|
@ -402,6 +402,7 @@ impl Deref for Node {
|
|||||||
#[derive(Clone, CloneRef, Debug)]
|
#[derive(Clone, CloneRef, Debug)]
|
||||||
#[allow(missing_docs)]
|
#[allow(missing_docs)]
|
||||||
pub struct NodeModel {
|
pub struct NodeModel {
|
||||||
|
// Required for switching the node to a different layer
|
||||||
pub app: Application,
|
pub app: Application,
|
||||||
pub display_object: display::object::Instance,
|
pub display_object: display::object::Instance,
|
||||||
pub background: Background,
|
pub background: Background,
|
||||||
|
@ -133,7 +133,6 @@ impl From<node::Expression> for Expression {
|
|||||||
/// Internal model of the port area.
|
/// Internal model of the port area.
|
||||||
#[derive(Debug)]
|
#[derive(Debug)]
|
||||||
pub struct Model {
|
pub struct Model {
|
||||||
app: Application,
|
|
||||||
display_object: display::object::Instance,
|
display_object: display::object::Instance,
|
||||||
edit_mode_label: text::Text,
|
edit_mode_label: text::Text,
|
||||||
expression: RefCell<Expression>,
|
expression: RefCell<Expression>,
|
||||||
@ -152,17 +151,16 @@ impl Model {
|
|||||||
/// Constructor.
|
/// Constructor.
|
||||||
#[profile(Debug)]
|
#[profile(Debug)]
|
||||||
pub fn new(app: &Application) -> Self {
|
pub fn new(app: &Application) -> Self {
|
||||||
let app = app.clone_ref();
|
|
||||||
let display_object = display::object::Instance::new_named("input");
|
let display_object = display::object::Instance::new_named("input");
|
||||||
|
|
||||||
let edit_mode_label = app.new_view::<text::Text>();
|
let edit_mode_label = app.new_view::<text::Text>();
|
||||||
let expression = default();
|
let expression = default();
|
||||||
let styles = StyleWatch::new(&app.display.default_scene.style_sheet);
|
let styles = StyleWatch::new(&app.display.default_scene.style_sheet);
|
||||||
let styles_frp = StyleWatchFrp::new(&app.display.default_scene.style_sheet);
|
let styles_frp = StyleWatchFrp::new(&app.display.default_scene.style_sheet);
|
||||||
let widget_tree = widget::Tree::new(&app);
|
let widget_tree = widget::Tree::new(app);
|
||||||
with_context(|ctx| ctx.layers.widget.add(&widget_tree));
|
with_context(|ctx| ctx.layers.widget.add(&widget_tree));
|
||||||
Self { app, display_object, edit_mode_label, expression, styles, styles_frp, widget_tree }
|
Self { display_object, edit_mode_label, expression, styles, styles_frp, widget_tree }
|
||||||
.init()
|
.init(app)
|
||||||
}
|
}
|
||||||
|
|
||||||
/// React to edit mode change. Shows and hides appropriate child views according to current
|
/// React to edit mode change. Shows and hides appropriate child views according to current
|
||||||
@ -183,19 +181,24 @@ impl Model {
|
|||||||
}
|
}
|
||||||
|
|
||||||
#[profile(Debug)]
|
#[profile(Debug)]
|
||||||
fn init(self) -> Self {
|
fn init(self, app: &Application) -> Self {
|
||||||
// TODO: Depth sorting of labels to in front of the mouse pointer. Temporary solution.
|
// TODO: Depth sorting of labels to in front of the mouse pointer. Temporary solution.
|
||||||
// It needs to be more flexible once we have proper depth management.
|
// It needs to be more flexible once we have proper depth management.
|
||||||
// See https://www.pivotaltracker.com/story/show/183567632.
|
// See https://www.pivotaltracker.com/story/show/183567632.
|
||||||
let scene = &self.app.display.default_scene;
|
let scene = &app.display.default_scene;
|
||||||
self.set_label_layer(&scene.layers.label);
|
self.set_label_layer(&scene.layers.label);
|
||||||
|
|
||||||
let text_color = self.styles.get_color(theme::graph_editor::node::text);
|
let text_color = self.styles.get_color(theme::graph_editor::node::text);
|
||||||
|
|
||||||
self.edit_mode_label.set_single_line_mode(true);
|
self.edit_mode_label.set_single_line_mode(true);
|
||||||
self.edit_mode_label.disable_command("cursor_move_up");
|
|
||||||
self.edit_mode_label.disable_command("cursor_move_down");
|
app.commands.set_command_enabled(&self.edit_mode_label, "cursor_move_up", false);
|
||||||
self.edit_mode_label.disable_command("add_cursor_at_mouse_position");
|
app.commands.set_command_enabled(&self.edit_mode_label, "cursor_move_down", false);
|
||||||
|
app.commands.set_command_enabled(
|
||||||
|
&self.edit_mode_label,
|
||||||
|
"add_cursor_at_mouse_position",
|
||||||
|
false,
|
||||||
|
);
|
||||||
self.edit_mode_label.set_property_default(text_color);
|
self.edit_mode_label.set_property_default(text_color);
|
||||||
self.edit_mode_label.set_property_default(text::Size(TEXT_SIZE));
|
self.edit_mode_label.set_property_default(text::Size(TEXT_SIZE));
|
||||||
self.edit_mode_label.remove_all_cursors();
|
self.edit_mode_label.remove_all_cursors();
|
||||||
|
@ -400,6 +400,7 @@ fn entry_for_current_value(
|
|||||||
/// is minimal, as the actual dropdown view is not created.
|
/// is minimal, as the actual dropdown view is not created.
|
||||||
#[derive(Debug)]
|
#[derive(Debug)]
|
||||||
struct LazyDropdown {
|
struct LazyDropdown {
|
||||||
|
// Required for lazy initialization
|
||||||
app: ensogl::application::Application,
|
app: ensogl::application::Application,
|
||||||
set_all_entries: frp::Any<Vec<Choice>>,
|
set_all_entries: frp::Any<Vec<Choice>>,
|
||||||
set_selected_entries: frp::Any<HashSet<Choice>>,
|
set_selected_entries: frp::Any<HashSet<Choice>>,
|
||||||
|
@ -156,7 +156,6 @@ impl Model {
|
|||||||
/// Constructor.
|
/// Constructor.
|
||||||
#[profile(Debug)]
|
#[profile(Debug)]
|
||||||
pub fn new(app: &Application, frp: &Frp) -> Self {
|
pub fn new(app: &Application, frp: &Frp) -> Self {
|
||||||
let app = app.clone_ref();
|
|
||||||
let display_object = display::object::Instance::new_named("output");
|
let display_object = display::object::Instance::new_named("output");
|
||||||
let ports = display::object::Instance::new();
|
let ports = display::object::Instance::new();
|
||||||
let port_models = default();
|
let port_models = default();
|
||||||
@ -169,7 +168,7 @@ impl Model {
|
|||||||
display_object.add_child(&label);
|
display_object.add_child(&label);
|
||||||
display_object.add_child(&ports);
|
display_object.add_child(&ports);
|
||||||
Self {
|
Self {
|
||||||
app,
|
app: app.clone_ref(),
|
||||||
display_object,
|
display_object,
|
||||||
ports,
|
ports,
|
||||||
port_models,
|
port_models,
|
||||||
@ -180,21 +179,21 @@ impl Model {
|
|||||||
styles_frp,
|
styles_frp,
|
||||||
frp,
|
frp,
|
||||||
}
|
}
|
||||||
.init()
|
.init(app)
|
||||||
}
|
}
|
||||||
|
|
||||||
#[profile(Debug)]
|
#[profile(Debug)]
|
||||||
fn init(self) -> Self {
|
fn init(self, app: &Application) -> Self {
|
||||||
// FIXME[WD]: Depth sorting of labels to in front of the mouse pointer. Temporary solution.
|
// FIXME[WD]: Depth sorting of labels to in front of the mouse pointer. Temporary solution.
|
||||||
// It needs to be more flexible once we have proper depth management.
|
// It needs to be more flexible once we have proper depth management.
|
||||||
let scene = &self.app.display.default_scene;
|
let scene = &app.display.default_scene;
|
||||||
scene.layers.main.remove(&self.label);
|
scene.layers.main.remove(&self.label);
|
||||||
self.label.add_to_scene_layer(&scene.layers.label);
|
self.label.add_to_scene_layer(&scene.layers.label);
|
||||||
|
|
||||||
let text_color = self.styles.get_color(theme::graph_editor::node::text);
|
let text_color = self.styles.get_color(theme::graph_editor::node::text);
|
||||||
self.label.set_single_line_mode(true);
|
self.label.set_single_line_mode(true);
|
||||||
self.label.disable_command("cursor_move_up");
|
app.commands.set_command_enabled(&self.label, "cursor_move_up", false);
|
||||||
self.label.disable_command("cursor_move_down");
|
app.commands.set_command_enabled(&self.label, "cursor_move_up", false);
|
||||||
self.label.set_property_default(text_color);
|
self.label.set_property_default(text_color);
|
||||||
self.label.set_property_default(text::Size(input::area::TEXT_SIZE));
|
self.label.set_property_default(text::Size(input::area::TEXT_SIZE));
|
||||||
self.label.remove_all_cursors();
|
self.label.remove_all_cursors();
|
||||||
|
@ -658,6 +658,8 @@ ensogl::define_endpoints_2! {
|
|||||||
set_error_visualization_data ((NodeId, visualization::Data)),
|
set_error_visualization_data ((NodeId, visualization::Data)),
|
||||||
enable_visualization (NodeId),
|
enable_visualization (NodeId),
|
||||||
disable_visualization (NodeId),
|
disable_visualization (NodeId),
|
||||||
|
/// Inform Graph Editor that attaching or updating visualization has resulted in error.
|
||||||
|
visualization_update_failed ((NodeId, String)),
|
||||||
|
|
||||||
/// Remove from visualization registry all non-default visualizations.
|
/// Remove from visualization registry all non-default visualizations.
|
||||||
reset_visualization_registry (),
|
reset_visualization_registry (),
|
||||||
@ -760,6 +762,7 @@ ensogl::define_endpoints_2! {
|
|||||||
is_fs_visualization_displayed (bool),
|
is_fs_visualization_displayed (bool),
|
||||||
visualization_preprocessor_changed ((NodeId,PreprocessorConfiguration)),
|
visualization_preprocessor_changed ((NodeId,PreprocessorConfiguration)),
|
||||||
visualization_registry_reload_requested (),
|
visualization_registry_reload_requested (),
|
||||||
|
visualization_update_error ((NodeId, String)),
|
||||||
|
|
||||||
widgets_requested (NodeId, ast::Id, ast::Id),
|
widgets_requested (NodeId, ast::Id, ast::Id),
|
||||||
request_import (ImString),
|
request_import (ImString),
|
||||||
@ -1802,6 +1805,7 @@ impl GraphEditorModelWithNetwork {
|
|||||||
#[allow(missing_docs)] // FIXME[everyone] Public-facing API should be documented.
|
#[allow(missing_docs)] // FIXME[everyone] Public-facing API should be documented.
|
||||||
pub struct GraphEditorModel {
|
pub struct GraphEditorModel {
|
||||||
pub display_object: display::object::Instance,
|
pub display_object: display::object::Instance,
|
||||||
|
// Required for dynamically creating nodes and edges.
|
||||||
pub app: Application,
|
pub app: Application,
|
||||||
pub breadcrumbs: component::Breadcrumbs,
|
pub breadcrumbs: component::Breadcrumbs,
|
||||||
pub cursor: cursor::Cursor,
|
pub cursor: cursor::Cursor,
|
||||||
@ -2713,10 +2717,6 @@ impl application::View for GraphEditor {
|
|||||||
new_graph_editor(app)
|
new_graph_editor(app)
|
||||||
}
|
}
|
||||||
|
|
||||||
fn app(&self) -> &Application {
|
|
||||||
&self.model.app
|
|
||||||
}
|
|
||||||
|
|
||||||
fn default_shortcuts() -> Vec<application::shortcut::Shortcut> {
|
fn default_shortcuts() -> Vec<application::shortcut::Shortcut> {
|
||||||
use crate::shortcuts::SHORTCUTS;
|
use crate::shortcuts::SHORTCUTS;
|
||||||
SHORTCUTS.iter().map(|(a, b, c, d)| Self::self_shortcut_when(*a, *c, *d, *b)).collect()
|
SHORTCUTS.iter().map(|(a, b, c, d)| Self::self_shortcut_when(*a, *c, *d, *b)).collect()
|
||||||
@ -3520,7 +3520,8 @@ fn new_graph_editor(app: &Application) -> GraphEditor {
|
|||||||
viz_enable_by_press <= viz_tgt_nodes.gate_not(&viz_tgt_nodes_all_on);
|
viz_enable_by_press <= viz_tgt_nodes.gate_not(&viz_tgt_nodes_all_on);
|
||||||
viz_enable <- any(viz_enable_by_press,inputs.enable_visualization);
|
viz_enable <- any(viz_enable_by_press,inputs.enable_visualization);
|
||||||
viz_disable_by_press <= viz_tgt_nodes.gate(&viz_tgt_nodes_all_on);
|
viz_disable_by_press <= viz_tgt_nodes.gate(&viz_tgt_nodes_all_on);
|
||||||
viz_disable <- any(viz_disable_by_press,inputs.disable_visualization);
|
viz_update_failed <- inputs.visualization_update_failed._0();
|
||||||
|
viz_disable <- any(viz_disable_by_press, inputs.disable_visualization, viz_update_failed);
|
||||||
viz_preview_disable <= viz_tgt_nodes_off.sample(&viz_preview_mode_end);
|
viz_preview_disable <= viz_tgt_nodes_off.sample(&viz_preview_mode_end);
|
||||||
viz_fullscreen_on <= viz_open_fs_ev.map(f_!(model.nodes.last_selected()));
|
viz_fullscreen_on <= viz_open_fs_ev.map(f_!(model.nodes.last_selected()));
|
||||||
|
|
||||||
@ -3544,6 +3545,8 @@ fn new_graph_editor(app: &Application) -> GraphEditor {
|
|||||||
|
|
||||||
out.is_fs_visualization_displayed <+ out.visualization_fullscreen.map(Option::is_some);
|
out.is_fs_visualization_displayed <+ out.visualization_fullscreen.map(Option::is_some);
|
||||||
|
|
||||||
|
out.visualization_update_error <+ inputs.visualization_update_failed;
|
||||||
|
|
||||||
|
|
||||||
// === Register Visualization ===
|
// === Register Visualization ===
|
||||||
|
|
||||||
|
@ -155,10 +155,6 @@ impl application::View for View {
|
|||||||
Self::new(app)
|
Self::new(app)
|
||||||
}
|
}
|
||||||
|
|
||||||
fn app(&self) -> &Application {
|
|
||||||
self.model.app()
|
|
||||||
}
|
|
||||||
|
|
||||||
fn default_shortcuts() -> Vec<shortcut::Shortcut> {
|
fn default_shortcuts() -> Vec<shortcut::Shortcut> {
|
||||||
use shortcut::ActionType::*;
|
use shortcut::ActionType::*;
|
||||||
[(Press, "ctrl `", "toggle"), (Press, "escape", "hide")]
|
[(Press, "ctrl `", "toggle"), (Press, "escape", "hide")]
|
||||||
|
@ -143,7 +143,6 @@ ensogl::define_endpoints! {
|
|||||||
|
|
||||||
#[derive(Clone, CloneRef, Debug)]
|
#[derive(Clone, CloneRef, Debug)]
|
||||||
struct Model {
|
struct Model {
|
||||||
app: Application,
|
|
||||||
display_object: display::object::Instance,
|
display_object: display::object::Instance,
|
||||||
project_view_top_bar: ProjectViewTopBar,
|
project_view_top_bar: ProjectViewTopBar,
|
||||||
graph_editor: Rc<GraphEditor>,
|
graph_editor: Rc<GraphEditor>,
|
||||||
@ -175,10 +174,8 @@ impl Model {
|
|||||||
display_object.add_child(&project_view_top_bar);
|
display_object.add_child(&project_view_top_bar);
|
||||||
display_object.remove_child(&searcher);
|
display_object.remove_child(&searcher);
|
||||||
|
|
||||||
let app = app.clone_ref();
|
|
||||||
let graph_editor = Rc::new(graph_editor);
|
let graph_editor = Rc::new(graph_editor);
|
||||||
Self {
|
Self {
|
||||||
app,
|
|
||||||
display_object,
|
display_object,
|
||||||
project_view_top_bar,
|
project_view_top_bar,
|
||||||
graph_editor,
|
graph_editor,
|
||||||
@ -411,6 +408,7 @@ impl View {
|
|||||||
graph.set_navigator_disabled <+ disable_navigation;
|
graph.set_navigator_disabled <+ disable_navigation;
|
||||||
|
|
||||||
model.popup.set_label <+ graph.model.breadcrumbs.project_name_error;
|
model.popup.set_label <+ graph.model.breadcrumbs.project_name_error;
|
||||||
|
model.popup.set_label <+ graph.visualization_update_error._1();
|
||||||
graph.set_read_only <+ frp.set_read_only;
|
graph.set_read_only <+ frp.set_read_only;
|
||||||
graph.set_debug_mode <+ frp.source.debug_mode;
|
graph.set_debug_mode <+ frp.source.debug_mode;
|
||||||
|
|
||||||
@ -722,10 +720,6 @@ impl application::View for View {
|
|||||||
View::new(app)
|
View::new(app)
|
||||||
}
|
}
|
||||||
|
|
||||||
fn app(&self) -> &Application {
|
|
||||||
&self.model.app
|
|
||||||
}
|
|
||||||
|
|
||||||
fn default_shortcuts() -> Vec<application::shortcut::Shortcut> {
|
fn default_shortcuts() -> Vec<application::shortcut::Shortcut> {
|
||||||
use shortcut::ActionType::*;
|
use shortcut::ActionType::*;
|
||||||
[
|
[
|
||||||
|
@ -44,7 +44,6 @@ mod shape {
|
|||||||
/// An internal model of Status Bar component
|
/// An internal model of Status Bar component
|
||||||
#[derive(Clone, CloneRef, Debug)]
|
#[derive(Clone, CloneRef, Debug)]
|
||||||
pub struct Model {
|
pub struct Model {
|
||||||
app: Application,
|
|
||||||
display_object: display::object::Instance,
|
display_object: display::object::Instance,
|
||||||
shape: shape::View,
|
shape: shape::View,
|
||||||
close: close::View,
|
close: close::View,
|
||||||
@ -54,7 +53,6 @@ pub struct Model {
|
|||||||
impl Model {
|
impl Model {
|
||||||
/// Constructor.
|
/// Constructor.
|
||||||
pub fn new(app: &Application) -> Self {
|
pub fn new(app: &Application) -> Self {
|
||||||
let app = app.clone_ref();
|
|
||||||
let display_object = display::object::Instance::new_named("WindowControlButtons");
|
let display_object = display::object::Instance::new_named("WindowControlButtons");
|
||||||
|
|
||||||
ensogl::shapes_order_dependencies! {
|
ensogl::shapes_order_dependencies! {
|
||||||
@ -63,10 +61,10 @@ impl Model {
|
|||||||
shape -> fullscreen::shape;
|
shape -> fullscreen::shape;
|
||||||
}
|
}
|
||||||
};
|
};
|
||||||
let close = close::View::new(&app);
|
let close = close::View::new(app);
|
||||||
display_object.add_child(&close);
|
display_object.add_child(&close);
|
||||||
|
|
||||||
let fullscreen = fullscreen::View::new(&app);
|
let fullscreen = fullscreen::View::new(app);
|
||||||
display_object.add_child(&fullscreen);
|
display_object.add_child(&fullscreen);
|
||||||
|
|
||||||
let shape = shape::View::new();
|
let shape = shape::View::new();
|
||||||
@ -74,7 +72,7 @@ impl Model {
|
|||||||
|
|
||||||
app.display.default_scene.layers.panel.add(&display_object);
|
app.display.default_scene.layers.panel.add(&display_object);
|
||||||
|
|
||||||
Self { app, display_object, shape, close, fullscreen }
|
Self { display_object, shape, close, fullscreen }
|
||||||
}
|
}
|
||||||
|
|
||||||
/// Updates positions of the buttons and sizes of the mouse area.
|
/// Updates positions of the buttons and sizes of the mouse area.
|
||||||
@ -190,10 +188,8 @@ impl application::View for View {
|
|||||||
fn label() -> &'static str {
|
fn label() -> &'static str {
|
||||||
"TopButtons"
|
"TopButtons"
|
||||||
}
|
}
|
||||||
|
|
||||||
fn new(app: &Application) -> Self {
|
fn new(app: &Application) -> Self {
|
||||||
View::new(app)
|
View::new(app)
|
||||||
}
|
}
|
||||||
fn app(&self) -> &Application {
|
|
||||||
&self.model.app
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
|
@ -33,13 +33,14 @@ enum State {
|
|||||||
/// visibility.
|
/// visibility.
|
||||||
#[derive(Clone, CloneRef, Debug)]
|
#[derive(Clone, CloneRef, Debug)]
|
||||||
pub struct Model {
|
pub struct Model {
|
||||||
|
// Required for creating project view dynamically
|
||||||
app: Application,
|
app: Application,
|
||||||
display_object: display::object::Instance,
|
display_object: display::object::Instance,
|
||||||
state: Rc<CloneCell<State>>,
|
state: Rc<CloneCell<State>>,
|
||||||
status_bar: crate::status_bar::View,
|
status_bar: crate::status_bar::View,
|
||||||
welcome_view: crate::welcome_screen::View,
|
welcome_view: crate::welcome_screen::View,
|
||||||
project_view: Rc<CloneCell<Option<crate::project::View>>>,
|
project_view: Rc<CloneCell<Option<crate::project::View>>>,
|
||||||
frp: Frp,
|
frp_outputs: FrpOutputsSource,
|
||||||
}
|
}
|
||||||
|
|
||||||
impl Model {
|
impl Model {
|
||||||
@ -53,9 +54,9 @@ impl Model {
|
|||||||
let welcome_view = app.new_view::<crate::welcome_screen::View>();
|
let welcome_view = app.new_view::<crate::welcome_screen::View>();
|
||||||
let project_view = Rc::new(CloneCell::new(None));
|
let project_view = Rc::new(CloneCell::new(None));
|
||||||
display_object.add_child(&welcome_view);
|
display_object.add_child(&welcome_view);
|
||||||
let frp = frp.clone_ref();
|
let frp_outputs = frp.output.source.clone_ref();
|
||||||
|
|
||||||
Self { app, display_object, state, status_bar, welcome_view, project_view, frp }
|
Self { app, display_object, state, status_bar, welcome_view, project_view, frp_outputs }
|
||||||
}
|
}
|
||||||
|
|
||||||
/// Switch displayed view from Project View to Welcome Screen. Project View will not be
|
/// Switch displayed view from Project View to Welcome Screen. Project View will not be
|
||||||
@ -84,18 +85,18 @@ impl Model {
|
|||||||
|
|
||||||
fn init_project_view(&self) {
|
fn init_project_view(&self) {
|
||||||
if self.project_view.get().is_none() {
|
if self.project_view.get().is_none() {
|
||||||
let network = &self.frp.network;
|
|
||||||
let view = self.app.new_view::<crate::project::View>();
|
let view = self.app.new_view::<crate::project::View>();
|
||||||
|
let network = &view.network;
|
||||||
let project_list_frp = &view.project_list().frp;
|
let project_list_frp = &view.project_list().frp;
|
||||||
let status_bar = &self.status_bar;
|
let status_bar = &self.status_bar;
|
||||||
let display_object = &self.display_object;
|
let display_object = &self.display_object;
|
||||||
frp::new_bridge_network! { [network, view.network] project_bridge
|
frp::extend! { network
|
||||||
fs_vis_shown <- view.fullscreen_visualization_shown.on_true();
|
fs_vis_shown <- view.fullscreen_visualization_shown.on_true();
|
||||||
fs_vis_hidden <- view.fullscreen_visualization_shown.on_false();
|
fs_vis_hidden <- view.fullscreen_visualization_shown.on_false();
|
||||||
eval fs_vis_shown ((_) status_bar.unset_parent());
|
eval fs_vis_shown ((_) status_bar.unset_parent());
|
||||||
eval fs_vis_hidden ([display_object, status_bar](_) display_object.add_child(&status_bar));
|
eval fs_vis_hidden ([display_object, status_bar](_) display_object.add_child(&status_bar));
|
||||||
|
|
||||||
self.frp.source.selected_project <+ project_list_frp.selected_project;
|
self.frp_outputs.selected_project <+ project_list_frp.selected_project;
|
||||||
}
|
}
|
||||||
self.project_view.set(Some(view));
|
self.project_view.set(Some(view));
|
||||||
}
|
}
|
||||||
@ -203,8 +204,4 @@ impl application::View for View {
|
|||||||
fn new(app: &Application) -> Self {
|
fn new(app: &Application) -> Self {
|
||||||
Self::new(app)
|
Self::new(app)
|
||||||
}
|
}
|
||||||
|
|
||||||
fn app(&self) -> &Application {
|
|
||||||
&self.model.app
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
|
@ -107,7 +107,6 @@ pub type Entry = list_view::entry::GlyphHighlightedLabel;
|
|||||||
|
|
||||||
#[derive(Clone, CloneRef, Debug)]
|
#[derive(Clone, CloneRef, Debug)]
|
||||||
struct Model {
|
struct Model {
|
||||||
app: Application,
|
|
||||||
display_object: display::object::Instance,
|
display_object: display::object::Instance,
|
||||||
list: ListView<Entry>,
|
list: ListView<Entry>,
|
||||||
documentation: documentation::View,
|
documentation: documentation::View,
|
||||||
@ -117,11 +116,10 @@ struct Model {
|
|||||||
impl Model {
|
impl Model {
|
||||||
fn new(app: &Application) -> Self {
|
fn new(app: &Application) -> Self {
|
||||||
let scene = &app.display.default_scene;
|
let scene = &app.display.default_scene;
|
||||||
let app = app.clone_ref();
|
|
||||||
let display_object = display::object::Instance::new();
|
let display_object = display::object::Instance::new();
|
||||||
let list = app.new_view::<ListView<Entry>>();
|
let list = app.new_view::<ListView<Entry>>();
|
||||||
list.deprecated_focus();
|
list.deprecated_focus();
|
||||||
let documentation = documentation::View::new(&app);
|
let documentation = documentation::View::new(app);
|
||||||
let doc_provider = default();
|
let doc_provider = default();
|
||||||
scene.layers.node_searcher.add(&list);
|
scene.layers.node_searcher.add(&list);
|
||||||
display_object.add_child(&documentation);
|
display_object.add_child(&documentation);
|
||||||
@ -137,7 +135,7 @@ impl Model {
|
|||||||
list.set_x(ACTION_LIST_X);
|
list.set_x(ACTION_LIST_X);
|
||||||
documentation.set_x(DOCUMENTATION_X);
|
documentation.set_x(DOCUMENTATION_X);
|
||||||
documentation.set_y(-action_list_gap);
|
documentation.set_y(-action_list_gap);
|
||||||
Self { app, display_object, list, documentation, doc_provider }
|
Self { display_object, list, documentation, doc_provider }
|
||||||
}
|
}
|
||||||
|
|
||||||
fn set_height(&self, h: f32) {
|
fn set_height(&self, h: f32) {
|
||||||
@ -287,12 +285,11 @@ impl application::View for View {
|
|||||||
fn label() -> &'static str {
|
fn label() -> &'static str {
|
||||||
"Searcher"
|
"Searcher"
|
||||||
}
|
}
|
||||||
|
|
||||||
fn new(app: &Application) -> Self {
|
fn new(app: &Application) -> Self {
|
||||||
Self::new(app)
|
Self::new(app)
|
||||||
}
|
}
|
||||||
fn app(&self) -> &Application {
|
|
||||||
&self.model.app
|
|
||||||
}
|
|
||||||
fn default_shortcuts() -> Vec<shortcut::Shortcut> {
|
fn default_shortcuts() -> Vec<shortcut::Shortcut> {
|
||||||
use shortcut::ActionType::*;
|
use shortcut::ActionType::*;
|
||||||
[(Press, "tab", "use_as_suggestion")]
|
[(Press, "tab", "use_as_suggestion")]
|
||||||
|
@ -116,7 +116,6 @@ static STYLESHEET: &str = include_str!("../style.css");
|
|||||||
/// Model of Welcome Screen that generates HTML DOM elements.
|
/// Model of Welcome Screen that generates HTML DOM elements.
|
||||||
#[derive(Clone, CloneRef, Debug)]
|
#[derive(Clone, CloneRef, Debug)]
|
||||||
pub struct Model {
|
pub struct Model {
|
||||||
application: Application,
|
|
||||||
dom: DomSymbol,
|
dom: DomSymbol,
|
||||||
display_object: display::object::Instance,
|
display_object: display::object::Instance,
|
||||||
side_menu: SideMenu,
|
side_menu: SideMenu,
|
||||||
@ -126,7 +125,6 @@ pub struct Model {
|
|||||||
impl Model {
|
impl Model {
|
||||||
/// Constructor. `frp` is used to set up event handlers on buttons.
|
/// Constructor. `frp` is used to set up event handlers on buttons.
|
||||||
pub fn new(app: &Application) -> Self {
|
pub fn new(app: &Application) -> Self {
|
||||||
let application = app.clone_ref();
|
|
||||||
let display_object = display::object::Instance::new();
|
let display_object = display::object::Instance::new();
|
||||||
|
|
||||||
let side_menu = SideMenu::new();
|
let side_menu = SideMenu::new();
|
||||||
@ -141,7 +139,7 @@ impl Model {
|
|||||||
style.set_inner_html(STYLESHEET);
|
style.set_inner_html(STYLESHEET);
|
||||||
dom.append_or_warn(&style);
|
dom.append_or_warn(&style);
|
||||||
|
|
||||||
Self { application, dom, display_object, side_menu, template_cards }
|
Self { dom, display_object, side_menu, template_cards }
|
||||||
}
|
}
|
||||||
|
|
||||||
fn create_dom(side_menu: &SideMenu, template_cards: &TemplateCards) -> DomSymbol {
|
fn create_dom(side_menu: &SideMenu, template_cards: &TemplateCards) -> DomSymbol {
|
||||||
@ -258,8 +256,4 @@ impl application::View for View {
|
|||||||
fn new(app: &Application) -> Self {
|
fn new(app: &Application) -> Self {
|
||||||
Self::new(app)
|
Self::new(app)
|
||||||
}
|
}
|
||||||
|
|
||||||
fn app(&self) -> &Application {
|
|
||||||
&self.model.application
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
|
@ -203,19 +203,17 @@ pub mod shape {
|
|||||||
#[derivative(Clone(bound = ""))]
|
#[derivative(Clone(bound = ""))]
|
||||||
#[allow(missing_docs)]
|
#[allow(missing_docs)]
|
||||||
pub struct Model<S: Shape> {
|
pub struct Model<S: Shape> {
|
||||||
app: Application,
|
|
||||||
display_object: display::object::Instance,
|
display_object: display::object::Instance,
|
||||||
shape: ShapeView<S>,
|
shape: ShapeView<S>,
|
||||||
}
|
}
|
||||||
|
|
||||||
impl<Shape: ButtonShape> Model<Shape> {
|
impl<Shape: ButtonShape> Model<Shape> {
|
||||||
/// Construct a button's model.
|
/// Construct a button's model.
|
||||||
pub fn new(app: &Application) -> Self {
|
pub fn new(_app: &Application) -> Self {
|
||||||
let app = app.clone_ref();
|
|
||||||
let display_object = display::object::Instance::new();
|
let display_object = display::object::Instance::new();
|
||||||
let shape = ShapeView::new();
|
let shape = ShapeView::new();
|
||||||
display_object.add_child(&shape);
|
display_object.add_child(&shape);
|
||||||
Self { app, display_object, shape }
|
Self { display_object, shape }
|
||||||
}
|
}
|
||||||
|
|
||||||
/// Set the background (i.e. the circle) color.
|
/// Set the background (i.e. the circle) color.
|
||||||
|
@ -95,7 +95,6 @@ impl component::Frp<Model> for Frp {
|
|||||||
|
|
||||||
#[derive(Clone, CloneRef, Debug)]
|
#[derive(Clone, CloneRef, Debug)]
|
||||||
pub struct Model {
|
pub struct Model {
|
||||||
app: Application,
|
|
||||||
background: background::View,
|
background: background::View,
|
||||||
label: Rc<RefCell<Option<text::Text>>>,
|
label: Rc<RefCell<Option<text::Text>>>,
|
||||||
display_object: display::object::Instance,
|
display_object: display::object::Instance,
|
||||||
@ -115,8 +114,7 @@ impl component::Model for Model {
|
|||||||
display_object.add_child(&background);
|
display_object.add_child(&background);
|
||||||
scene.layers.tooltip.add(&background);
|
scene.layers.tooltip.add(&background);
|
||||||
|
|
||||||
let app = app.clone_ref();
|
Model { background, label, display_object }
|
||||||
Model { app, background, label, display_object }
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -114,6 +114,7 @@ pub struct FlameGraph {
|
|||||||
blocks: Vec<Block>,
|
blocks: Vec<Block>,
|
||||||
marks: Vec<Mark>,
|
marks: Vec<Mark>,
|
||||||
origin_x: f64,
|
origin_x: f64,
|
||||||
|
// Required for dynamically adding blocks.
|
||||||
app: Application,
|
app: Application,
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -98,7 +98,6 @@ impl component::Frp<Model> for Frp {
|
|||||||
|
|
||||||
#[derive(Clone, CloneRef, Debug)]
|
#[derive(Clone, CloneRef, Debug)]
|
||||||
pub struct Model {
|
pub struct Model {
|
||||||
app: Application,
|
|
||||||
background: background::View,
|
background: background::View,
|
||||||
label: Rc<RefCell<Option<text::Text>>>,
|
label: Rc<RefCell<Option<text::Text>>>,
|
||||||
display_object: display::object::Instance,
|
display_object: display::object::Instance,
|
||||||
@ -118,8 +117,7 @@ impl component::Model for Model {
|
|||||||
display_object.add_child(&background);
|
display_object.add_child(&background);
|
||||||
scene.layers.tooltip.add(&background);
|
scene.layers.tooltip.add(&background);
|
||||||
|
|
||||||
let app = app.clone_ref();
|
Model { background, label, display_object }
|
||||||
Model { app, background, label, display_object }
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -59,6 +59,7 @@ impl<E: display::Object> display::Object for VisibleEntry<E> {
|
|||||||
#[derive(CloneRef, Debug, Derivative)]
|
#[derive(CloneRef, Debug, Derivative)]
|
||||||
#[derivative(Clone(bound = ""))]
|
#[derivative(Clone(bound = ""))]
|
||||||
pub struct CreationCtx<EntryParams> {
|
pub struct CreationCtx<EntryParams> {
|
||||||
|
// Required for dynamically creating entries.
|
||||||
pub app: Application,
|
pub app: Application,
|
||||||
pub network: frp::WeakNetwork,
|
pub network: frp::WeakNetwork,
|
||||||
pub set_entry_size: frp::Stream<Vector2>,
|
pub set_entry_size: frp::Stream<Vector2>,
|
||||||
|
@ -688,10 +688,6 @@ impl<E: Entry> application::View for GridView<E> {
|
|||||||
GridView::<E>::new(app)
|
GridView::<E>::new(app)
|
||||||
}
|
}
|
||||||
|
|
||||||
fn app(&self) -> &Application {
|
|
||||||
self.widget.app()
|
|
||||||
}
|
|
||||||
|
|
||||||
fn default_shortcuts() -> Vec<application::shortcut::Shortcut> {
|
fn default_shortcuts() -> Vec<application::shortcut::Shortcut> {
|
||||||
use application::shortcut::ActionType::*;
|
use application::shortcut::ActionType::*;
|
||||||
[
|
[
|
||||||
|
@ -144,10 +144,6 @@ where
|
|||||||
ComponentView::new(app)
|
ComponentView::new(app)
|
||||||
}
|
}
|
||||||
|
|
||||||
fn app(&self) -> &Application {
|
|
||||||
self.widget.app()
|
|
||||||
}
|
|
||||||
|
|
||||||
fn default_shortcuts() -> Vec<shortcut::Shortcut> {
|
fn default_shortcuts() -> Vec<shortcut::Shortcut> {
|
||||||
F::default_shortcuts()
|
F::default_shortcuts()
|
||||||
}
|
}
|
||||||
|
@ -59,8 +59,7 @@ struct Model {
|
|||||||
}
|
}
|
||||||
|
|
||||||
impl Model {
|
impl Model {
|
||||||
fn new(app: Application) -> Self {
|
fn new(app: &Application) -> Self {
|
||||||
let app = app.clone_ref();
|
|
||||||
let scene = &app.display.default_scene;
|
let scene = &app.display.default_scene;
|
||||||
let display_object = display::object::Instance::new();
|
let display_object = display::object::Instance::new();
|
||||||
let label = app.new_view::<text::Text>();
|
let label = app.new_view::<text::Text>();
|
||||||
@ -144,7 +143,7 @@ impl Label {
|
|||||||
/// Constructor.
|
/// Constructor.
|
||||||
pub fn new(app: &Application) -> Self {
|
pub fn new(app: &Application) -> Self {
|
||||||
let frp = Rc::new(Frp::new());
|
let frp = Rc::new(Frp::new());
|
||||||
let model = Rc::new(Model::new(app.clone_ref()));
|
let model = Rc::new(Model::new(app));
|
||||||
Label { model, frp }.init()
|
Label { model, frp }.init()
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -66,6 +66,7 @@ pub type List<E> = ListData<E, <E as Entry>::Params>;
|
|||||||
#[derivative(Clone(bound = ""))]
|
#[derivative(Clone(bound = ""))]
|
||||||
#[clone_ref(bound = "E:CloneRef")]
|
#[clone_ref(bound = "E:CloneRef")]
|
||||||
pub struct ListData<E, P> {
|
pub struct ListData<E, P> {
|
||||||
|
// Required for dynamically creating new entries.
|
||||||
app: Application,
|
app: Application,
|
||||||
display_object: display::object::Instance,
|
display_object: display::object::Instance,
|
||||||
entries: Rc<RefCell<Vec<DisplayedEntry<E>>>>,
|
entries: Rc<RefCell<Vec<DisplayedEntry<E>>>>,
|
||||||
|
@ -124,7 +124,6 @@ impl Default for JumpTarget {
|
|||||||
/// The Model of Select Component.
|
/// The Model of Select Component.
|
||||||
#[derive(Clone, CloneRef, Debug)]
|
#[derive(Clone, CloneRef, Debug)]
|
||||||
struct Model<E: Entry> {
|
struct Model<E: Entry> {
|
||||||
app: Application,
|
|
||||||
entries: entry::List<E>,
|
entries: entry::List<E>,
|
||||||
selection: Selection,
|
selection: Selection,
|
||||||
background: Rectangle,
|
background: Rectangle,
|
||||||
@ -134,10 +133,9 @@ struct Model<E: Entry> {
|
|||||||
|
|
||||||
impl<E: Entry> Model<E> {
|
impl<E: Entry> Model<E> {
|
||||||
fn new(app: &Application) -> Self {
|
fn new(app: &Application) -> Self {
|
||||||
let app = app.clone_ref();
|
|
||||||
let display_object = display::object::Instance::new();
|
let display_object = display::object::Instance::new();
|
||||||
let scrolled_area = display::object::Instance::new();
|
let scrolled_area = display::object::Instance::new();
|
||||||
let entries = entry::List::new(&app);
|
let entries = entry::List::new(app);
|
||||||
let background = Rectangle();
|
let background = Rectangle();
|
||||||
background.set_border_color(color::Rgba::transparent());
|
background.set_border_color(color::Rgba::transparent());
|
||||||
let selection = Selection::default();
|
let selection = Selection::default();
|
||||||
@ -146,7 +144,7 @@ impl<E: Entry> Model<E> {
|
|||||||
display_object.add_child(&scrolled_area);
|
display_object.add_child(&scrolled_area);
|
||||||
scrolled_area.add_child(&entries);
|
scrolled_area.add_child(&entries);
|
||||||
scrolled_area.add_child(&selection);
|
scrolled_area.add_child(&selection);
|
||||||
Model { app, entries, selection, background, scrolled_area, display_object }
|
Model { entries, selection, background, scrolled_area, display_object }
|
||||||
}
|
}
|
||||||
|
|
||||||
/// Update the displayed entries list when _view_ has changed - the list was scrolled or
|
/// Update the displayed entries list when _view_ has changed - the list was scrolled or
|
||||||
@ -438,7 +436,7 @@ where E::Model: Default
|
|||||||
|
|
||||||
// === Selected Entry ===
|
// === Selected Entry ===
|
||||||
|
|
||||||
eval frp.source.focused([frp](f) if !f { frp.deselect_entries.emit(()) } );
|
frp.deselect_entries <+ frp.focused.on_false();
|
||||||
|
|
||||||
frp.source.selected_entry <+ frp.select_entry;
|
frp.source.selected_entry <+ frp.select_entry;
|
||||||
frp.source.selected_entry <+ frp.output.chosen_entry;
|
frp.source.selected_entry <+ frp.output.chosen_entry;
|
||||||
@ -636,12 +634,11 @@ impl<E: Entry> application::View for ListView<E> {
|
|||||||
fn label() -> &'static str {
|
fn label() -> &'static str {
|
||||||
"ListView"
|
"ListView"
|
||||||
}
|
}
|
||||||
|
|
||||||
fn new(app: &Application) -> Self {
|
fn new(app: &Application) -> Self {
|
||||||
ListView::new(app)
|
ListView::new(app)
|
||||||
}
|
}
|
||||||
fn app(&self) -> &Application {
|
|
||||||
&self.model.app
|
|
||||||
}
|
|
||||||
fn default_shortcuts() -> Vec<shortcut::Shortcut> {
|
fn default_shortcuts() -> Vec<shortcut::Shortcut> {
|
||||||
use shortcut::ActionType::*;
|
use shortcut::ActionType::*;
|
||||||
[
|
[
|
||||||
|
@ -367,18 +367,14 @@ impl ScrollArea {
|
|||||||
(0.0..=size.x).contains(&local_pos.x) && (-size.y..=0.0).contains(&local_pos.y)
|
(0.0..=size.x).contains(&local_pos.x) && (-size.y..=0.0).contains(&local_pos.y)
|
||||||
}));
|
}));
|
||||||
hovering <- hovering.sampler();
|
hovering <- hovering.sampler();
|
||||||
|
let on_scroll = model.display_object.on_event::<mouse::Wheel>();
|
||||||
|
on_scroll_when_hovering <- on_scroll.gate(&hovering);
|
||||||
|
model.h_scrollbar.scroll_by <+ on_scroll_when_hovering
|
||||||
|
.map(|event| event.delta_x() as f32);
|
||||||
|
model.v_scrollbar.scroll_by <+ on_scroll_when_hovering
|
||||||
|
.map(|event| event.delta_y() as f32);
|
||||||
}
|
}
|
||||||
|
|
||||||
let mouse_manager = &mouse.mouse_manager;
|
|
||||||
let scroll_handler = f!([model](event: &mouse::Wheel)
|
|
||||||
if hovering.value() {
|
|
||||||
model.h_scrollbar.scroll_by(event.delta_x() as f32);
|
|
||||||
model.v_scrollbar.scroll_by(event.delta_y() as f32);
|
|
||||||
}
|
|
||||||
);
|
|
||||||
let scroll_handler_handle = mouse_manager.on_wheel.add(scroll_handler);
|
|
||||||
network.store(&scroll_handler_handle);
|
|
||||||
|
|
||||||
|
|
||||||
ScrollArea { model, frp }
|
ScrollArea { model, frp }
|
||||||
}
|
}
|
||||||
|
@ -115,7 +115,7 @@ impl Frp {
|
|||||||
resize <- frp.set_length.map(|&length| Vector2::new(length,WIDTH));
|
resize <- frp.set_length.map(|&length| Vector2::new(length,WIDTH));
|
||||||
}
|
}
|
||||||
|
|
||||||
let base_frp = selector::Frp::new(model, style, network, resize.clone(), mouse);
|
let base_frp = selector::Frp::new(app, model, style, network, resize.clone(), mouse);
|
||||||
|
|
||||||
model.use_track_handles(false);
|
model.use_track_handles(false);
|
||||||
model.set_track_corner_round(true);
|
model.set_track_corner_round(true);
|
||||||
@ -358,22 +358,17 @@ pub struct Scrollbar {
|
|||||||
/// Public FRP api of the Component.
|
/// Public FRP api of the Component.
|
||||||
pub frp: Rc<Frp>,
|
pub frp: Rc<Frp>,
|
||||||
model: Rc<Model>,
|
model: Rc<Model>,
|
||||||
/// Reference to the application the Component belongs to. Generally required for implementing
|
|
||||||
/// `application::View` and initialising the `Model` and `Frp` and thus provided by the
|
|
||||||
/// `Component`.
|
|
||||||
pub app: Application,
|
|
||||||
}
|
}
|
||||||
|
|
||||||
impl Scrollbar {
|
impl Scrollbar {
|
||||||
/// Constructor.
|
/// Constructor.
|
||||||
pub fn new(app: &Application) -> Self {
|
pub fn new(app: &Application) -> Self {
|
||||||
let app = app.clone_ref();
|
let model = Rc::new(Model::new(app));
|
||||||
let model = Rc::new(Model::new(&app));
|
|
||||||
let frp = Frp::default();
|
let frp = Frp::default();
|
||||||
let style = StyleWatchFrp::new(&app.display.default_scene.style_sheet);
|
let style = StyleWatchFrp::new(&app.display.default_scene.style_sheet);
|
||||||
frp.init(&app, &model, &style);
|
frp.init(app, &model, &style);
|
||||||
let frp = Rc::new(frp);
|
let frp = Rc::new(frp);
|
||||||
Self { frp, model, app }
|
Self { frp, model }
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -400,10 +395,8 @@ impl application::View for Scrollbar {
|
|||||||
fn label() -> &'static str {
|
fn label() -> &'static str {
|
||||||
"Scrollbar"
|
"Scrollbar"
|
||||||
}
|
}
|
||||||
|
|
||||||
fn new(app: &Application) -> Self {
|
fn new(app: &Application) -> Self {
|
||||||
Scrollbar::new(app)
|
Scrollbar::new(app)
|
||||||
}
|
}
|
||||||
fn app(&self) -> &Application {
|
|
||||||
&self.app
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
|
@ -100,18 +100,16 @@ impl display::Object for Model {
|
|||||||
pub struct FloatLabel {
|
pub struct FloatLabel {
|
||||||
pub frp: Rc<Frp>,
|
pub frp: Rc<Frp>,
|
||||||
model: Rc<Model>,
|
model: Rc<Model>,
|
||||||
app: Application,
|
|
||||||
}
|
}
|
||||||
|
|
||||||
impl FloatLabel {
|
impl FloatLabel {
|
||||||
/// Constructor.
|
/// Constructor.
|
||||||
pub fn new(app: &Application) -> Self {
|
pub fn new(app: &Application) -> Self {
|
||||||
let app = app.clone_ref();
|
let model = Rc::new(Model::new(app));
|
||||||
let model = Rc::new(Model::new(&app));
|
|
||||||
let frp = Frp::default();
|
let frp = Frp::default();
|
||||||
frp.init(&model);
|
frp.init(&model);
|
||||||
let frp = Rc::new(frp);
|
let frp = Rc::new(frp);
|
||||||
Self { frp, model, app }
|
Self { frp, model }
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -9,6 +9,7 @@ use crate::shape::shape_is_dragged;
|
|||||||
use enso_frp as frp;
|
use enso_frp as frp;
|
||||||
use enso_frp::io::Mouse_DEPRECATED;
|
use enso_frp::io::Mouse_DEPRECATED;
|
||||||
use enso_frp::Network;
|
use enso_frp::Network;
|
||||||
|
use ensogl_core::application::Application;
|
||||||
use ensogl_core::display::object::ObjectOps;
|
use ensogl_core::display::object::ObjectOps;
|
||||||
use ensogl_core::display::shape::StyleWatchFrp;
|
use ensogl_core::display::shape::StyleWatchFrp;
|
||||||
use ensogl_hardcoded_theme as theme;
|
use ensogl_hardcoded_theme as theme;
|
||||||
@ -69,6 +70,7 @@ pub struct Frp {
|
|||||||
impl Frp {
|
impl Frp {
|
||||||
/// Create and initialize the FRP.
|
/// Create and initialize the FRP.
|
||||||
pub fn new(
|
pub fn new(
|
||||||
|
app: &Application,
|
||||||
model: &Model,
|
model: &Model,
|
||||||
style: &StyleWatchFrp,
|
style: &StyleWatchFrp,
|
||||||
network: &Network,
|
network: &Network,
|
||||||
@ -76,7 +78,7 @@ impl Frp {
|
|||||||
mouse: &Mouse_DEPRECATED,
|
mouse: &Mouse_DEPRECATED,
|
||||||
) -> Frp {
|
) -> Frp {
|
||||||
let net = &network;
|
let net = &network;
|
||||||
let scene = &model.app.display.default_scene;
|
let scene = &app.display.default_scene;
|
||||||
let shadow = shadow::frp_from_style(style, theme::shadow);
|
let shadow = shadow::frp_from_style(style, theme::shadow);
|
||||||
let text_size = style.get_number(theme::text::size);
|
let text_size = style.get_number(theme::text::size);
|
||||||
|
|
||||||
|
@ -77,22 +77,17 @@ pub struct NumberPicker {
|
|||||||
/// Public FRP api of the Component.
|
/// Public FRP api of the Component.
|
||||||
pub frp: Rc<number::Frp>,
|
pub frp: Rc<number::Frp>,
|
||||||
model: Rc<Model>,
|
model: Rc<Model>,
|
||||||
/// Reference to the application the Component belongs to. Generally required for implementing
|
|
||||||
/// `application::View` and initialising the `Model` and `Frp` and thus provided by the
|
|
||||||
/// `Component`.
|
|
||||||
pub app: Application,
|
|
||||||
}
|
}
|
||||||
|
|
||||||
impl NumberPicker {
|
impl NumberPicker {
|
||||||
/// Constructor.
|
/// Constructor.
|
||||||
pub fn new(app: &Application) -> Self {
|
pub fn new(app: &Application) -> Self {
|
||||||
let app = app.clone_ref();
|
let model = Rc::new(Model::new(app));
|
||||||
let model = Rc::new(Model::new(&app));
|
|
||||||
let frp = number::Frp::default();
|
let frp = number::Frp::default();
|
||||||
let style = StyleWatchFrp::new(&app.display.default_scene.style_sheet);
|
let style = StyleWatchFrp::new(&app.display.default_scene.style_sheet);
|
||||||
frp.init(&app, &model, &style);
|
frp.init(app, &model, &style);
|
||||||
let frp = Rc::new(frp);
|
let frp = Rc::new(frp);
|
||||||
Self { frp, model, app }
|
Self { frp, model }
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -119,12 +114,10 @@ impl application::View for NumberPicker {
|
|||||||
fn label() -> &'static str {
|
fn label() -> &'static str {
|
||||||
"NumberPicker"
|
"NumberPicker"
|
||||||
}
|
}
|
||||||
|
|
||||||
fn new(app: &Application) -> Self {
|
fn new(app: &Application) -> Self {
|
||||||
NumberPicker::new(app)
|
NumberPicker::new(app)
|
||||||
}
|
}
|
||||||
fn app(&self) -> &Application {
|
|
||||||
&self.app
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
@ -147,22 +140,17 @@ pub struct NumberRangePicker {
|
|||||||
/// Public FRP api of the Component.
|
/// Public FRP api of the Component.
|
||||||
pub frp: Rc<range::Frp>,
|
pub frp: Rc<range::Frp>,
|
||||||
model: Rc<Model>,
|
model: Rc<Model>,
|
||||||
/// Reference to the application the Component belongs to. Generally required for implementing
|
|
||||||
/// `application::View` and initialising the `Model` and `Frp` and thus provided by the
|
|
||||||
/// `Component`.
|
|
||||||
pub app: Application,
|
|
||||||
}
|
}
|
||||||
|
|
||||||
impl NumberRangePicker {
|
impl NumberRangePicker {
|
||||||
/// Constructor.
|
/// Constructor.
|
||||||
pub fn new(app: &Application) -> Self {
|
pub fn new(app: &Application) -> Self {
|
||||||
let app = app.clone_ref();
|
let model = Rc::new(Model::new(app));
|
||||||
let model = Rc::new(Model::new(&app));
|
|
||||||
let frp = range::Frp::default();
|
let frp = range::Frp::default();
|
||||||
let style = StyleWatchFrp::new(&app.display.default_scene.style_sheet);
|
let style = StyleWatchFrp::new(&app.display.default_scene.style_sheet);
|
||||||
frp.init(&app, &model, &style);
|
frp.init(app, &model, &style);
|
||||||
let frp = Rc::new(frp);
|
let frp = Rc::new(frp);
|
||||||
Self { frp, model, app }
|
Self { frp, model }
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -189,10 +177,8 @@ impl application::View for NumberRangePicker {
|
|||||||
fn label() -> &'static str {
|
fn label() -> &'static str {
|
||||||
"RangePicker"
|
"RangePicker"
|
||||||
}
|
}
|
||||||
|
|
||||||
fn new(app: &Application) -> Self {
|
fn new(app: &Application) -> Self {
|
||||||
NumberRangePicker::new(app)
|
NumberRangePicker::new(app)
|
||||||
}
|
}
|
||||||
fn app(&self) -> &Application {
|
|
||||||
&self.app
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
|
@ -70,8 +70,6 @@ pub struct Model {
|
|||||||
background_left_corner_roundness: Rc<Cell<bool>>,
|
background_left_corner_roundness: Rc<Cell<bool>>,
|
||||||
background_right_corner_roundness: Rc<Cell<bool>>,
|
background_right_corner_roundness: Rc<Cell<bool>>,
|
||||||
padding: Rc<Cell<f32>>,
|
padding: Rc<Cell<f32>>,
|
||||||
|
|
||||||
pub app: Application,
|
|
||||||
}
|
}
|
||||||
|
|
||||||
#[allow(missing_docs)]
|
#[allow(missing_docs)]
|
||||||
@ -95,7 +93,6 @@ impl Model {
|
|||||||
let background_right_corner_roundness = default();
|
let background_right_corner_roundness = default();
|
||||||
let padding = default();
|
let padding = default();
|
||||||
|
|
||||||
let app = app.clone_ref();
|
|
||||||
let scene = &app.display.default_scene;
|
let scene = &app.display.default_scene;
|
||||||
|
|
||||||
root.add_child(&label);
|
root.add_child(&label);
|
||||||
@ -134,7 +131,6 @@ impl Model {
|
|||||||
background_left_corner_roundness,
|
background_left_corner_roundness,
|
||||||
background_right_corner_roundness,
|
background_right_corner_roundness,
|
||||||
padding,
|
padding,
|
||||||
app,
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -49,7 +49,8 @@ impl Frp {
|
|||||||
|
|
||||||
model.show_background(true);
|
model.show_background(true);
|
||||||
|
|
||||||
let base_frp = super::Frp::new(model, style, network, frp.resize.clone().into(), mouse);
|
let base_frp =
|
||||||
|
super::Frp::new(app, model, style, network, frp.resize.clone().into(), mouse);
|
||||||
|
|
||||||
let background_click = relative_shape_down_position(network, scene, &model.background);
|
let background_click = relative_shape_down_position(network, scene, &model.background);
|
||||||
let track_click = relative_shape_down_position(network, scene, &model.track);
|
let track_click = relative_shape_down_position(network, scene, &model.track);
|
||||||
|
@ -44,7 +44,8 @@ impl Frp {
|
|||||||
let scene = &app.display.default_scene;
|
let scene = &app.display.default_scene;
|
||||||
let mouse = &scene.mouse.frp_deprecated;
|
let mouse = &scene.mouse.frp_deprecated;
|
||||||
|
|
||||||
let base_frp = super::Frp::new(model, style, network, frp.resize.clone().into(), mouse);
|
let base_frp =
|
||||||
|
super::Frp::new(app, model, style, network, frp.resize.clone().into(), mouse);
|
||||||
|
|
||||||
model.use_track_handles(true);
|
model.use_track_handles(true);
|
||||||
model.show_background(true);
|
model.show_background(true);
|
||||||
|
@ -89,6 +89,7 @@ impl component::Frp<Model> for Frp {
|
|||||||
/// Internal model of the SequenceDiagram.
|
/// Internal model of the SequenceDiagram.
|
||||||
#[derive(Clone, CloneRef, Debug)]
|
#[derive(Clone, CloneRef, Debug)]
|
||||||
pub struct Model {
|
pub struct Model {
|
||||||
|
// Required for dynamically creating new lines.
|
||||||
app: Application,
|
app: Application,
|
||||||
display_object: display::object::Instance,
|
display_object: display::object::Instance,
|
||||||
actor_lines: Rc<RefCell<Vec<LabeledLine>>>,
|
actor_lines: Rc<RefCell<Vec<LabeledLine>>>,
|
||||||
|
@ -337,10 +337,6 @@ pub struct Slider {
|
|||||||
#[deref]
|
#[deref]
|
||||||
pub frp: Frp,
|
pub frp: Frp,
|
||||||
model: Rc<Model>,
|
model: Rc<Model>,
|
||||||
/// Reference to the application the component belongs to. Generally required for implementing
|
|
||||||
/// `application::View` and initialising the `Model` and `Frp` and thus provided by the
|
|
||||||
/// component.
|
|
||||||
pub app: Application,
|
|
||||||
}
|
}
|
||||||
|
|
||||||
impl Slider {
|
impl Slider {
|
||||||
@ -348,12 +344,11 @@ impl Slider {
|
|||||||
pub fn new(app: &Application) -> Self {
|
pub fn new(app: &Application) -> Self {
|
||||||
let frp = Frp::new();
|
let frp = Frp::new();
|
||||||
let model = Rc::new(Model::new(app, frp.network()));
|
let model = Rc::new(Model::new(app, frp.network()));
|
||||||
let app = app.clone_ref();
|
Self { frp, model }.init(app)
|
||||||
Self { frp, model, app }.init()
|
|
||||||
}
|
}
|
||||||
|
|
||||||
fn init(self) -> Self {
|
fn init(self, app: &Application) -> Self {
|
||||||
self.init_value_update();
|
self.init_value_update(app);
|
||||||
self.init_limit_handling();
|
self.init_limit_handling();
|
||||||
self.init_value_display();
|
self.init_value_display();
|
||||||
|
|
||||||
@ -367,13 +362,13 @@ impl Slider {
|
|||||||
}
|
}
|
||||||
|
|
||||||
/// Initialize the slider value update FRP network.
|
/// Initialize the slider value update FRP network.
|
||||||
fn init_value_update(&self) {
|
fn init_value_update(&self, app: &Application) {
|
||||||
let network = self.frp.network();
|
let network = self.frp.network();
|
||||||
let frp = &self.frp;
|
let frp = &self.frp;
|
||||||
let input = &self.frp.input;
|
let input = &self.frp.input;
|
||||||
let output = &self.frp.private.output;
|
let output = &self.frp.private.output;
|
||||||
let model = &self.model;
|
let model = &self.model;
|
||||||
let scene = &self.app.display.default_scene;
|
let scene = &app.display.default_scene;
|
||||||
let mouse = &scene.mouse.frp_deprecated;
|
let mouse = &scene.mouse.frp_deprecated;
|
||||||
let keyboard = &scene.keyboard.frp;
|
let keyboard = &scene.keyboard.frp;
|
||||||
|
|
||||||
@ -845,10 +840,6 @@ impl application::View for Slider {
|
|||||||
Self::new(app)
|
Self::new(app)
|
||||||
}
|
}
|
||||||
|
|
||||||
fn app(&self) -> &Application {
|
|
||||||
&self.app
|
|
||||||
}
|
|
||||||
|
|
||||||
fn default_shortcuts() -> Vec<shortcut::Shortcut> {
|
fn default_shortcuts() -> Vec<shortcut::Shortcut> {
|
||||||
use shortcut::ActionType::DoublePress;
|
use shortcut::ActionType::DoublePress;
|
||||||
use shortcut::ActionType::Press;
|
use shortcut::ActionType::Press;
|
||||||
|
@ -1978,10 +1978,6 @@ impl application::View for Text {
|
|||||||
Text::new(app)
|
Text::new(app)
|
||||||
}
|
}
|
||||||
|
|
||||||
fn app(&self) -> &Application {
|
|
||||||
&self.data.app
|
|
||||||
}
|
|
||||||
|
|
||||||
fn default_shortcuts() -> Vec<shortcut::Shortcut> {
|
fn default_shortcuts() -> Vec<shortcut::Shortcut> {
|
||||||
use shortcut::ActionType::*;
|
use shortcut::ActionType::*;
|
||||||
([
|
([
|
||||||
|
@ -76,15 +76,6 @@ pub struct ApplicationData {
|
|||||||
pub frp: Frp,
|
pub frp: Frp,
|
||||||
}
|
}
|
||||||
|
|
||||||
impl ApplicationData {
|
|
||||||
/// Show or hide the system mouse cursor by setting the `cursor` CSS property of the `body`
|
|
||||||
/// element.
|
|
||||||
fn show_system_cursor(&self, show: bool) {
|
|
||||||
let style = if show { "auto" } else { "none" };
|
|
||||||
web::document.body_or_panic().set_style_or_warn("cursor", style);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
impl Application {
|
impl Application {
|
||||||
/// Constructor.
|
/// Constructor.
|
||||||
pub fn new(dom: impl DomPath) -> Self {
|
pub fn new(dom: impl DomPath) -> Self {
|
||||||
@ -94,7 +85,7 @@ impl Application {
|
|||||||
let commands = command::Registry::create();
|
let commands = command::Registry::create();
|
||||||
let shortcuts =
|
let shortcuts =
|
||||||
shortcut::Registry::new(&scene.mouse.frp_deprecated, &scene.keyboard.frp, &commands);
|
shortcut::Registry::new(&scene.mouse.frp_deprecated, &scene.keyboard.frp, &commands);
|
||||||
let views = view::Registry::create(&display, &commands, &shortcuts);
|
let views = view::Registry::create(&commands, &shortcuts);
|
||||||
let cursor = Cursor::new(&display.default_scene);
|
let cursor = Cursor::new(&display.default_scene);
|
||||||
display.add_child(&cursor);
|
display.add_child(&cursor);
|
||||||
let frp = Frp::new();
|
let frp = Frp::new();
|
||||||
@ -106,20 +97,27 @@ impl Application {
|
|||||||
|
|
||||||
fn init(self) -> Self {
|
fn init(self) -> Self {
|
||||||
let frp = &self.frp;
|
let frp = &self.frp;
|
||||||
let data = &self.inner;
|
|
||||||
let network = self.frp.network();
|
let network = self.frp.network();
|
||||||
enso_frp::extend! { network
|
enso_frp::extend! { network
|
||||||
app_focused <- self.display.default_scene.frp.focused.on_change();
|
app_focused <- self.display.default_scene.frp.focused.on_change();
|
||||||
eval app_focused((t) data.show_system_cursor(!t));
|
eval app_focused([](t) Self::show_system_cursor(!t));
|
||||||
|
eval_ frp.private.input.show_system_cursor([] Self::show_system_cursor(true));
|
||||||
|
eval_ frp.private.input.hide_system_cursor([] Self::show_system_cursor(false));
|
||||||
|
|
||||||
frp.private.output.tooltip <+ frp.private.input.set_tooltip;
|
frp.private.output.tooltip <+ frp.private.input.set_tooltip;
|
||||||
eval_ frp.private.input.show_system_cursor(data.show_system_cursor(true));
|
|
||||||
eval_ frp.private.input.hide_system_cursor(data.show_system_cursor(false));
|
|
||||||
}
|
}
|
||||||
// We hide the system cursor to replace it with the EnsoGL-provided one.
|
// We hide the system cursor to replace it with the EnsoGL-provided one.
|
||||||
self.frp.hide_system_cursor();
|
self.frp.hide_system_cursor();
|
||||||
self
|
self
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/// Show or hide the system mouse cursor by setting the `cursor` CSS property of the `body`
|
||||||
|
/// element.
|
||||||
|
fn show_system_cursor(show: bool) {
|
||||||
|
let style = if show { "auto" } else { "none" };
|
||||||
|
web::document.body_or_panic().set_style_or_warn("cursor", style);
|
||||||
|
}
|
||||||
|
|
||||||
/// Create a new instance of a view.
|
/// Create a new instance of a view.
|
||||||
pub fn new_view<T: View>(&self) -> T {
|
pub fn new_view<T: View>(&self) -> T {
|
||||||
self.views.new_view(self)
|
self.views.new_view(self)
|
||||||
|
@ -27,9 +27,6 @@ pub trait View: FrpNetworkProvider + DerefToCommandApi {
|
|||||||
/// Constructor.
|
/// Constructor.
|
||||||
fn new(app: &Application) -> Self;
|
fn new(app: &Application) -> Self;
|
||||||
|
|
||||||
/// Application reference.
|
|
||||||
fn app(&self) -> &Application;
|
|
||||||
|
|
||||||
/// Set of default shortcuts.
|
/// Set of default shortcuts.
|
||||||
fn default_shortcuts() -> Vec<Shortcut> {
|
fn default_shortcuts() -> Vec<Shortcut> {
|
||||||
default()
|
default()
|
||||||
@ -58,24 +55,6 @@ pub trait View: FrpNetworkProvider + DerefToCommandApi {
|
|||||||
condition,
|
condition,
|
||||||
)
|
)
|
||||||
}
|
}
|
||||||
|
|
||||||
/// Disable the command in this component instance.
|
|
||||||
fn disable_command(&self, name: impl AsRef<str>)
|
|
||||||
where Self: Sized {
|
|
||||||
self.set_command_enabled(name, false)
|
|
||||||
}
|
|
||||||
|
|
||||||
/// Enable the command in this component instance.
|
|
||||||
fn enable_command(&self, name: impl AsRef<str>)
|
|
||||||
where Self: Sized {
|
|
||||||
self.set_command_enabled(name, true)
|
|
||||||
}
|
|
||||||
|
|
||||||
/// Set the command enable status in this component instance.
|
|
||||||
fn set_command_enabled(&self, name: impl AsRef<str>, enabled: bool)
|
|
||||||
where Self: Sized {
|
|
||||||
self.app().commands.set_command_enabled(self, name, enabled)
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
|
|
||||||
/// FRP Network provider. Used to check whether FRP bindings are still alive.
|
/// FRP Network provider. Used to check whether FRP bindings are still alive.
|
||||||
@ -232,7 +211,7 @@ impl Registry {
|
|||||||
}
|
}
|
||||||
|
|
||||||
/// Sets the command enable status for the provided component instance.
|
/// Sets the command enable status for the provided component instance.
|
||||||
fn set_command_enabled<T: View>(&self, instance: &T, name: impl AsRef<str>, enabled: bool) {
|
pub fn set_command_enabled<T: View>(&self, instance: &T, name: impl AsRef<str>, enabled: bool) {
|
||||||
self.with_command_mut(instance, name, |command| command.enabled = enabled)
|
self.with_command_mut(instance, name, |command| command.enabled = enabled)
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@ -2,8 +2,6 @@
|
|||||||
|
|
||||||
use crate::prelude::*;
|
use crate::prelude::*;
|
||||||
|
|
||||||
use crate::display::world::World;
|
|
||||||
|
|
||||||
use super::command;
|
use super::command;
|
||||||
use super::shortcut;
|
use super::shortcut;
|
||||||
use super::Application;
|
use super::Application;
|
||||||
@ -26,7 +24,6 @@ pub use command::View;
|
|||||||
#[derive(Debug, Clone, CloneRef)]
|
#[derive(Debug, Clone, CloneRef)]
|
||||||
#[allow(missing_docs)]
|
#[allow(missing_docs)]
|
||||||
pub struct Registry {
|
pub struct Registry {
|
||||||
pub display: World,
|
|
||||||
pub command_registry: command::Registry,
|
pub command_registry: command::Registry,
|
||||||
pub shortcut_registry: shortcut::Registry,
|
pub shortcut_registry: shortcut::Registry,
|
||||||
pub definitions: Rc<RefCell<HashSet<String>>>,
|
pub definitions: Rc<RefCell<HashSet<String>>>,
|
||||||
@ -35,15 +32,13 @@ pub struct Registry {
|
|||||||
impl Registry {
|
impl Registry {
|
||||||
/// Constructor.
|
/// Constructor.
|
||||||
pub fn create(
|
pub fn create(
|
||||||
display: &World,
|
|
||||||
command_registry: &command::Registry,
|
command_registry: &command::Registry,
|
||||||
shortcut_registry: &shortcut::Registry,
|
shortcut_registry: &shortcut::Registry,
|
||||||
) -> Self {
|
) -> Self {
|
||||||
let display = display.clone_ref();
|
|
||||||
let command_registry = command_registry.clone_ref();
|
let command_registry = command_registry.clone_ref();
|
||||||
let shortcut_registry = shortcut_registry.clone_ref();
|
let shortcut_registry = shortcut_registry.clone_ref();
|
||||||
let definitions = default();
|
let definitions = default();
|
||||||
Self { display, command_registry, shortcut_registry, definitions }
|
Self { command_registry, shortcut_registry, definitions }
|
||||||
}
|
}
|
||||||
|
|
||||||
/// View registration.
|
/// View registration.
|
||||||
|
@ -18,6 +18,14 @@ struct Garbage {
|
|||||||
before_mouse_events: Vec<Box<dyn Any>>,
|
before_mouse_events: Vec<Box<dyn Any>>,
|
||||||
}
|
}
|
||||||
|
|
||||||
|
impl Garbage {
|
||||||
|
fn collected_items_count(&self) -> usize {
|
||||||
|
self.before_pixel_sync.len()
|
||||||
|
+ self.before_pixel_update.len()
|
||||||
|
+ self.before_mouse_events.len()
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
/// The Garbage Collector
|
/// The Garbage Collector
|
||||||
///
|
///
|
||||||
@ -90,6 +98,14 @@ impl Collector {
|
|||||||
};
|
};
|
||||||
drop(before_mouse_events);
|
drop(before_mouse_events);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/// Immediately drop all collected garbage.
|
||||||
|
pub fn force_garbage_drop(&self) {
|
||||||
|
// Elements may add new objects on drop, thus we need to clear garbage in loop.
|
||||||
|
while self.garbage.borrow().collected_items_count() > 0 {
|
||||||
|
self.garbage.take();
|
||||||
|
}
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
|
@ -670,6 +670,13 @@ impl WorldData {
|
|||||||
self.garbage_collector.collect(object);
|
self.garbage_collector.collect(object);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/// Immediately drop the garbage.
|
||||||
|
///
|
||||||
|
/// May be used to resolve dependence cycles if garbage keeps reference to [`World`].
|
||||||
|
pub fn force_garbage_drop(&self) {
|
||||||
|
self.garbage_collector.force_garbage_drop()
|
||||||
|
}
|
||||||
|
|
||||||
/// Set the maximum frequency at which the pointer location will be checked, in terms of number
|
/// Set the maximum frequency at which the pointer location will be checked, in terms of number
|
||||||
/// of frames per check.
|
/// of frames per check.
|
||||||
pub fn set_pixel_read_period(&self, period: usize) {
|
pub fn set_pixel_read_period(&self, period: usize) {
|
||||||
|
@ -367,13 +367,6 @@ impl<Model: 'static, Frp: 'static> Widget<Model, Frp> {
|
|||||||
pub fn model(&self) -> &Model {
|
pub fn model(&self) -> &Model {
|
||||||
&self.data.model
|
&self.data.model
|
||||||
}
|
}
|
||||||
|
|
||||||
/// Reference to the application the Widget belongs to. It's required for handling model and
|
|
||||||
/// FRP garbage collection, but also may be helpful when, for example, implementing
|
|
||||||
/// `application::View`.
|
|
||||||
pub fn app(&self) -> &Application {
|
|
||||||
&self.data.app
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
|
|
||||||
impl<Model: 'static, Frp: 'static> display::Object for Widget<Model, Frp> {
|
impl<Model: 'static, Frp: 'static> display::Object for Widget<Model, Frp> {
|
||||||
|
@ -44,15 +44,13 @@ use ensogl_text_msdf::run_once_initialized;
|
|||||||
|
|
||||||
#[derive(Clone, CloneRef, Debug)]
|
#[derive(Clone, CloneRef, Debug)]
|
||||||
struct Model {
|
struct Model {
|
||||||
app: Application,
|
|
||||||
display_object: display::object::Instance,
|
display_object: display::object::Instance,
|
||||||
shape: Rectangle,
|
shape: Rectangle,
|
||||||
cover: Rectangle,
|
cover: Rectangle,
|
||||||
}
|
}
|
||||||
|
|
||||||
impl Model {
|
impl Model {
|
||||||
fn new(app: &Application) -> Self {
|
fn new() -> Self {
|
||||||
let app = app.clone_ref();
|
|
||||||
let display_object = display::object::Instance::new();
|
let display_object = display::object::Instance::new();
|
||||||
let shape: Rectangle = default();
|
let shape: Rectangle = default();
|
||||||
shape.set_size(Vector2(300.0, 300.0));
|
shape.set_size(Vector2(300.0, 300.0));
|
||||||
@ -68,7 +66,7 @@ impl Model {
|
|||||||
cover.set_corner_radius_max();
|
cover.set_corner_radius_max();
|
||||||
cover.set_pointer_events(false);
|
cover.set_pointer_events(false);
|
||||||
display_object.add_child(&cover);
|
display_object.add_child(&cover);
|
||||||
Self { app, display_object, shape, cover }
|
Self { display_object, shape, cover }
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -99,9 +97,9 @@ struct View {
|
|||||||
|
|
||||||
impl View {
|
impl View {
|
||||||
/// Constructor.
|
/// Constructor.
|
||||||
pub fn new(app: &Application) -> Self {
|
pub fn new() -> Self {
|
||||||
let frp = Frp::new();
|
let frp = Frp::new();
|
||||||
let model = Model::new(app);
|
let model = Model::new();
|
||||||
let network = &frp.network;
|
let network = &frp.network;
|
||||||
frp::extend! { network
|
frp::extend! { network
|
||||||
trace model.shape.events_deprecated.mouse_up;
|
trace model.shape.events_deprecated.mouse_up;
|
||||||
@ -139,11 +137,9 @@ impl application::View for View {
|
|||||||
fn label() -> &'static str {
|
fn label() -> &'static str {
|
||||||
"Circul"
|
"Circul"
|
||||||
}
|
}
|
||||||
fn new(app: &Application) -> Self {
|
|
||||||
View::new(app)
|
fn new(_app: &Application) -> Self {
|
||||||
}
|
View::new()
|
||||||
fn app(&self) -> &Application {
|
|
||||||
&self.model.app
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -232,16 +232,14 @@ impl FrpNetworkProvider for SliderCollection {
|
|||||||
struct SliderCollection {
|
struct SliderCollection {
|
||||||
#[deref]
|
#[deref]
|
||||||
frp: Frp,
|
frp: Frp,
|
||||||
app: Application,
|
|
||||||
model: Model,
|
model: Model,
|
||||||
}
|
}
|
||||||
|
|
||||||
impl SliderCollection {
|
impl SliderCollection {
|
||||||
fn new(app: &Application) -> Self {
|
fn new(app: &Application) -> Self {
|
||||||
let frp = Frp::new();
|
let frp = Frp::new();
|
||||||
let app = app.clone_ref();
|
let model = Model::new(app);
|
||||||
let model = Model::new(&app);
|
Self { frp, model }.init()
|
||||||
Self { frp, app, model }.init()
|
|
||||||
}
|
}
|
||||||
|
|
||||||
fn init(self) -> Self {
|
fn init(self) -> Self {
|
||||||
@ -272,10 +270,6 @@ impl View for SliderCollection {
|
|||||||
Self::new(app)
|
Self::new(app)
|
||||||
}
|
}
|
||||||
|
|
||||||
fn app(&self) -> &Application {
|
|
||||||
&self.app
|
|
||||||
}
|
|
||||||
|
|
||||||
fn default_shortcuts() -> Vec<shortcut::Shortcut> {
|
fn default_shortcuts() -> Vec<shortcut::Shortcut> {
|
||||||
use shortcut::ActionType::Press;
|
use shortcut::ActionType::Press;
|
||||||
vec![
|
vec![
|
||||||
|
@ -146,9 +146,9 @@ impl Drop for TraceCopies {
|
|||||||
/// A module containing an utility for detecting leaks.
|
/// A module containing an utility for detecting leaks.
|
||||||
///
|
///
|
||||||
/// If you suspect a particular struct is leaking, i.e. its instances are still present when we
|
/// If you suspect a particular struct is leaking, i.e. its instances are still present when we
|
||||||
/// expect them to be removed, you may add a [`Trace`] field to it. Then, at the point where we
|
/// expect them to be removed, you may add a [`Trace`] field to it and call [`enable`]. Then, at
|
||||||
/// expect all instances to be dropped, we may check the [`TRACKED_OBJECTS`] global variable, what
|
/// the point where we expect all instances to be dropped, we may check the [`TRACKED_OBJECTS`]
|
||||||
/// instances are still alive and their creation backtraces.
|
/// global variable, what instances are still alive and their creation backtraces.
|
||||||
pub mod leak_detector {
|
pub mod leak_detector {
|
||||||
use crate::*;
|
use crate::*;
|
||||||
|
|
||||||
|
Loading…
Reference in New Issue
Block a user