diff --git a/Cargo.lock b/Cargo.lock index cd7d8fd..c3c30e1 100644 --- a/Cargo.lock +++ b/Cargo.lock @@ -331,6 +331,7 @@ name = "graphui-rs" version = "0.0.1" dependencies = [ "cairo-rs", + "gdk", "gio", "glib", "gtk", diff --git a/Cargo.toml b/Cargo.toml index 1994888..5adba8d 100644 --- a/Cargo.toml +++ b/Cargo.toml @@ -9,5 +9,6 @@ edition = "2018" [dependencies] cairo-rs = "0.9.1" glib = "0.10.3" +gdk = "0.13.2" gtk = "0.9.2" gio = "0.9.1" \ No newline at end of file diff --git a/src/view/pipewire_node.rs b/src/view/pipewire_node.rs index 572f6cd..6d70625 100644 --- a/src/view/pipewire_node.rs +++ b/src/view/pipewire_node.rs @@ -1,26 +1,63 @@ -use gtk::GridExt; - +use gtk::prelude::*; +use gdk::prelude::*; use std::collections::HashMap; pub struct PipewireNode { pub(super) widget: gtk::Grid, - _label: gtk::Label, + label: gtk::Label, + label_box: gtk::EventBox, ingoing_ports: HashMap, outgoing_ports: HashMap, } impl PipewireNode { pub fn new(name: &str) -> Self { - let widget = gtk::Grid::new(); - let label = gtk::Label::new(Some(name)); - widget.attach(&label, 0, 0, 2, 1); - - Self { - widget, - _label: label, + let result = Self { + widget: gtk::Grid::new(), + label: gtk::Label::new(Some(name)), + label_box: gtk::EventBox::new(), ingoing_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::() + .unwrap(); + let graphview = grid + .get_ancestor(gtk::Layout::static_type()) + .unwrap() + .dynamic_cast::() + .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) {