Make Nodes on graph draggable

This commit is contained in:
Tom A. Wagner
2020-12-17 11:26:41 +01:00
parent c72bef364d
commit 82c9a5bd4d
3 changed files with 50 additions and 11 deletions

1
Cargo.lock generated
View File

@@ -331,6 +331,7 @@ name = "graphui-rs"
version = "0.0.1" version = "0.0.1"
dependencies = [ dependencies = [
"cairo-rs", "cairo-rs",
"gdk",
"gio", "gio",
"glib", "glib",
"gtk", "gtk",

View File

@@ -9,5 +9,6 @@ edition = "2018"
[dependencies] [dependencies]
cairo-rs = "0.9.1" cairo-rs = "0.9.1"
glib = "0.10.3" glib = "0.10.3"
gdk = "0.13.2"
gtk = "0.9.2" gtk = "0.9.2"
gio = "0.9.1" gio = "0.9.1"

View File

@@ -1,26 +1,63 @@
use gtk::GridExt; use gtk::prelude::*;
use gdk::prelude::*;
use std::collections::HashMap; use std::collections::HashMap;
pub struct PipewireNode { pub struct PipewireNode {
pub(super) widget: gtk::Grid, pub(super) widget: gtk::Grid,
_label: gtk::Label, label: gtk::Label,
label_box: gtk::EventBox,
ingoing_ports: HashMap<u32, gtk::Button>, ingoing_ports: HashMap<u32, gtk::Button>,
outgoing_ports: HashMap<u32, gtk::Button>, outgoing_ports: HashMap<u32, gtk::Button>,
} }
impl PipewireNode { impl PipewireNode {
pub fn new(name: &str) -> Self { pub fn new(name: &str) -> Self {
let widget = gtk::Grid::new(); let result = Self {
let label = gtk::Label::new(Some(name)); widget: gtk::Grid::new(),
widget.attach(&label, 0, 0, 2, 1); label: gtk::Label::new(Some(name)),
label_box: gtk::EventBox::new(),
Self {
widget,
_label: label,
ingoing_ports: HashMap::new(), ingoing_ports: HashMap::new(),
outgoing_ports: HashMap::new(), outgoing_ports: HashMap::new(),
} };
result.label_box.add(&result.label);
result.widget.attach(&result.label_box, 0, 0, 2, 1);
result
.label_box
.add_events(gdk::EventMask::BUTTON1_MOTION_MASK);
result
.label_box
.connect_motion_notify_event(|label, event| {
let grid = label
.get_ancestor(gtk::Grid::static_type())
.unwrap()
.dynamic_cast::<gtk::Grid>()
.unwrap();
let graphview = grid
.get_ancestor(gtk::Layout::static_type())
.unwrap()
.dynamic_cast::<gtk::Layout>()
.unwrap();
// Use root coordinates to prevent jumping around
// as moving the widget also influences the relative coordinates.
let (x, y) = event.get_root();
let (offset_x, offset_y) = graphview.get_window().unwrap().get_root_origin();
// TODO: Calculate proper values to center the mouse on the label
// instead of using hardcoded offsets.
graphview.set_child_x(&grid, x as i32 - offset_x - 100);
graphview.set_child_y(&grid, y as i32 - offset_y - 50);
// FIXME: If links become proper widgets,
// we don't need to redraw the full graph everytime.
graphview.queue_draw();
Inhibit(true)
});
result
} }
pub fn add_ingoing_port(&mut self, id: u32, port: gtk::Button) { pub fn add_ingoing_port(&mut self, id: u32, port: gtk::Button) {