mirror of
https://github.com/enso-org/enso.git
synced 2024-12-20 12:31:45 +03:00
Improved node searcher (https://github.com/enso-org/ide/pull/519)
Original commit: be88749d88
This commit is contained in:
parent
a1af4b7da0
commit
b1e629716a
1
gui/src/rust/Cargo.lock
generated
1
gui/src/rust/Cargo.lock
generated
@ -1258,6 +1258,7 @@ dependencies = [
|
||||
"bimap 0.4.0 (registry+https://github.com/rust-lang/crates.io-index)",
|
||||
"console_error_panic_hook 0.1.6 (registry+https://github.com/rust-lang/crates.io-index)",
|
||||
"data 0.1.0",
|
||||
"enso-callback 0.1.0",
|
||||
"enso-frp 0.1.0",
|
||||
"enso-prelude 0.1.0",
|
||||
"enso-protocol 0.1.0",
|
||||
|
@ -33,7 +33,6 @@ use crate::system::web::StyleSetter;
|
||||
use crate::system::web;
|
||||
use crate::display::shape::ShapeSystemInstance;
|
||||
use crate::display::shape::system::ShapeSystemOf;
|
||||
use crate::display::layout::Alignment;
|
||||
|
||||
use display::style::data::DataMatch;
|
||||
use enso_frp as frp;
|
||||
|
@ -8,6 +8,7 @@ edition = "2018"
|
||||
crate-type = ["cdylib", "rlib"]
|
||||
|
||||
[dependencies]
|
||||
enso-callback = { version = "0.1.0" , path = "../lib/callback" }
|
||||
ensogl = { version = "0.1.0" , path = "../ensogl" }
|
||||
ensogl-core-msdf-sys = { version = "0.1.0" , path = "../ensogl/msdf-sys" }
|
||||
ensogl-system-web = { version = "0.1.0" , path = "../lib/system/web" }
|
||||
|
@ -9,10 +9,12 @@ use crate::view::text_editor::TextEditor;
|
||||
use crate::view::node_editor::NodeEditor;
|
||||
use crate::view::node_searcher::NodeSearcher;
|
||||
|
||||
use enso_callback as callback;
|
||||
use enso_frp::io::keyboard;
|
||||
use ensogl::application::Application;
|
||||
use ensogl::display::shape::text::glyph::font;
|
||||
use ensogl::display::traits::*;
|
||||
use ensogl::display::Uniform;
|
||||
use ensogl::display::world::World;
|
||||
use nalgebra::Vector2;
|
||||
use nalgebra::zero;
|
||||
@ -30,11 +32,15 @@ shared! { ViewLayout
|
||||
/// Initial implementation of ViewLayout with a TextEditor and NodeEditor.
|
||||
#[derive(Debug)]
|
||||
pub struct ViewLayoutData {
|
||||
text_editor : TextEditor,
|
||||
node_editor : NodeEditor,
|
||||
node_searcher : NodeSearcher,
|
||||
size : Vector2<f32>,
|
||||
logger : Logger
|
||||
text_editor : TextEditor,
|
||||
node_editor : NodeEditor,
|
||||
node_searcher : NodeSearcher,
|
||||
size : Vector2<f32>,
|
||||
logger : Logger,
|
||||
/// FIXME[dg]: This is a provisional code. Getting the mouse position from Uniform is bad. Mouse
|
||||
/// position should be retrieved from the frp network instead.
|
||||
mouse_position : Uniform<Vector2<i32>>,
|
||||
node_searcher_show_action : Option<callback::Handle>
|
||||
}
|
||||
|
||||
impl {
|
||||
@ -96,25 +102,38 @@ impl ViewLayout {
|
||||
, visualization_controller : controller::Visualization
|
||||
, fonts : &mut font::Registry
|
||||
) -> FallibleResult<Self> {
|
||||
let logger = logger.sub("ViewLayout");
|
||||
let world = &application.display;
|
||||
let text_editor = TextEditor::new(&logger,world,text_controller,kb_actions,fonts);
|
||||
let graph = graph_controller.graph.clone_ref();
|
||||
let node_searcher = NodeSearcher::new(world,&logger,graph,fonts);
|
||||
let graph_controller = graph_controller.clone_ref();
|
||||
let node_editor = NodeEditor::new
|
||||
let logger = logger.sub("ViewLayout");
|
||||
let world = &application.display;
|
||||
let text_editor = TextEditor::new(&logger,world,text_controller,kb_actions,fonts);
|
||||
let graph = graph_controller.graph.clone_ref();
|
||||
let node_editor = NodeEditor::new
|
||||
(&logger,application,graph_controller,visualization_controller).await?;
|
||||
let node_searcher = NodeSearcher::new(world,&logger,node_editor.clone_ref(),graph,fonts);
|
||||
world.add_child(&text_editor.display_object());
|
||||
world.add_child(&node_editor);
|
||||
world.add_child(&node_searcher);
|
||||
let size = zero();
|
||||
let data = ViewLayoutData {text_editor,node_editor,node_searcher,size,logger};
|
||||
let size = zero();
|
||||
let mouse_position = world.scene().mouse.position.clone_ref();
|
||||
let node_searcher_show_action = None;
|
||||
let data = ViewLayoutData{text_editor,node_editor,node_searcher,size,logger,mouse_position,
|
||||
node_searcher_show_action};
|
||||
let rc = Rc::new(RefCell::new(data));
|
||||
Ok(Self {rc}.init(world,kb_actions))
|
||||
}
|
||||
|
||||
fn init_keyboard(self, _keyboard_actions:&mut keyboard::Actions) -> Self {
|
||||
fn init_keyboard(self, keyboard_actions:&mut keyboard::Actions) -> Self {
|
||||
// TODO[ao] add here some useful staff (quitting project for example)
|
||||
let layout = self.rc.clone_ref();
|
||||
let keys = &[keyboard::Key::Tab];
|
||||
let node_searcher_show_action = keyboard_actions.add_action(keys, move || {
|
||||
let mut layout = layout.borrow_mut();
|
||||
let position = layout.mouse_position.get();
|
||||
//TODO[dg]: Test it when graph scene panning is working.
|
||||
let node_searcher_position = Vector3::new(position.x as f32,position.y as f32,0.0);
|
||||
layout.node_searcher.set_position(node_searcher_position);
|
||||
layout.node_searcher.show();
|
||||
});
|
||||
self.rc.borrow_mut().node_searcher_show_action = Some(node_searcher_show_action);
|
||||
self
|
||||
}
|
||||
|
||||
|
@ -3,7 +3,12 @@
|
||||
|
||||
use crate::prelude::*;
|
||||
|
||||
use crate::controller::graph::{NewNodeInfo, LocationHint};
|
||||
use crate::controller::graph::LocationHint;
|
||||
use crate::controller::graph::NewNodeInfo;
|
||||
use crate::model::module::NodeMetadata;
|
||||
use crate::model::module::Position;
|
||||
use crate::view::node_editor::NodeEditor;
|
||||
|
||||
use ensogl::data::color;
|
||||
use ensogl::display::shape::text::glyph::font;
|
||||
use ensogl::display::shape::text::text_field::TextField;
|
||||
@ -13,9 +18,10 @@ use ensogl::display;
|
||||
use ensogl::traits::*;
|
||||
|
||||
|
||||
#[derive(Clone,Debug)]
|
||||
#[derive(Clone,Debug,CloneRef)]
|
||||
pub struct NodeSearcher {
|
||||
display_object : display::object::Instance,
|
||||
node_editor : NodeEditor,
|
||||
text_field : TextField,
|
||||
controller : controller::graph::Handle,
|
||||
logger : Logger,
|
||||
@ -23,7 +29,11 @@ pub struct NodeSearcher {
|
||||
|
||||
impl NodeSearcher {
|
||||
pub fn new
|
||||
(world:&World, logger:&Logger, controller:controller::graph::Handle, fonts:&mut font::Registry)
|
||||
( world : &World
|
||||
, logger : &Logger
|
||||
, node_editor : NodeEditor
|
||||
, controller : controller::graph::Handle
|
||||
, fonts : &mut font::Registry)
|
||||
-> Self {
|
||||
let scene = world.scene();
|
||||
let camera = scene.camera();
|
||||
@ -31,40 +41,54 @@ impl NodeSearcher {
|
||||
let logger = logger.sub("NodeSearcher");
|
||||
let display_object = display::object::Instance::new(&logger);
|
||||
let properties = TextFieldProperties {
|
||||
font : fonts.get_or_load_embedded_font("DejaVuSansMono").unwrap(),
|
||||
text_size : 16.0,
|
||||
base_color : color::Rgba::new(1.0, 1.0, 1.0, 0.7),
|
||||
size : Vector2::new(screen.width,16.0),
|
||||
font : fonts.get_or_load_embedded_font("DejaVuSansMono").unwrap(),
|
||||
text_size : 16.0,
|
||||
base_color : color::Rgba::new(1.0, 1.0, 1.0, 0.7),
|
||||
size : Vector2::new(screen.width,16.0),
|
||||
};
|
||||
let text_field = TextField::new(world,properties);
|
||||
let text_field = TextField::new(world,properties);
|
||||
display_object.add_child(&text_field.display_object());
|
||||
let searcher = NodeSearcher{ display_object,text_field,controller,logger};
|
||||
let searcher = NodeSearcher{node_editor,display_object,text_field,controller,logger};
|
||||
searcher.initialize()
|
||||
}
|
||||
|
||||
fn initialize(self) -> Self {
|
||||
let text_field_weak = self.text_field.downgrade();
|
||||
let controller = self.controller.clone();
|
||||
let mut node_searcher = self.clone_ref();
|
||||
self.text_field.set_text_edit_callback(move |change| {
|
||||
// If the text edit callback is called, the TextEdit must be still alive.
|
||||
let text_field = text_field_weak.upgrade().unwrap();
|
||||
let field_content = text_field.get_content();
|
||||
let field_content = node_searcher.text_field.get_content();
|
||||
let expression = field_content.split('\n').next().unwrap();
|
||||
if change.inserted == "\n" {
|
||||
let metadata = default();
|
||||
let position = node_searcher.display_object.position();
|
||||
let position = position - node_searcher.node_editor.position();
|
||||
let position = Some(Position{vector:Vector2::new(position.x,position.y)});
|
||||
let metadata = Some(NodeMetadata{position});
|
||||
let id = None;
|
||||
let location_hint = LocationHint::End;
|
||||
let expression = expression.to_string();
|
||||
let new_node = NewNodeInfo { expression,metadata,id,location_hint };
|
||||
controller.add_node(new_node);
|
||||
text_field.clear_content();
|
||||
node_searcher.controller.add_node(new_node);
|
||||
node_searcher.hide();
|
||||
} else {
|
||||
// Keep only one line.
|
||||
text_field.set_content(expression);
|
||||
node_searcher.text_field.set_content(expression);
|
||||
}
|
||||
});
|
||||
self
|
||||
}
|
||||
|
||||
/// Show NodeSearcher if it is invisible.
|
||||
pub fn show(&mut self) {
|
||||
self.display_object.add_child(&self.text_field.display_object());
|
||||
self.text_field.clear_content();
|
||||
self.text_field.set_focus();
|
||||
}
|
||||
|
||||
/// Hide NodeSearcher if it is visible.
|
||||
pub fn hide(&mut self) {
|
||||
self.text_field.clear_content();
|
||||
self.display_object.remove_child(&self.text_field.display_object());
|
||||
}
|
||||
}
|
||||
|
||||
impl display::Object for NodeSearcher {
|
||||
|
Loading…
Reference in New Issue
Block a user