Skip to content

Commit

Permalink
Node click api (#17)
Browse files Browse the repository at this point in the history
* Node click api

* 0.0.21
  • Loading branch information
blitzarx1 authored Apr 27, 2023
1 parent d457117 commit 03ac132
Show file tree
Hide file tree
Showing 9 changed files with 64 additions and 69 deletions.
6 changes: 3 additions & 3 deletions Cargo.lock

Some generated files are not rendered by default. Learn more about how customized files appear on GitHub.

2 changes: 1 addition & 1 deletion Cargo.toml
Original file line number Diff line number Diff line change
@@ -1,6 +1,6 @@
[package]
name = "egui_graphs"
version = "0.0.20"
version = "0.0.21"
authors = ["Dmitrii Samsonov <[email protected]>"]
license = "MIT"
homepage = "https://github.com/blitzarx1/egui_graphs"
Expand Down
2 changes: 1 addition & 1 deletion examples/basic/Cargo.toml
Original file line number Diff line number Diff line change
@@ -1,6 +1,6 @@
[package]
name = "basic"
version = "0.0.20"
version = "0.0.21"
authors = ["Dmitrii Samsonov <[email protected]>"]
license = "MIT"
edition = "2021"
Expand Down
2 changes: 1 addition & 1 deletion examples/interactive/Cargo.toml
Original file line number Diff line number Diff line change
@@ -1,6 +1,6 @@
[package]
name = "interactive"
version = "0.0.20"
version = "0.0.21"
authors = ["Dmitrii Samsonov <[email protected]>"]
license = "MIT"
edition = "2021"
Expand Down
38 changes: 20 additions & 18 deletions examples/interactive/src/main.rs
Original file line number Diff line number Diff line change
Expand Up @@ -48,17 +48,17 @@ impl InteractiveApp {
simulation,
elements,

settings_interaction: Default::default(),
settings_navigation: Default::default(),

changes_receiver,
changes_sender,

settings_interaction: Default::default(),
settings_navigation: Default::default(),

selected_nodes: Default::default(),
selected_edges: Default::default(),

simulation_stopped: false,

fps: 0.,
fps_history: Default::default(),
last_update_time: Instant::now(),
Expand Down Expand Up @@ -186,9 +186,10 @@ impl App for InteractiveApp {
ui.add_space(5.);

ui.add_enabled_ui(!self.settings_navigation.fit_to_screen, |ui| {
ui.checkbox(&mut self.settings_navigation.zoom_and_pan, "pan & zoom")
.on_disabled_hover_text("disabled autofit to enable pan & zoom");
ui.label("Enable pan and zoom. To pan use LMB + drag and to zoom use Ctrl + Mouse Wheel.");
ui.vertical(|ui| {
ui.checkbox(&mut self.settings_navigation.zoom_and_pan, "pan & zoom");
ui.label("Enable pan and zoom. To pan use LMB + drag and to zoom use Ctrl + Mouse Wheel.");
}).response.on_disabled_hover_text("disabled autofit to enable pan & zoom");
});

ui.add_space(10.);
Expand All @@ -200,19 +201,20 @@ impl App for InteractiveApp {
ui.label("Enable drag. To drag use LMB + drag on a node.");

ui.add_space(5.);

if ui.checkbox(&mut self.settings_interaction.node_select, "select").changed() && !self.settings_interaction.node_select {
self.settings_interaction.node_multiselect = false;
};
ui.label("Enable select to select nodes with LMB click. If node is selected clicking on it again will deselect it.");

ui.add_enabled_ui(!self.settings_interaction.node_multiselect, |ui| {
ui.vertical(|ui| {
ui.checkbox(&mut self.settings_interaction.node_select, "select").on_disabled_hover_text("multiselect enables select");
ui.label("Enable select to select nodes with LMB click. If node is selected clicking on it again will deselect it.");
}).response.on_disabled_hover_text("multiselect enables select");
});

ui.add_space(5.);

ui.add_enabled_ui(self.settings_interaction.node_select, |ui| {
ui.checkbox(&mut self.settings_interaction.node_multiselect, "multiselect")
.on_disabled_hover_text("enable select to enable multiselect");
ui.label("Enable multiselect to select multiple nodes.");
});
if ui.checkbox(&mut self.settings_interaction.node_multiselect, "multiselect").changed() {
self.settings_interaction.node_select = true;
}
ui.label("Enable multiselect to select multiple nodes.");

ui.add_space(5.);

Expand Down
35 changes: 9 additions & 26 deletions src/changes.rs
Original file line number Diff line number Diff line change
Expand Up @@ -23,12 +23,12 @@ impl Changes {
};
}

pub(crate) fn scale_node(&mut self, idx: &usize, n: &Node, factor: f32) {
pub(crate) fn click_node(&mut self, idx: &usize) {
match self.nodes.get_mut(idx) {
Some(changes_node) => changes_node.scale(n, factor),
Some(changes_node) => changes_node.click(),
None => {
let mut changes_node = ChangesNode::default();
changes_node.scale(n, factor);
changes_node.click();
self.nodes.insert(*idx, changes_node);
}
};
Expand Down Expand Up @@ -99,18 +99,6 @@ impl Changes {
}
};
}

pub(crate) fn scale_edge(&mut self, e: &Edge, factor: f32) {
let key = e.id();
match self.edges.get_mut(&key) {
Some(changes_edge) => changes_edge.scale(e, factor),
None => {
let mut changes_edge = ChangesEdge::default();
changes_edge.scale(e, factor);
self.edges.insert(key, changes_edge);
}
};
}
}

/// Stores changes to the node properties
Expand All @@ -121,6 +109,7 @@ pub struct ChangesNode {
pub radius: Option<f32>,
pub selected: Option<bool>,
pub dragged: Option<bool>,
pub clicked: Option<bool>,
}

impl ChangesNode {
Expand Down Expand Up @@ -153,6 +142,11 @@ impl ChangesNode {
let dragged = self.dragged.get_or_insert(n.dragged);
*dragged = false;
}

fn click(&mut self) {
let clicked = self.clicked.get_or_insert(true);
*clicked = true;
}
}

/// Stores changes to the edge properties
Expand All @@ -166,17 +160,6 @@ pub struct ChangesEdge {
}

impl ChangesEdge {
fn scale(&mut self, n: &Edge, factor: f32) {
let width = self.width.get_or_insert(n.width);
*width *= factor;

let tip_size = self.tip_size.get_or_insert(n.tip_size);
*tip_size *= factor;

let curve_size = self.curve_size.get_or_insert(n.curve_size);
*curve_size *= factor;
}

fn select(&mut self, n: &Edge) {
let selected = self.selected.get_or_insert(n.selected);
*selected = true;
Expand Down
4 changes: 3 additions & 1 deletion src/elements.rs
Original file line number Diff line number Diff line change
Expand Up @@ -4,8 +4,10 @@ use egui::{Color32, Vec2};

use crate::{Changes, ChangesEdge, ChangesNode};

/// Struct `Elements` represents the collection of all nodes and edges in a graph.
/// Used to store the state of the graph, i.e. the location of the nodes.
/// It is passed to the GraphView widget and is used to draw the graph.
///
/// Changes to elements should be applied using the `apply_changes` method.
pub struct Elements {
nodes: HashMap<usize, Node>,
edges: HashMap<(usize, usize), Vec<Edge>>,
Expand Down
25 changes: 20 additions & 5 deletions src/graph_view.rs
Original file line number Diff line number Diff line change
Expand Up @@ -37,7 +37,7 @@ impl<'a> Widget for GraphView<'a> {
let state = self.draw_and_sync(&painter, &mut metadata);

self.handle_drags(&response, &state, &mut metadata);
self.handle_clicks(&response, &state, &mut metadata);
self.handle_click(&response, &state, &mut metadata);
self.handle_navigation(ui, &response, &state, &mut metadata);

metadata.store(ui);
Expand Down Expand Up @@ -113,17 +113,21 @@ impl<'a> GraphView<'a> {
}
}

fn handle_clicks(&self, response: &Response, state: &FrameState, metadata: &mut Metadata) {
if !self.setings_interaction.node_select {
fn handle_click(&self, response: &Response, state: &FrameState, metadata: &mut Metadata) {
if !response.clicked() {
return;
}
if !response.clicked() {

if !(self.setings_interaction.node_click
|| self.setings_interaction.node_select
|| self.setings_interaction.node_multiselect)
{
return;
}

// click on empty space
let node = self.node_by_pos(metadata, response.hover_pos().unwrap());
if node.is_none() {
if node.is_none() && self.setings_interaction.node_select {
self.deselect_all_nodes(state);
self.deselect_all_edges(state);
return;
Expand All @@ -134,6 +138,11 @@ impl<'a> GraphView<'a> {
}

fn handle_node_click(&self, idx: &usize, state: &FrameState) {
if !self.setings_interaction.node_select {
self.click_node(idx);
return;
}

let n = self.elements.get_node(idx).unwrap();
if n.selected {
self.deselect_node(idx, n);
Expand All @@ -148,6 +157,12 @@ impl<'a> GraphView<'a> {
self.select_node(idx, n);
}

fn click_node(&self, idx: &usize) {
let mut changes = Changes::default();
changes.click_node(idx);
self.send_changes(changes);
}

fn select_node(&self, idx: &usize, node: &Node) {
let mut changes = Changes::default();
changes.select_node(idx, node);
Expand Down
19 changes: 6 additions & 13 deletions src/settings.rs
Original file line number Diff line number Diff line change
@@ -1,25 +1,18 @@
#[derive(Debug, Clone)]
#[derive(Debug, Clone, Default)]
pub struct SettingsInteraction {
/// Node dragging
pub node_drag: bool,

/// Node selection
/// Allows clicking on nodes
pub node_click: bool,

/// Selects clicked node, enables node_click
pub node_select: bool,

/// Multiselection for nodes
/// Multiselection for nodes, enables node_click
pub node_multiselect: bool,
}

impl Default for SettingsInteraction {
fn default() -> Self {
Self {
node_drag: false,
node_select: false,
node_multiselect: false,
}
}
}

#[derive(Debug, Clone)]
pub struct SettingsNavigation {
/// Fit graph to the screen
Expand Down

0 comments on commit 03ac132

Please sign in to comment.