Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Placement of newly opened Component Browser dictated by the mouse pointer. #3301

Merged
merged 213 commits into from
Mar 31, 2022
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
Show all changes
213 commits
Select commit Hold shift + click to select a range
15b5a51
node creation refactoring
vitvakatu Feb 1, 2022
1b85682
opening searcher (doesn't really work)
vitvakatu Feb 1, 2022
a7e132b
Seems like refactored
farmaazon Feb 10, 2022
4f94e96
WIP
farmaazon Feb 11, 2022
514e4b1
WIP
farmaazon Feb 14, 2022
13f3aa4
WIP
farmaazon Feb 15, 2022
e08436b
Button is displayed, but with the wrong shadow
farmaazon Feb 15, 2022
1159a0f
The Shadow displayed correctly, and the button actually works
farmaazon Feb 15, 2022
b2f7949
Fixing node placement + bug
farmaazon Feb 16, 2022
63ef571
Code cleanup part 1
farmaazon Feb 16, 2022
6ca7c3f
Re-use free place finder in find_new_node_position
farmaazon Feb 17, 2022
fd70dc6
Move status bar to the top
farmaazon Feb 17, 2022
8bfe041
Merge remote-tracking branch 'origin/develop' into wip/farmaazon/add-…
farmaazon Feb 17, 2022
7d1f6cc
Fix linter issues
farmaazon Feb 17, 2022
7ba9752
Self-review
farmaazon Feb 17, 2022
bb6acce
Merge remote-tracking branch 'origin/develop' into wip/farmaazon/add-…
farmaazon Feb 17, 2022
3c24031
Restore old limit
farmaazon Feb 17, 2022
c1ed6c2
Change owners of integration tests
farmaazon Feb 17, 2022
0d9e7f3
Merge branch 'develop' into wip/farmaazon/add-node-button-180887253
farmaazon Feb 17, 2022
84113f1
Applying @wdanilo review
farmaazon Feb 17, 2022
133d36b
Merge branch 'develop' into wip/farmaazon/add-node-button-180887253
farmaazon Feb 18, 2022
0908481
Plus button add nodes on the center of screen
farmaazon Feb 18, 2022
4d548a0
Applying @vitvakatu comments and bugfixes
farmaazon Feb 21, 2022
a18b71a
DRAFT find_nearest_node()
akavel Feb 22, 2022
18fc97b
fix to compile
akavel Feb 22, 2022
b313d4a
WIP approach_area_contains()
akavel Feb 22, 2022
f57e865
DEBUG print nearest_node.id()
akavel Feb 22, 2022
98112c1
DEBUG in find_nearest_node()
akavel Feb 23, 2022
5dc6d0f
use approached_node for TAB node creation
akavel Feb 23, 2022
6a3a852
DEBUG approached_node
akavel Feb 23, 2022
6205a64
also handle DroppingEdge
akavel Feb 23, 2022
070c12f
DEBUG for DroppingEdge
akavel Feb 23, 2022
898919c
extract helper func & simplify somewhat
akavel Feb 23, 2022
25e1998
DEBUG
akavel Feb 23, 2022
890a1db
Revert "DEBUG"
akavel Feb 23, 2022
737f079
nearest-node algo tweak (geom. center)
akavel Feb 23, 2022
8a73101
better distance algorithm
akavel Feb 23, 2022
63201ac
DEBUG
akavel Feb 23, 2022
f94bf48
increase approach_area vertically
akavel Feb 23, 2022
ea1f605
refactor code around a bit
akavel Feb 23, 2022
9a69cf8
TODO
akavel Feb 23, 2022
f2663d1
Revert "DEBUG"
akavel Feb 23, 2022
65ecf8f
refactor into more funcs
akavel Feb 23, 2022
83a400d
cargo fmt
akavel Feb 23, 2022
e4623c1
CLEANUP todo
akavel Feb 23, 2022
f4700ca
Merge branch 'develop' into wip/farmaazon/add-node-button-180887253
vitvakatu Feb 23, 2022
daa6530
Add integration test for add node button
vitvakatu Feb 23, 2022
d6dc807
Fix comment
vitvakatu Feb 23, 2022
6544e70
Merge remote-tracking branch 'origin/wip/farmaazon/add-node-button-18…
akavel Feb 24, 2022
e30dd3e
Fix cursor style after removing node
farmaazon Feb 24, 2022
cfd384d
Merge remote-tracking branch 'origin/wip/farmaazon/add-node-button-18…
akavel Feb 24, 2022
96d063f
Merge branch 'develop' into wip/farmaazon/add-node-button-180887253
farmaazon Feb 24, 2022
9c9f31e
Merge remote-tracking branch 'origin/wip/farmaazon/add-node-button-18…
akavel Feb 24, 2022
f3a51be
tweak comment wording
akavel Feb 24, 2022
2052da6
rename consts
akavel Feb 24, 2022
263853b
use BoundingBox instead of OccupiedArea
akavel Feb 24, 2022
bc75ef9
fix grammar in comment
akavel Feb 24, 2022
995da5b
rearrange funcs
akavel Feb 24, 2022
933e0e4
rearrange more
akavel Feb 24, 2022
7d1d622
changelog
akavel Feb 24, 2022
8cf5001
missing link in changelog
akavel Feb 24, 2022
1d92bbd
Merge remote-tracking branch 'origin/develop' into wip/akavel/cb-plac…
akavel Feb 25, 2022
0ca1020
review: s/find_place_dictated_by_node/new_node_position_based_on_mouse
akavel Feb 25, 2022
3155b86
rename var
akavel Feb 25, 2022
7def385
review: rename new_node_position_after_dropping_edge
akavel Feb 25, 2022
4da6186
review: rename new_node_position_based_on_mouse_without_source
akavel Feb 25, 2022
bbef8fb
review: use theme instead of const
akavel Feb 25, 2022
7d417b5
shorten the name of guiding_node
akavel Feb 25, 2022
0f52d7c
cargo fmt
akavel Feb 25, 2022
869f650
review: docs WIP
akavel Feb 28, 2022
922195e
WIP simplify comment & rename func
akavel Feb 28, 2022
48b4889
review: add comments, modify names, improve nearest node distance cal…
akavel Feb 28, 2022
2e37cd1
grammarly tweaks
akavel Feb 28, 2022
05c6441
Merge branch 'develop' into wip/akavel/cb-placement-by-mouse-181076066
akavel Feb 28, 2022
7c243f1
WIP visualization.bounding_box FRP
akavel Mar 1, 2022
a68ba55
WIP
akavel Mar 2, 2022
9a884bf
WIP
akavel Mar 2, 2022
81d29e2
Revert "WIP"
akavel Mar 2, 2022
55c4aea
Revert "WIP"
akavel Mar 2, 2022
64bce6c
Revert "WIP visualization.bounding_box FRP"
akavel Mar 2, 2022
b62ab3c
WIP start incl. vis_enabled in node.bbox
akavel Mar 2, 2022
ea30f64
calculate visualization bbox
akavel Mar 2, 2022
c657e60
add fixme
akavel Mar 2, 2022
e07d9f3
slight rename
akavel Mar 2, 2022
696a61f
tweak fixme
akavel Mar 2, 2022
27b4eaa
BB.grow_to_include() + use it
akavel Mar 2, 2022
9e25fff
DEBUG mouse_pos & node.bbox
akavel Mar 2, 2022
9d4637a
DEBUG better
akavel Mar 2, 2022
da9419b
Revert "DEBUG better"
akavel Mar 2, 2022
a9b1d6a
Revert "DEBUG mouse_pos & node.bbox"
akavel Mar 2, 2022
922542e
BB.distance_squared()
akavel Mar 2, 2022
9665ddc
rename find_node_nearest_to_point
akavel Mar 2, 2022
34eaa17
improve naming of BB distance func
akavel Mar 2, 2022
9bd6f10
fix some names after review
akavel Mar 2, 2022
32b423c
another func rename
akavel Mar 2, 2022
042be8e
rename as suggested in code-review
akavel Mar 2, 2022
795841d
another rename
akavel Mar 2, 2022
35536cb
further renames etc
akavel Mar 2, 2022
d6e1234
cargo fmt
akavel Mar 2, 2022
42a302f
more renames
akavel Mar 2, 2022
5c49f97
fix to compile
akavel Mar 2, 2022
3fc560e
visualization_enabled_and_visible
akavel Mar 3, 2022
7185bf3
use bounding_box in find_free_place_for_node
akavel Mar 3, 2022
41b92a8
clone_ref not needed
akavel Mar 3, 2022
73990aa
left/right/top/bottom fn comments
akavel Mar 3, 2022
d3145b0
comment tweaks
akavel Mar 3, 2022
5d7823e
WIP tests
akavel Mar 3, 2022
ca501ca
DEBUG compile tests with serde
akavel Mar 3, 2022
6676283
add tests for bb funcs
akavel Mar 3, 2022
3a6ab35
better comment
akavel Mar 3, 2022
4d44ce7
add helper func for vis. offset calc.
akavel Mar 3, 2022
b324427
Merge remote-tracking branch 'origin/develop' into wip/akavel/cb-plac…
akavel Mar 3, 2022
193d86f
<kbd>TAB</kbd>
akavel Mar 3, 2022
4d57c8b
doc comments
akavel Mar 3, 2022
bc5d2b4
cargo fmt
akavel Mar 3, 2022
f25b882
wrap lines & remove debug
akavel Mar 3, 2022
e1d253f
cargo toml
akavel Mar 3, 2022
ff4a80b
node_bounding_box
akavel Mar 3, 2022
359346f
move node_bounding_box to separate func
akavel Mar 3, 2022
724a9cf
vert. align
akavel Mar 3, 2022
896f20f
rename
akavel Mar 3, 2022
0d438b7
pos -> position
akavel Mar 3, 2022
302a410
drop absolute_ prefix
akavel Mar 3, 2022
ac7d317
pos_of_bb_of_node
akavel Mar 3, 2022
e4c78a0
if_near -> if_close
akavel Mar 3, 2022
615089b
close enough, etc.
akavel Mar 3, 2022
edbe55d
explain distance + grammarly
akavel Mar 3, 2022
7057961
rephrase
akavel Mar 3, 2022
bf48d0a
Merge branch 'develop' into wip/akavel/cb-placement-by-mouse-181076066
akavel Mar 3, 2022
22e06e2
review: shorten map expression in node.frp
akavel Mar 4, 2022
3b465d2
review: use global min/max funcs
akavel Mar 4, 2022
7600787
review: impl PartialSemigroup for BoundingBox
akavel Mar 4, 2022
927053a
review: shorten theme names
akavel Mar 4, 2022
d628606
review: make tests less repetitive
akavel Mar 4, 2022
dce6304
assert_intersect
akavel Mar 4, 2022
ab2400a
massage tests: "bounding_box" fn
akavel Mar 4, 2022
c5e3348
review: but -> and
akavel Mar 4, 2022
c2af52a
review: do not disambig. fn links in rustdoc preemptively
akavel Mar 4, 2022
82865ef
review: pretty picture in comment
akavel Mar 4, 2022
5001f5c
review: drop find_ prefix
akavel Mar 4, 2022
5203c12
review: BBox fields explanation
akavel Mar 4, 2022
eb8555b
review: add comment explaining visualization enabled and not visible
akavel Mar 4, 2022
4825ee2
review: update names with better understanding of edge source meaning
akavel Mar 4, 2022
dd04d28
review: rename stream var to bbox_input
akavel Mar 4, 2022
c030eb2
review: WIP view_position_of_node_with_size
akavel Mar 7, 2022
702c2fb
review: improve names & move funcs to module scope
akavel Mar 7, 2022
4282013
more usages of view_pos
akavel Mar 7, 2022
5158030
review: assert_concat! macro
akavel Mar 7, 2022
e7f3acc
review: pretty macro for squared_distance test
akavel Mar 7, 2022
80be379
CLEANUP unused import
akavel Mar 7, 2022
654510c
review: pretty macro for assert_intersect
akavel Mar 7, 2022
1984754
tuple into bbox
akavel Mar 7, 2022
fb18c46
cargo fmt
akavel Mar 7, 2022
9735060
Merge remote-tracking branch 'origin/develop' into wip/akavel/cb-plac…
akavel Mar 7, 2022
142ba69
review: clarify squared_distance for points inside bbox
akavel Mar 7, 2022
1875975
review: drop if_close from name
akavel Mar 7, 2022
d7567bd
review: shorten some _position to _pos
akavel Mar 7, 2022
2e27f7e
cargo fmt
akavel Mar 7, 2022
e1237c2
CLEANUP dev-dependencies
akavel Mar 7, 2022
3aa13de
tweak comment
akavel Mar 7, 2022
1ae4cfe
workaround for weird formatting
akavel Mar 7, 2022
ecc7de0
grammarly
akavel Mar 7, 2022
e9d031c
Merge remote-tracking branch 'origin/develop' into wip/akavel/cb-plac…
akavel Mar 8, 2022
db6f981
review: make bounding_box callsite prettier
akavel Mar 9, 2022
b982861
review: background_offset & visualization_offset + docs
akavel Mar 9, 2022
ef87ebf
review: add documentation to find_free_place_for_node
akavel Mar 9, 2022
8ad1045
review: fix var name from _pos to _offset
akavel Mar 9, 2022
72a0267
fix var name - pos, not offset
akavel Mar 9, 2022
8aca3da
review: x_offset_to_node_center
akavel Mar 10, 2022
3060616
review: do not destructure a tuple
akavel Mar 10, 2022
e71a5d1
review: do not align arrows vertically
akavel Mar 10, 2022
cecbdba
review: do not reference Node docs in vis_offset func
akavel Mar 10, 2022
1a7f716
review: WIP start extracting helper mod
akavel Mar 10, 2022
61b6f74
move funcs to separate file
akavel Mar 10, 2022
d4d2b7b
WIP comments
akavel Mar 10, 2022
71a43af
tweak comment more
akavel Mar 10, 2022
de30583
tweak comment more
akavel Mar 10, 2022
12ce0b5
improve CHANGELOG with Giuliano
akavel Mar 10, 2022
c3b045a
WIP replace old comment with new
akavel Mar 11, 2022
31fc8c6
tweak the comment of find_free_place_for_node
akavel Mar 11, 2022
16121aa
tweak more & rename func
akavel Mar 11, 2022
82363db
rename module to new_node_position
akavel Mar 11, 2022
579f126
cargo fmt + comments fmt
akavel Mar 11, 2022
a256309
tweak comments
akavel Mar 11, 2022
5f13585
more comments
akavel Mar 11, 2022
85922c9
tweak docs
akavel Mar 11, 2022
312d6a7
tweak
akavel Mar 11, 2022
1cbda1a
tweak more
akavel Mar 11, 2022
a807e5c
section comments
akavel Mar 11, 2022
a839356
section tweak
akavel Mar 11, 2022
b6cd0a0
section tweak
akavel Mar 11, 2022
7ba9855
## avail. pos
akavel Mar 11, 2022
26e3aad
more comm. tweaks
akavel Mar 11, 2022
5d7a142
availability
akavel Mar 11, 2022
58962bd
review: use concat_ref in node::bounding_box()
akavel Mar 16, 2022
55dee13
Merge remote-tracking branch 'origin/develop' into wip/akavel/cb-plac…
akavel Mar 17, 2022
6d90620
review: make free_place_finder submod of new_node_position
akavel Mar 17, 2022
97e086a
review: WIP extracting code from create_node() to the new module
akavel Mar 17, 2022
7fb3ed5
docs for new_node_position
akavel Mar 17, 2022
9d98437
tweak new_node_position() desc
akavel Mar 17, 2022
91fef63
data_source_for_new_node
akavel Mar 17, 2022
3e701f8
Merge branch 'develop' into wip/akavel/cb-placement-by-mouse-181076066
akavel Mar 17, 2022
40a17e0
Merge remote-tracking branch 'origin/develop' into wip/akavel/cb-plac…
akavel Mar 21, 2022
4c5c3da
forgot to commit a file
akavel Mar 21, 2022
876dedd
Merge remote-tracking branch 'origin/develop' into wip/akavel/cb-plac…
akavel Mar 29, 2022
9832d58
Merge remote-tracking branch 'origin/develop' into wip/akavel/cb-plac…
akavel Mar 29, 2022
a0256c6
Integration test and debugging
farmaazon Mar 21, 2022
8e895ca
Cleaning Debugs
farmaazon Mar 29, 2022
28520ba
WIP
farmaazon Mar 30, 2022
75de4ca
Merge remote-tracking branch 'origin/develop' into wip/akavel/cb-plac…
farmaazon Mar 30, 2022
a65fa98
Turn off optimizations in integration tests
farmaazon Mar 31, 2022
0df2d56
Merge branch 'develop' into wip/akavel/cb-placement-by-mouse-181076066
mergify[bot] Mar 31, 2022
af0a276
Merge branch 'develop' into wip/akavel/cb-placement-by-mouse-181076066
farmaazon Mar 31, 2022
File filter

Filter by extension

Filter by extension


Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
6 changes: 6 additions & 0 deletions CHANGELOG.md
Original file line number Diff line number Diff line change
Expand Up @@ -2,6 +2,11 @@

#### Visual Environment

- [Nodes created near existing nodes via the <kbd>TAB</kbd> key or by dropping a
connection are now repositioned and aligned to existing nodes.][3301] This is
to make the resulting graph prettier and avoid overlapping. In such cases,
created nodes will be placed below an existing node or on the bottom-left
diagonal if there is no space underneath.
- [Nodes can be added to the graph by double-clicking the output ports of
existing nodes (or by clicking them with the right mouse button).][3346]
- [Node Searcher preserves its zoom factor.][3327] The visible size of the node
Expand Down Expand Up @@ -106,6 +111,7 @@
[3285]: https://github.com/enso-org/enso/pull/3285
[3287]: https://github.com/enso-org/enso/pull/3287
[3292]: https://github.com/enso-org/enso/pull/3292
[3301]: https://github.com/enso-org/enso/pull/3301
[3302]: https://github.com/enso-org/enso/pull/3302
[3305]: https://github.com/enso-org/enso/pull/3305
[3309]: https://github.com/enso-org/enso/pull/3309
Expand Down
5 changes: 4 additions & 1 deletion Cargo.toml
Original file line number Diff line number Diff line change
Expand Up @@ -41,4 +41,7 @@ debug-assertions = true

[profile.integration-test]
inherits = "test"
opt-level = 2
# The integration-test profile was created to be able run integration tests with optimizations (as they took a lot of
# time). There is, however, an issue with running them with optimizations #181740444.
# opt-level = 2
opt-level = 0
71 changes: 54 additions & 17 deletions app/gui/view/graph-editor/src/component/node.rs
Original file line number Diff line number Diff line change
Expand Up @@ -610,21 +610,22 @@ impl NodeModel {
self.drag_area.size.set(padded_size);
self.error_indicator.size.set(padded_size);
self.vcs_indicator.set_size(padded_size);
self.backdrop.mod_position(|t| t.x = width / 2.0);
self.background.mod_position(|t| t.x = width / 2.0);
self.drag_area.mod_position(|t| t.x = width / 2.0);
self.error_indicator.set_position_x(width / 2.0);
self.vcs_indicator.set_position_x(width / 2.0);
let x_offset_to_node_center = x_offset_to_node_center(width);
self.backdrop.set_position_x(x_offset_to_node_center);
self.background.set_position_x(x_offset_to_node_center);
self.drag_area.set_position_x(x_offset_to_node_center);
self.error_indicator.set_position_x(x_offset_to_node_center);
self.vcs_indicator.set_position_x(x_offset_to_node_center);

let action_bar_width = ACTION_BAR_WIDTH;
self.action_bar.mod_position(|t| {
t.x = width + CORNER_RADIUS + action_bar_width / 2.0;
t.x = x_offset_to_node_center + width / 2.0 + CORNER_RADIUS + action_bar_width / 2.0;
});
self.action_bar.frp.set_size(Vector2::new(action_bar_width, ACTION_BAR_HEIGHT));

let visualization_pos = Vector2(width / 2.0, VISUALIZATION_OFFSET_Y);
self.error_visualization.set_position_xy(visualization_pos);
self.visualization.set_position_xy(visualization_pos);
let visualization_offset = visualization_offset(width);
self.error_visualization.set_position_xy(visualization_offset);
self.visualization.set_position_xy(visualization_offset);

size
}
Expand Down Expand Up @@ -752,14 +753,6 @@ impl Node {
eval new_size ((t) model.output.frp.set_size.emit(t));


// === Bounding Box ===
bounding_box_input <- all2(&new_size,&position);
out.bounding_box <+ bounding_box_input.map(|(size,position)| {
let position = position - Vector2::new(0.0,size.y / 2.0);
BoundingBox::from_position_and_size(position,*size)
});


// === Action Bar ===

let visualization_enabled = action_bar.action_visibility.clone_ref();
Expand Down Expand Up @@ -934,6 +927,16 @@ impl Node {
<+ visualization_visible.not().and(&no_error_set);


// === Bounding Box ===

let visualization_size = &model.visualization.frp.size;
// Visualization can be enabled and not visible when the node has an error.
visualization_enabled_and_visible <- visualization_enabled && visualization_visible;
MichaelMauderer marked this conversation as resolved.
Show resolved Hide resolved
bbox_input <- all4(
&position,&new_size,&visualization_enabled_and_visible,visualization_size);
out.bounding_box <+ bbox_input.map(|(a,b,c,d)| bounding_box(*a,*b,*c,*d));


// === VCS Handling ===

model.vcs_indicator.frp.set_status <+ input.set_vcs_status;
Expand Down Expand Up @@ -971,6 +974,40 @@ impl display::Object for Node {
}


// === Positioning ===

fn x_offset_to_node_center(node_width: f32) -> f32 {
node_width / 2.0
}

/// Calculate a position where to render the [`visualization::Container`] of a node, relative to
/// the node's origin.
fn visualization_offset(node_width: f32) -> Vector2 {
Vector2(x_offset_to_node_center(node_width), VISUALIZATION_OFFSET_Y)
}

fn bounding_box(
node_position: Vector2,
node_size: Vector2,
visualization_enabled_and_visible: bool,
visualization_size: Vector2,
) -> BoundingBox {
let x_offset_to_node_center = x_offset_to_node_center(node_size.x);
let node_bbox_pos = node_position + Vector2(x_offset_to_node_center, 0.0) - node_size / 2.0;
let node_bbox = BoundingBox::from_position_and_size(node_bbox_pos, node_size);
if visualization_enabled_and_visible {
let visualization_offset = visualization_offset(node_size.x);
let visualization_pos = node_position + visualization_offset;
let visualization_bbox_pos = visualization_pos - visualization_size / 2.0;
let visualization_bbox =
BoundingBox::from_position_and_size(visualization_bbox_pos, visualization_size);
node_bbox.concat_ref(visualization_bbox)
} else {
node_bbox
}
}



// ==================
// === Test Utils ===
Expand Down
97 changes: 30 additions & 67 deletions app/gui/view/graph-editor/src/lib.rs
Original file line number Diff line number Diff line change
Expand Up @@ -31,8 +31,7 @@ pub mod component;

pub mod builtin;
pub mod data;
#[warn(missing_docs)]
pub mod free_place_finder;
pub mod new_node_position;
#[warn(missing_docs)]
pub mod profiling;
#[warn(missing_docs)]
Expand All @@ -49,8 +48,6 @@ use crate::component::visualization;
use crate::component::visualization::instance::PreprocessorConfiguration;
use crate::component::visualization::MockDataGenerator3D;
use crate::data::enso;
use crate::free_place_finder::find_free_place;
use crate::free_place_finder::OccupiedArea;
pub use crate::node::profiling::Status as NodeProfilingStatus;

use enso_config::ARGS;
Expand Down Expand Up @@ -394,6 +391,12 @@ impl<K, V, S> SharedHashMap<K, V, S> {
where K: Clone {
self.raw.borrow().keys().cloned().collect_vec()
}

/// Get the vector of map's values.
pub fn values(&self) -> Vec<V>
where V: Clone {
self.raw.borrow().values().cloned().collect_vec()
}
}


Expand Down Expand Up @@ -1388,17 +1391,20 @@ impl GraphEditorModelWithNetwork {

// === Node Creation ===

/// Describes the way used to request creation of a new node.
#[derive(Clone, Debug)]
enum WayOfCreatingNode {
pub enum WayOfCreatingNode {
/// "add_node" FRP event was emitted.
AddNodeEvent,
/// "start_node_creation" FRP event was emitted.
StartCreationEvent,
/// "start_node_creation_from_port" FRP event was emitted.
#[allow(missing_docs)]
StartCreationFromPortEvent { endpoint: EdgeEndpoint },
/// add_node_button was clicked.
ClickingButton,
/// The edge was dropped on the stage.
#[allow(missing_docs)]
DroppingEdge { edge_id: EdgeId },
}

Expand All @@ -1425,36 +1431,33 @@ impl GraphEditorModelWithNetwork {
way: &WayOfCreatingNode,
mouse_position: Vector2,
) -> (NodeId, Option<NodeSource>, bool) {
use WayOfCreatingNode::*;
let should_edit = !matches!(way, AddNodeEvent);
let selection = self.nodes.selected.first_cloned();
let source_node = match way {
AddNodeEvent => None,
StartCreationEvent | ClickingButton => selection,
DroppingEdge { edge_id } => self.edge_source_node_id(*edge_id),
StartCreationFromPortEvent { endpoint } => Some(endpoint.node_id),
};
let source = source_node.map(|node| NodeSource { node });
let screen_center =
self.scene().screen_to_object_space(&self.display_object, Vector2(0.0, 0.0));
let position: Vector2 = match way {
AddNodeEvent => default(),
StartCreationEvent | ClickingButton if selection.is_some() =>
self.find_free_place_under(selection.unwrap()),
StartCreationEvent => mouse_position,
ClickingButton =>
self.find_free_place_for_node(screen_center, Vector2(0.0, -1.0)).unwrap(),
DroppingEdge { .. } => mouse_position,
StartCreationFromPortEvent { endpoint } => self.find_free_place_under(endpoint.node_id),
};
let position = new_node_position::new_node_position(self, way, selection, mouse_position);
let node = self.new_node(ctx);
node.set_position_xy(position);
let should_edit = !matches!(way, WayOfCreatingNode::AddNodeEvent);
if should_edit {
node.view.set_expression(node::Expression::default());
}
let source = self.data_source_for_new_node(way, selection);
(node.id(), source, should_edit)
}

fn data_source_for_new_node(
&self,
way: &WayOfCreatingNode,
selection: Option<NodeId>,
) -> Option<NodeSource> {
use WayOfCreatingNode::*;
let source_node = match way {
AddNodeEvent => None,
StartCreationEvent | ClickingButton => selection,
DroppingEdge { edge_id } => self.edge_source_node_id(*edge_id),
StartCreationFromPortEvent { endpoint } => Some(endpoint.node_id),
};
source_node.map(|node| NodeSource { node })
}

fn new_node(&self, ctx: &NodeCreationContext) -> Node {
use ensogl::application::command::FrpNetworkProvider;
let view = component::Node::new(&self.app, self.vis_registry.clone_ref());
Expand Down Expand Up @@ -1722,7 +1725,7 @@ impl GraphEditorModel {

/// Create a new node and place it at a free place below `above` node.
pub fn add_node_below(&self, above: NodeId) -> NodeId {
let pos = self.find_free_place_under(above);
let pos = new_node_position::under(self, above);
self.add_node_at(pos)
}

Expand All @@ -1732,46 +1735,6 @@ impl GraphEditorModel {
self.frp.set_node_position((node_id, pos));
node_id
}

/// Return the first available position for a new node below `node_above` node.
pub fn find_free_place_under(&self, node_above: NodeId) -> Vector2 {
let above_pos = self.node_position(node_above);
let y_gap = self.frp.default_y_gap_between_nodes.value();
let y_offset = y_gap + node::HEIGHT;
let starting_point = above_pos - Vector2(0.0, y_offset);
let direction = Vector2(-1.0, 0.0);
self.find_free_place_for_node(starting_point, direction).unwrap()
}

/// Return the first unoccupied point when going along the ray starting from `starting_point`
/// and parallel to `direction` vector.
pub fn find_free_place_for_node(
&self,
starting_from: Vector2,
direction: Vector2,
) -> Option<Vector2> {
let x_gap = self.frp.default_x_gap_between_nodes.value();
let y_gap = self.frp.default_y_gap_between_nodes.value();
// This is how much horizontal space we are looking for.
let min_spacing = self.frp.min_x_spacing_for_new_nodes.value();
let nodes = self.nodes.all.raw.borrow();
// The "occupied area" for given node consists of:
// - area taken by node view (obviously);
// - the minimum gap between nodes in all directions, so the new node won't be "glued" to
// another;
// - the new node size measured from origin point at each direction accordingly: because
// `find_free_place` looks for free place for the origin point, and we want to fit not
// only the point, but the whole node.
let node_areas = nodes.values().map(|node| {
let position = node.position();
let left = position.x - x_gap - min_spacing;
let right = position.x + node.view.model.width() + x_gap;
let top = position.y + node::HEIGHT + y_gap;
let bottom = position.y - node::HEIGHT - y_gap;
OccupiedArea { x1: left, x2: right, y1: top, y2: bottom }
});
find_free_place(starting_from, direction, node_areas)
}
}


Expand Down
Loading