Update gtk and glib dependencies

This commit is contained in:
Tom A. Wagner
2023-02-12 20:21:28 +01:00
parent 4ed52bb00d
commit 146fb65dc5
7 changed files with 205 additions and 248 deletions

115
Cargo.lock generated
View File

@@ -42,22 +42,23 @@ checksum = "bef38d45163c2f1dde094a7dfd33ccf595c92905c8f8f4fdc18d06fb1037718a"
[[package]] [[package]]
name = "cairo-rs" name = "cairo-rs"
version = "0.15.12" version = "0.17.0"
source = "registry+https://github.com/rust-lang/crates.io-index" source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "c76ee391b03d35510d9fa917357c7f1855bd9a6659c95a1b392e33f49b3369bc" checksum = "a8af54f5d48af1226928adc1f57edd22f5df1349e7da1fc96ae15cf43db0e871"
dependencies = [ dependencies = [
"bitflags", "bitflags",
"cairo-sys-rs", "cairo-sys-rs",
"glib", "glib",
"libc", "libc",
"once_cell",
"thiserror", "thiserror",
] ]
[[package]] [[package]]
name = "cairo-sys-rs" name = "cairo-sys-rs"
version = "0.15.1" version = "0.17.0"
source = "registry+https://github.com/rust-lang/crates.io-index" source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "3c55d429bef56ac9172d25fecb85dc8068307d17acd74b377866b7a1ef25d3c8" checksum = "f55382a01d30e5e53f185eee269124f5e21ab526595b872751278dfbb463594e"
dependencies = [ dependencies = [
"glib-sys", "glib-sys",
"libc", "libc",
@@ -173,6 +174,17 @@ version = "0.3.26"
source = "registry+https://github.com/rust-lang/crates.io-index" source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "bfb8371b6fb2aeb2d280374607aeabfc99d95c72edfe51692e42d3d7f0d08531" checksum = "bfb8371b6fb2aeb2d280374607aeabfc99d95c72edfe51692e42d3d7f0d08531"
[[package]]
name = "futures-macro"
version = "0.3.26"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "95a73af87da33b5acf53acfebdc339fe592ecf5357ac7c0a7734ab9d8c876a70"
dependencies = [
"proc-macro2",
"quote",
"syn",
]
[[package]] [[package]]
name = "futures-task" name = "futures-task"
version = "0.3.26" version = "0.3.26"
@@ -186,6 +198,7 @@ source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "9c1d6de3acfef38d2be4b1f543f553131788603495be83da675e180c8d6b7bd1" checksum = "9c1d6de3acfef38d2be4b1f543f553131788603495be83da675e180c8d6b7bd1"
dependencies = [ dependencies = [
"futures-core", "futures-core",
"futures-macro",
"futures-task", "futures-task",
"pin-project-lite", "pin-project-lite",
"pin-utils", "pin-utils",
@@ -194,22 +207,23 @@ dependencies = [
[[package]] [[package]]
name = "gdk-pixbuf" name = "gdk-pixbuf"
version = "0.15.11" version = "0.17.0"
source = "registry+https://github.com/rust-lang/crates.io-index" source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "ad38dd9cc8b099cceecdf41375bb6d481b1b5a7cd5cd603e10a69a9383f8619a" checksum = "b023fbe0c6b407bd3d9805d107d9800da3829dc5a676653210f1d5f16d7f59bf"
dependencies = [ dependencies = [
"bitflags", "bitflags",
"gdk-pixbuf-sys", "gdk-pixbuf-sys",
"gio", "gio",
"glib", "glib",
"libc", "libc",
"once_cell",
] ]
[[package]] [[package]]
name = "gdk-pixbuf-sys" name = "gdk-pixbuf-sys"
version = "0.15.10" version = "0.17.0"
source = "registry+https://github.com/rust-lang/crates.io-index" source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "140b2f5378256527150350a8346dbdb08fadc13453a7a2d73aecd5fab3c402a7" checksum = "7b41bd2b44ed49d99277d3925652a163038bd5ed943ec9809338ffb2f4391e3b"
dependencies = [ dependencies = [
"gio-sys", "gio-sys",
"glib-sys", "glib-sys",
@@ -220,9 +234,9 @@ dependencies = [
[[package]] [[package]]
name = "gdk4" name = "gdk4"
version = "0.4.8" version = "0.6.0"
source = "registry+https://github.com/rust-lang/crates.io-index" source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "4fabb7cf843c26b085a5d68abb95d0c0bf27a9ae2eeff9c4adb503a1eb580876" checksum = "6e4887e17b6926db51f1e538d871a8b1f5ceb5dfa3bd0034dc42ec355b390d8f"
dependencies = [ dependencies = [
"bitflags", "bitflags",
"cairo-rs", "cairo-rs",
@@ -236,9 +250,9 @@ dependencies = [
[[package]] [[package]]
name = "gdk4-sys" name = "gdk4-sys"
version = "0.4.8" version = "0.6.0"
source = "registry+https://github.com/rust-lang/crates.io-index" source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "efe7dcb44f5c00aeabff3f69abfc5673de46559070f89bd3fbb7b66485d9cef2" checksum = "f4993c019bf03d18137c00ddafb2b23e73f7cbb45ae244f52af2542a3f4a9452"
dependencies = [ dependencies = [
"cairo-sys-rs", "cairo-sys-rs",
"gdk-pixbuf-sys", "gdk-pixbuf-sys",
@@ -253,26 +267,29 @@ dependencies = [
[[package]] [[package]]
name = "gio" name = "gio"
version = "0.15.12" version = "0.17.0"
source = "registry+https://github.com/rust-lang/crates.io-index" source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "68fdbc90312d462781a395f7a16d96a2b379bb6ef8cd6310a2df272771c4283b" checksum = "1981edf8679d2f2c8ec3120015867f45aa0a1c2d5e3e129ca2f7dda174d3d2a9"
dependencies = [ dependencies = [
"bitflags", "bitflags",
"futures-channel", "futures-channel",
"futures-core", "futures-core",
"futures-io", "futures-io",
"futures-util",
"gio-sys", "gio-sys",
"glib", "glib",
"libc", "libc",
"once_cell", "once_cell",
"pin-project-lite",
"smallvec",
"thiserror", "thiserror",
] ]
[[package]] [[package]]
name = "gio-sys" name = "gio-sys"
version = "0.15.10" version = "0.17.0"
source = "registry+https://github.com/rust-lang/crates.io-index" source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "32157a475271e2c4a023382e9cab31c4584ee30a97da41d3c4e9fdd605abcf8d" checksum = "b5d3076ecb86c8c3a672c9843d6232b3a344fb81d304d0ba1ac64b23343efa46"
dependencies = [ dependencies = [
"glib-sys", "glib-sys",
"gobject-sys", "gobject-sys",
@@ -283,20 +300,23 @@ dependencies = [
[[package]] [[package]]
name = "glib" name = "glib"
version = "0.15.12" version = "0.17.0"
source = "registry+https://github.com/rust-lang/crates.io-index" source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "edb0306fbad0ab5428b0ca674a23893db909a98582969c9b537be4ced78c505d" checksum = "ac347af59233f0544ce00a37bad50f4ac401d006505b26d80ad6d9bbecf6493f"
dependencies = [ dependencies = [
"bitflags", "bitflags",
"futures-channel", "futures-channel",
"futures-core", "futures-core",
"futures-executor", "futures-executor",
"futures-task", "futures-task",
"futures-util",
"gio-sys",
"glib-macros", "glib-macros",
"glib-sys", "glib-sys",
"gobject-sys", "gobject-sys",
"libc", "libc",
"log", "log",
"memchr",
"once_cell", "once_cell",
"smallvec", "smallvec",
"thiserror", "thiserror",
@@ -304,9 +324,9 @@ dependencies = [
[[package]] [[package]]
name = "glib-macros" name = "glib-macros"
version = "0.15.11" version = "0.17.0"
source = "registry+https://github.com/rust-lang/crates.io-index" source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "25a68131a662b04931e71891fb14aaf65ee4b44d08e8abc10f49e77418c86c64" checksum = "5965ae1a44aa4bae4e1e6970f25b66c058fef873d2626c9932a41128dbeea03f"
dependencies = [ dependencies = [
"anyhow", "anyhow",
"heck", "heck",
@@ -319,9 +339,9 @@ dependencies = [
[[package]] [[package]]
name = "glib-sys" name = "glib-sys"
version = "0.15.10" version = "0.17.0"
source = "registry+https://github.com/rust-lang/crates.io-index" source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "ef4b192f8e65e9cf76cbf4ea71fa8e3be4a0e18ffe3d68b8da6836974cc5bad4" checksum = "9ddcb73fa8236277bedadaaadb76aef49c85d66340f83bece244f46c2d4f0e01"
dependencies = [ dependencies = [
"libc", "libc",
"system-deps", "system-deps",
@@ -335,9 +355,9 @@ checksum = "d2fabcfbdc87f4758337ca535fb41a6d701b65693ce38287d856d1674551ec9b"
[[package]] [[package]]
name = "gobject-sys" name = "gobject-sys"
version = "0.15.10" version = "0.17.0"
source = "registry+https://github.com/rust-lang/crates.io-index" source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "0d57ce44246becd17153bd035ab4d32cfee096a657fc01f2231c9278378d1e0a" checksum = "9a0155d388840c77d61b033b66ef4f9bc7f4133d83df83572d6b4fb234a3be7d"
dependencies = [ dependencies = [
"glib-sys", "glib-sys",
"libc", "libc",
@@ -346,9 +366,9 @@ dependencies = [
[[package]] [[package]]
name = "graphene-rs" name = "graphene-rs"
version = "0.15.1" version = "0.17.0"
source = "registry+https://github.com/rust-lang/crates.io-index" source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "7c54f9fbbeefdb62c99f892dfca35f83991e2cb5b46a8dc2a715e58612f85570" checksum = "372514f21c7e342e0206a916d6bd522b15337578cfa68855518a3b4960ba8254"
dependencies = [ dependencies = [
"glib", "glib",
"graphene-sys", "graphene-sys",
@@ -357,9 +377,9 @@ dependencies = [
[[package]] [[package]]
name = "graphene-sys" name = "graphene-sys"
version = "0.15.10" version = "0.17.0"
source = "registry+https://github.com/rust-lang/crates.io-index" source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "fa691fc7337ba1df599afb55c3bcb85c04f1b3f17362570e9bb0ff0d1bc3028a" checksum = "cf80a4849a8d9565410a8fec6fc3678e9c617f4ac7be182ca55ab75016e07af9"
dependencies = [ dependencies = [
"glib-sys", "glib-sys",
"libc", "libc",
@@ -369,9 +389,9 @@ dependencies = [
[[package]] [[package]]
name = "gsk4" name = "gsk4"
version = "0.4.8" version = "0.6.0"
source = "registry+https://github.com/rust-lang/crates.io-index" source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "05e9020d333280b3aa38d496495bfa9b50712eebf1ad63f0ec5bcddb5eb61be4" checksum = "432f981e4ea9f0739a5731d8a649acb794a3a729d2254e559ce7d613b17caf95"
dependencies = [ dependencies = [
"bitflags", "bitflags",
"cairo-rs", "cairo-rs",
@@ -385,9 +405,9 @@ dependencies = [
[[package]] [[package]]
name = "gsk4-sys" name = "gsk4-sys"
version = "0.4.8" version = "0.6.0"
source = "registry+https://github.com/rust-lang/crates.io-index" source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "7add39ccf60078508c838643a2dcc91f045c46ed63b5ea6ab701b2e25bda3fea" checksum = "096cb59175b0915ebf69c05a45263c0c989bd8537b8f2169912d0de644ba6a76"
dependencies = [ dependencies = [
"cairo-sys-rs", "cairo-sys-rs",
"gdk4-sys", "gdk4-sys",
@@ -401,9 +421,9 @@ dependencies = [
[[package]] [[package]]
name = "gtk4" name = "gtk4"
version = "0.4.9" version = "0.6.0"
source = "registry+https://github.com/rust-lang/crates.io-index" source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "4e8ae5aef2793bc3551b5e5e3fa062a5de54bb1eccf10dfa4effe9e4384fbbbc" checksum = "f61aa16bbd4554552645227d4249b58fd730b27985a7e0283fd0a2d479e954a8"
dependencies = [ dependencies = [
"bitflags", "bitflags",
"cairo-rs", "cairo-rs",
@@ -424,24 +444,23 @@ dependencies = [
[[package]] [[package]]
name = "gtk4-macros" name = "gtk4-macros"
version = "0.4.9" version = "0.6.0"
source = "registry+https://github.com/rust-lang/crates.io-index" source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "d9a4a8077b3a392dd7d637924529e1213d2e0c8e4d531177bc3355e86c257a54" checksum = "db4676c4f90d8b010e88cb4558f61f47d76d6f6b8e6f6b89e62640f443907f61"
dependencies = [ dependencies = [
"anyhow", "anyhow",
"proc-macro-crate", "proc-macro-crate",
"proc-macro-error", "proc-macro-error",
"proc-macro2", "proc-macro2",
"quick-xml",
"quote", "quote",
"syn", "syn",
] ]
[[package]] [[package]]
name = "gtk4-sys" name = "gtk4-sys"
version = "0.4.8" version = "0.6.0"
source = "registry+https://github.com/rust-lang/crates.io-index" source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "5bc8006eea634b7c72da3ff79e24606e45f21b3b832a3c5a1f543f5f97eb0f63" checksum = "e13cf3bc9559f71963c957eb639060b643e1276ae47b892ef6091d5bc15c3e1b"
dependencies = [ dependencies = [
"cairo-sys-rs", "cairo-sys-rs",
"gdk-pixbuf-sys", "gdk-pixbuf-sys",
@@ -614,11 +633,12 @@ checksum = "6f61fba1741ea2b3d6a1e3178721804bb716a68a6aeba1149b5d52e3d464ea66"
[[package]] [[package]]
name = "pango" name = "pango"
version = "0.15.10" version = "0.17.0"
source = "registry+https://github.com/rust-lang/crates.io-index" source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "22e4045548659aee5313bde6c582b0d83a627b7904dd20dc2d9ef0895d414e4f" checksum = "243c048be90312220fb3bd578176eed8290568274a93c95040289d39349384bc"
dependencies = [ dependencies = [
"bitflags", "bitflags",
"gio",
"glib", "glib",
"libc", "libc",
"once_cell", "once_cell",
@@ -627,9 +647,9 @@ dependencies = [
[[package]] [[package]]
name = "pango-sys" name = "pango-sys"
version = "0.15.10" version = "0.17.0"
source = "registry+https://github.com/rust-lang/crates.io-index" source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "d2a00081cde4661982ed91d80ef437c20eacaf6aa1a5962c0279ae194662c3aa" checksum = "4293d0f0b5525eb5c24734d30b0ed02cd02aa734f216883f376b54de49625de8"
dependencies = [ dependencies = [
"glib-sys", "glib-sys",
"gobject-sys", "gobject-sys",
@@ -743,15 +763,6 @@ dependencies = [
"unicode-ident", "unicode-ident",
] ]
[[package]]
name = "quick-xml"
version = "0.22.0"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "8533f14c8382aaad0d592c812ac3b826162128b65662331e1127b45c3d18536b"
dependencies = [
"memchr",
]
[[package]] [[package]]
name = "quote" name = "quote"
version = "1.0.23" version = "1.0.23"

View File

@@ -15,8 +15,8 @@ categories = ["gui", "multimedia"]
[dependencies] [dependencies]
pipewire = "0.6" pipewire = "0.6"
gtk = { version = "0.4.1", package = "gtk4" } gtk = { version = "0.6", package = "gtk4" }
glib = { version = "0.15.1", features = ["log"] } glib = { version = "0.17", features = ["log"] }
log = "0.4.11" log = "0.4.11"

View File

@@ -52,7 +52,8 @@ mod imp {
impl ObjectImpl for Application {} impl ObjectImpl for Application {}
impl ApplicationImpl for Application { impl ApplicationImpl for Application {
fn activate(&self, app: &Self::Type) { fn activate(&self) {
let app = &*self.obj();
let scrollwindow = gtk::ScrolledWindow::builder() let scrollwindow = gtk::ScrolledWindow::builder()
.child(&self.graphview) .child(&self.graphview)
.build(); .build();
@@ -85,12 +86,12 @@ mod imp {
window.show(); window.show();
} }
fn startup(&self, app: &Self::Type) { fn startup(&self) {
self.parent_startup(app); self.parent_startup();
// Load CSS from the STYLE variable. // Load CSS from the STYLE variable.
let provider = gtk::CssProvider::new(); let provider = gtk::CssProvider::new();
provider.load_from_data(STYLE.as_bytes()); provider.load_from_data(STYLE);
gtk::StyleContext::add_provider_for_display( gtk::StyleContext::add_provider_for_display(
&gtk::gdk::Display::default().expect("Error initializing gtk css provider."), &gtk::gdk::Display::default().expect("Error initializing gtk css provider."),
&provider, &provider,
@@ -114,10 +115,11 @@ impl Application {
gtk_receiver: Receiver<PipewireMessage>, gtk_receiver: Receiver<PipewireMessage>,
pw_sender: Sender<GtkMessage>, pw_sender: Sender<GtkMessage>,
) -> Self { ) -> Self {
let app: Application = glib::Object::new(&[("application-id", &"org.pipewire.Helvum")]) let app: Application = glib::Object::builder()
.expect("Failed to create new Application"); .property("application-id", &"org.pipewire.Helvum")
.build();
let imp = imp::Application::from_instance(&app); let imp = app.imp();
imp.pw_sender imp.pw_sender
.set(RefCell::new(pw_sender)) .set(RefCell::new(pw_sender))
// Discard the returned sender, as it does not implement `Debug`. // Discard the returned sender, as it does not implement `Debug`.
@@ -159,11 +161,9 @@ impl Application {
fn add_node(&self, id: u32, name: &str, node_type: Option<NodeType>) { fn add_node(&self, id: u32, name: &str, node_type: Option<NodeType>) {
info!("Adding node to graph: id {}", id); info!("Adding node to graph: id {}", id);
imp::Application::from_instance(self).graphview.add_node( self.imp()
id, .graphview
view::Node::new(name, id), .add_node(id, view::Node::new(name, id), node_type);
node_type,
);
} }
/// Add a new port to the view. /// Add a new port to the view.
@@ -177,8 +177,6 @@ impl Application {
) { ) {
info!("Adding port to graph: id {}", id); info!("Adding port to graph: id {}", id);
let imp = imp::Application::from_instance(self);
let port = view::Port::new(id, name, direction, media_type); let port = view::Port::new(id, name, direction, media_type);
// Create or delete a link if the widget emits the "port-toggled" signal. // Create or delete a link if the widget emits the "port-toggled" signal.
@@ -196,7 +194,7 @@ impl Application {
}), }),
); );
imp.graphview.add_port(node_id, id, port); self.imp().graphview.add_port(node_id, id, port);
} }
/// Add a new link to the view. /// Add a new link to the view.
@@ -214,7 +212,7 @@ impl Application {
// FIXME: Links should be colored depending on the data they carry (video, audio, midi) like ports are. // FIXME: Links should be colored depending on the data they carry (video, audio, midi) like ports are.
// Update graph to contain the new link. // Update graph to contain the new link.
imp::Application::from_instance(self).graphview.add_link( self.imp().graphview.add_link(
id, id,
PipewireLink { PipewireLink {
node_from, node_from,
@@ -233,15 +231,17 @@ impl Application {
if active { "active" } else { "inactive" } if active { "active" } else { "inactive" }
); );
imp::Application::from_instance(self) self.imp().graphview.set_link_state(id, active);
.graphview
.set_link_state(id, active);
} }
// Toggle a link between the two specified ports on the remote pipewire server. // Toggle a link between the two specified ports on the remote pipewire server.
fn toggle_link(&self, port_from: u32, port_to: u32) { fn toggle_link(&self, port_from: u32, port_to: u32) {
let imp = imp::Application::from_instance(self); let sender = self
let sender = imp.pw_sender.get().expect("pw_sender not set").borrow_mut(); .imp()
.pw_sender
.get()
.expect("pw_sender not set")
.borrow_mut();
sender sender
.send(GtkMessage::ToggleLink { port_from, port_to }) .send(GtkMessage::ToggleLink { port_from, port_to })
.expect("Failed to send message"); .expect("Failed to send message");
@@ -251,8 +251,7 @@ impl Application {
fn remove_node(&self, id: u32) { fn remove_node(&self, id: u32) {
info!("Removing node from graph: id {}", id); info!("Removing node from graph: id {}", id);
let imp = imp::Application::from_instance(self); self.imp().graphview.remove_node(id);
imp.graphview.remove_node(id);
} }
/// Remove the port with the id `id` from the node with the id `node_id` /// Remove the port with the id `id` from the node with the id `node_id`
@@ -260,15 +259,13 @@ impl Application {
fn remove_port(&self, id: u32, node_id: u32) { fn remove_port(&self, id: u32, node_id: u32) {
info!("Removing port from graph: id {}, node_id: {}", id, node_id); info!("Removing port from graph: id {}, node_id: {}", id, node_id);
let imp = imp::Application::from_instance(self); self.imp().graphview.remove_port(id, node_id);
imp.graphview.remove_port(id, node_id);
} }
/// Remove the link with the specified id from the view. /// Remove the link with the specified id from the view.
fn remove_link(&self, id: u32) { fn remove_link(&self, id: u32) {
info!("Removing link from graph: id {}", id); info!("Removing link from graph: id {}", id);
let imp = imp::Application::from_instance(self); self.imp().graphview.remove_link(id);
imp.graphview.remove_link(id);
} }
} }

View File

@@ -83,17 +83,17 @@ mod imp {
} }
impl ObjectImpl for GraphView { impl ObjectImpl for GraphView {
fn constructed(&self, obj: &Self::Type) { fn constructed(&self) {
self.parent_constructed(obj); self.parent_constructed();
obj.set_overflow(gtk::Overflow::Hidden); self.obj().set_overflow(gtk::Overflow::Hidden);
self.setup_node_dragging(); self.setup_node_dragging();
self.setup_scroll_zooming(); self.setup_scroll_zooming();
self.setup_zoom_gesture(); self.setup_zoom_gesture();
} }
fn dispose(&self, _obj: &Self::Type) { fn dispose(&self) {
self.nodes self.nodes
.borrow() .borrow()
.values() .values()
@@ -107,22 +107,19 @@ mod imp {
glib::ParamSpecOverride::for_interface::<gtk::Scrollable>("vadjustment"), glib::ParamSpecOverride::for_interface::<gtk::Scrollable>("vadjustment"),
glib::ParamSpecOverride::for_interface::<gtk::Scrollable>("hscroll-policy"), glib::ParamSpecOverride::for_interface::<gtk::Scrollable>("hscroll-policy"),
glib::ParamSpecOverride::for_interface::<gtk::Scrollable>("vscroll-policy"), glib::ParamSpecOverride::for_interface::<gtk::Scrollable>("vscroll-policy"),
glib::ParamSpecDouble::new( glib::ParamSpecDouble::builder("zoom-factor")
"zoom-factor", .minimum(0.3)
"zoom-factor", .maximum(4.0)
"zoom-factor", .default_value(1.0)
0.3, .flags(glib::ParamFlags::CONSTRUCT | glib::ParamFlags::READWRITE)
4.0, .build(),
1.0,
glib::ParamFlags::CONSTRUCT | glib::ParamFlags::READWRITE,
),
] ]
}); });
PROPERTIES.as_ref() PROPERTIES.as_ref()
} }
fn property(&self, _obj: &Self::Type, _id: usize, pspec: &glib::ParamSpec) -> glib::Value { fn property(&self, _id: usize, pspec: &glib::ParamSpec) -> glib::Value {
match pspec.name() { match pspec.name() {
"hadjustment" => self.hadjustment.borrow().to_value(), "hadjustment" => self.hadjustment.borrow().to_value(),
"vadjustment" => self.vadjustment.borrow().to_value(), "vadjustment" => self.vadjustment.borrow().to_value(),
@@ -132,19 +129,15 @@ mod imp {
} }
} }
fn set_property( fn set_property(&self, _id: usize, value: &glib::Value, pspec: &glib::ParamSpec) {
&self, let obj = self.obj();
obj: &Self::Type,
_id: usize,
value: &glib::Value,
pspec: &glib::ParamSpec,
) {
match pspec.name() { match pspec.name() {
"hadjustment" => { "hadjustment" => {
self.set_adjustment(obj, value.get().ok(), gtk::Orientation::Horizontal) self.set_adjustment(&obj, value.get().ok(), gtk::Orientation::Horizontal)
} }
"vadjustment" => { "vadjustment" => {
self.set_adjustment(obj, value.get().ok(), gtk::Orientation::Vertical) self.set_adjustment(&obj, value.get().ok(), gtk::Orientation::Vertical)
} }
"hscroll-policy" | "vscroll-policy" => {} "hscroll-policy" | "vscroll-policy" => {}
"zoom-factor" => { "zoom-factor" => {
@@ -157,7 +150,9 @@ mod imp {
} }
impl WidgetImpl for GraphView { impl WidgetImpl for GraphView {
fn size_allocate(&self, widget: &Self::Type, _width: i32, _height: i32, baseline: i32) { fn size_allocate(&self, _width: i32, _height: i32, baseline: i32) {
let widget = &*self.obj();
let zoom_factor = self.zoom_factor.get(); let zoom_factor = self.zoom_factor.get();
for (node, point) in self.nodes.borrow().values() { for (node, point) in self.nodes.borrow().values() {
@@ -165,14 +160,13 @@ mod imp {
let transform = self let transform = self
.canvas_space_to_screen_space_transform() .canvas_space_to_screen_space_transform()
.translate(point) .translate(point);
.unwrap();
node.allocate( node.allocate(
(natural_size.width() as f64 / zoom_factor).ceil() as i32, (natural_size.width() as f64 / zoom_factor).ceil() as i32,
(natural_size.height() as f64 / zoom_factor).ceil() as i32, (natural_size.height() as f64 / zoom_factor).ceil() as i32,
baseline, baseline,
Some(&transform), Some(transform),
); );
} }
@@ -184,7 +178,8 @@ mod imp {
} }
} }
fn snapshot(&self, widget: &Self::Type, snapshot: &gtk::Snapshot) { fn snapshot(&self, snapshot: &gtk::Snapshot) {
let widget = &*self.obj();
let alloc = widget.allocation(); let alloc = widget.allocation();
self.snapshot_background(widget, snapshot); self.snapshot_background(widget, snapshot);
@@ -195,7 +190,7 @@ mod imp {
.values() .values()
// Cull nodes from rendering when they are outside the visible canvas area // Cull nodes from rendering when they are outside the visible canvas area
.filter(|(node, _)| alloc.intersect(&node.allocation()).is_some()) .filter(|(node, _)| alloc.intersect(&node.allocation()).is_some())
.for_each(|(node, _)| self.instance().snapshot_child(node, snapshot)); .for_each(|(node, _)| widget.snapshot_child(node, snapshot));
self.snapshot_links(widget, snapshot); self.snapshot_links(widget, snapshot);
} }
@@ -217,9 +212,7 @@ mod imp {
gsk::Transform::new() gsk::Transform::new()
.translate(&Point::new(-hadj as f32, -vadj as f32)) .translate(&Point::new(-hadj as f32, -vadj as f32))
.unwrap()
.scale(zoom_factor as f32, zoom_factor as f32) .scale(zoom_factor as f32, zoom_factor as f32)
.unwrap()
} }
/// Returns a [`gsk::Transform`] matrix that can translate from screen space to canvas space. /// Returns a [`gsk::Transform`] matrix that can translate from screen space to canvas space.
@@ -232,7 +225,6 @@ mod imp {
} }
fn setup_node_dragging(&self) { fn setup_node_dragging(&self) {
let obj = self.instance();
let drag_controller = gtk::GestureDrag::new(); let drag_controller = gtk::GestureDrag::new();
drag_controller.connect_drag_begin(|drag_controller, x, y| { drag_controller.connect_drag_begin(|drag_controller, x, y| {
@@ -297,12 +289,10 @@ mod imp {
), ),
); );
}); });
obj.add_controller(&drag_controller); self.obj().add_controller(drag_controller);
} }
fn setup_scroll_zooming(&self) { fn setup_scroll_zooming(&self) {
let obj = self.instance();
// We're only interested in the vertical axis, but for devices like touchpads, // We're only interested in the vertical axis, but for devices like touchpads,
// not capturing a small accidental horizontal move may cause the scroll to be disrupted if a widget // not capturing a small accidental horizontal move may cause the scroll to be disrupted if a widget
// higher up captures it instead. // higher up captures it instead.
@@ -327,7 +317,7 @@ mod imp {
gtk::Inhibit(false) gtk::Inhibit(false)
} }
}); });
obj.add_controller(&scroll_controller); self.obj().add_controller(scroll_controller);
} }
fn setup_zoom_gesture(&self) { fn setup_zoom_gesture(&self) {
@@ -355,7 +345,7 @@ mod imp {
widget.set_zoom_factor(initial_zoom * delta, gesture.bounding_box_center()); widget.set_zoom_factor(initial_zoom * delta, gesture.bounding_box_center());
}); });
self.instance().add_controller(&zoom_gesture); self.obj().add_controller(zoom_gesture);
} }
fn snapshot_background(&self, widget: &super::GraphView, snapshot: &gtk::Snapshot) { fn snapshot_background(&self, widget: &super::GraphView, snapshot: &gtk::Snapshot) {
@@ -491,6 +481,7 @@ mod imp {
/// # Returns /// # Returns
/// `Some((from_x, from_y, to_x, to_y))` if all objects the links refers to exist as widgets. /// `Some((from_x, from_y, to_x, to_y))` if all objects the links refers to exist as widgets.
fn get_link_coordinates(&self, link: &crate::PipewireLink) -> Option<(f64, f64, f64, f64)> { fn get_link_coordinates(&self, link: &crate::PipewireLink) -> Option<(f64, f64, f64, f64)> {
let widget = &*self.obj();
let nodes = self.nodes.borrow(); let nodes = self.nodes.borrow();
let output_port = &nodes.get(&link.node_from)?.0.get_port(link.port_from)?; let output_port = &nodes.get(&link.node_from)?.0.get_port(link.port_from)?;
@@ -499,7 +490,7 @@ mod imp {
(output_port.allocated_width() - output_port.width()) as f64 / 2.0; (output_port.allocated_width() - output_port.width()) as f64 / 2.0;
let (from_x, from_y) = output_port.translate_coordinates( let (from_x, from_y) = output_port.translate_coordinates(
&self.instance(), widget,
output_port.width() as f64 + output_port_padding, output_port.width() as f64 + output_port_padding,
(output_port.height() / 2) as f64, (output_port.height() / 2) as f64,
)?; )?;
@@ -510,7 +501,7 @@ mod imp {
(input_port.allocated_width() - input_port.width()) as f64 / 2.0; (input_port.allocated_width() - input_port.width()) as f64 / 2.0;
let (to_x, to_y) = input_port.translate_coordinates( let (to_x, to_y) = input_port.translate_coordinates(
&self.instance(), widget,
-input_port_padding, -input_port_padding,
(input_port.height() / 2) as f64, (input_port.height() / 2) as f64,
)?; )?;
@@ -573,7 +564,7 @@ impl GraphView {
pub const ZOOM_MAX: f64 = 4.0; pub const ZOOM_MAX: f64 = 4.0;
pub fn new() -> Self { pub fn new() -> Self {
glib::Object::new(&[]).expect("Failed to create GraphView") glib::Object::new()
} }
pub fn zoom_factor(&self) -> f64 { pub fn zoom_factor(&self) -> f64 {
@@ -619,7 +610,7 @@ impl GraphView {
} }
pub fn add_node(&self, id: u32, node: Node, node_type: Option<NodeType>) { pub fn add_node(&self, id: u32, node: Node, node_type: Option<NodeType>) {
let private = imp::GraphView::from_instance(self); let imp = self.imp();
node.set_parent(self); node.set_parent(self);
// Place widgets in colums of 3, growing down // Place widgets in colums of 3, growing down
@@ -632,7 +623,7 @@ impl GraphView {
420.0 420.0
}; };
let y = private let y = imp
.nodes .nodes
.borrow() .borrow()
.values() .values()
@@ -651,15 +642,11 @@ impl GraphView {
}) })
.map_or(20_f32, |(_x, y)| y + 100.0); .map_or(20_f32, |(_x, y)| y + 100.0);
private imp.nodes.borrow_mut().insert(id, (node, Point::new(x, y)));
.nodes
.borrow_mut()
.insert(id, (node, Point::new(x, y)));
} }
pub fn remove_node(&self, id: u32) { pub fn remove_node(&self, id: u32) {
let private = imp::GraphView::from_instance(self); let mut nodes = self.imp().nodes.borrow_mut();
let mut nodes = private.nodes.borrow_mut();
if let Some((node, _)) = nodes.remove(&id) { if let Some((node, _)) = nodes.remove(&id) {
node.unparent(); node.unparent();
} else { } else {
@@ -668,9 +655,7 @@ impl GraphView {
} }
pub fn add_port(&self, node_id: u32, port_id: u32, port: crate::view::port::Port) { pub fn add_port(&self, node_id: u32, port_id: u32, port: crate::view::port::Port) {
let private = imp::GraphView::from_instance(self); if let Some((node, _)) = self.imp().nodes.borrow_mut().get_mut(&node_id) {
if let Some((node, _)) = private.nodes.borrow_mut().get_mut(&node_id) {
node.add_port(port_id, port); node.add_port(port_id, port);
} else { } else {
error!( error!(
@@ -681,22 +666,22 @@ impl GraphView {
} }
pub fn remove_port(&self, id: u32, node_id: u32) { pub fn remove_port(&self, id: u32, node_id: u32) {
let private = imp::GraphView::from_instance(self); let nodes = self.imp().nodes.borrow();
let nodes = private.nodes.borrow();
if let Some((node, _)) = nodes.get(&node_id) { if let Some((node, _)) = nodes.get(&node_id) {
node.remove_port(id); node.remove_port(id);
} }
} }
pub fn add_link(&self, link_id: u32, link: crate::PipewireLink, active: bool) { pub fn add_link(&self, link_id: u32, link: crate::PipewireLink, active: bool) {
let private = imp::GraphView::from_instance(self); self.imp()
private.links.borrow_mut().insert(link_id, (link, active)); .links
.borrow_mut()
.insert(link_id, (link, active));
self.queue_draw(); self.queue_draw();
} }
pub fn set_link_state(&self, link_id: u32, active: bool) { pub fn set_link_state(&self, link_id: u32, active: bool) {
let private = imp::GraphView::from_instance(self); if let Some((_, state)) = self.imp().links.borrow_mut().get_mut(&link_id) {
if let Some((_, state)) = private.links.borrow_mut().get_mut(&link_id) {
*state = active; *state = active;
self.queue_draw(); self.queue_draw();
} else { } else {
@@ -705,8 +690,7 @@ impl GraphView {
} }
pub fn remove_link(&self, id: u32) { pub fn remove_link(&self, id: u32) {
let private = imp::GraphView::from_instance(self); let mut links = self.imp().links.borrow_mut();
let mut links = private.links.borrow_mut();
links.remove(&id); links.remove(&id);
self.queue_draw(); self.queue_draw();

View File

@@ -67,31 +67,25 @@ mod imp {
} }
impl ObjectImpl for Node { impl ObjectImpl for Node {
fn constructed(&self, obj: &Self::Type) { fn constructed(&self) {
self.parent_constructed(obj); self.parent_constructed();
self.grid.set_parent(obj); self.grid.set_parent(&*self.obj());
} }
fn properties() -> &'static [glib::ParamSpec] { fn properties() -> &'static [glib::ParamSpec] {
static PROPERTIES: Lazy<Vec<glib::ParamSpec>> = Lazy::new(|| { static PROPERTIES: Lazy<Vec<glib::ParamSpec>> = Lazy::new(|| {
vec![ vec![
glib::ParamSpecUInt::new( glib::ParamSpecUInt::builder("pipewire-id")
"pipewire-id", .flags(ParamFlags::READWRITE | ParamFlags::CONSTRUCT_ONLY)
"pipewire-id", .build(),
"pipewire-id", glib::ParamSpecString::builder("name").build(),
u32::MIN,
u32::MAX,
0,
ParamFlags::READWRITE | ParamFlags::CONSTRUCT_ONLY,
),
glib::ParamSpecString::new("name", "name", "name", None, ParamFlags::READWRITE),
] ]
}); });
PROPERTIES.as_ref() PROPERTIES.as_ref()
} }
fn property(&self, _obj: &Self::Type, _id: usize, pspec: &glib::ParamSpec) -> glib::Value { fn property(&self, _id: usize, pspec: &glib::ParamSpec) -> glib::Value {
match pspec.name() { match pspec.name() {
"pipewire-id" => self.pipewire_id.get().to_value(), "pipewire-id" => self.pipewire_id.get().to_value(),
"name" => self.label.text().to_value(), "name" => self.label.text().to_value(),
@@ -99,13 +93,7 @@ mod imp {
} }
} }
fn set_property( fn set_property(&self, _id: usize, value: &glib::Value, pspec: &glib::ParamSpec) {
&self,
_obj: &Self::Type,
_id: usize,
value: &glib::Value,
pspec: &glib::ParamSpec,
) {
match pspec.name() { match pspec.name() {
"name" => self.label.set_text(value.get().unwrap()), "name" => self.label.set_text(value.get().unwrap()),
"pipewire-id" => self.pipewire_id.set(value.get().unwrap()), "pipewire-id" => self.pipewire_id.set(value.get().unwrap()),
@@ -113,7 +101,7 @@ mod imp {
} }
} }
fn dispose(&self, _obj: &Self::Type) { fn dispose(&self) {
self.grid.unparent(); self.grid.unparent();
} }
} }
@@ -128,8 +116,10 @@ glib::wrapper! {
impl Node { impl Node {
pub fn new(name: &str, pipewire_id: u32) -> Self { pub fn new(name: &str, pipewire_id: u32) -> Self {
glib::Object::new(&[("name", &name), ("pipewire-id", &pipewire_id)]) glib::Object::builder()
.expect("Failed to create Node") .property("name", &name)
.property("pipewire-id", &pipewire_id)
.build()
} }
pub fn pipewire_id(&self) -> u32 { pub fn pipewire_id(&self) -> u32 {
@@ -147,37 +137,32 @@ impl Node {
} }
pub fn add_port(&mut self, id: u32, port: super::port::Port) { pub fn add_port(&mut self, id: u32, port: super::port::Port) {
let private = imp::Node::from_instance(self); let imp = self.imp();
match port.direction() { match port.direction() {
Direction::Input => { Direction::Input => {
private imp.grid.attach(&port, 0, imp.num_ports_in.get() + 1, 1, 1);
.grid imp.num_ports_in.set(imp.num_ports_in.get() + 1);
.attach(&port, 0, private.num_ports_in.get() + 1, 1, 1);
private.num_ports_in.set(private.num_ports_in.get() + 1);
} }
Direction::Output => { Direction::Output => {
private imp.grid.attach(&port, 1, imp.num_ports_out.get() + 1, 1, 1);
.grid imp.num_ports_out.set(imp.num_ports_out.get() + 1);
.attach(&port, 1, private.num_ports_out.get() + 1, 1, 1);
private.num_ports_out.set(private.num_ports_out.get() + 1);
} }
} }
private.ports.borrow_mut().insert(id, port); imp.ports.borrow_mut().insert(id, port);
} }
pub fn get_port(&self, id: u32) -> Option<super::port::Port> { pub fn get_port(&self, id: u32) -> Option<super::port::Port> {
let private = imp::Node::from_instance(self); self.imp().ports.borrow_mut().get(&id).cloned()
private.ports.borrow_mut().get(&id).cloned()
} }
pub fn remove_port(&self, id: u32) { pub fn remove_port(&self, id: u32) {
let private = imp::Node::from_instance(self); let imp = self.imp();
if let Some(port) = private.ports.borrow_mut().remove(&id) { if let Some(port) = imp.ports.borrow_mut().remove(&id) {
match port.direction() { match port.direction() {
Direction::Input => private.num_ports_in.set(private.num_ports_in.get() - 1), Direction::Input => imp.num_ports_in.set(imp.num_ports_in.get() - 1),
Direction::Output => private.num_ports_in.set(private.num_ports_out.get() - 1), Direction::Output => imp.num_ports_in.set(imp.num_ports_out.get() - 1),
} }
port.unparent(); port.unparent();

View File

@@ -67,35 +67,29 @@ mod imp {
} }
impl ObjectImpl for Port { impl ObjectImpl for Port {
fn constructed(&self, obj: &Self::Type) { fn constructed(&self) {
self.parent_constructed(obj); self.parent_constructed();
self.label.set_parent(obj); self.label.set_parent(&*self.obj());
} }
fn dispose(&self, _obj: &Self::Type) { fn dispose(&self) {
self.label.unparent() self.label.unparent()
} }
fn properties() -> &'static [glib::ParamSpec] { fn properties() -> &'static [glib::ParamSpec] {
static PROPERTIES: Lazy<Vec<glib::ParamSpec>> = Lazy::new(|| { static PROPERTIES: Lazy<Vec<glib::ParamSpec>> = Lazy::new(|| {
vec![ vec![
glib::ParamSpecUInt::new( glib::ParamSpecUInt::builder("pipewire-id")
"pipewire-id", .flags(ParamFlags::READWRITE | ParamFlags::CONSTRUCT_ONLY)
"pipewire-id", .build(),
"pipewire-id", glib::ParamSpecString::builder("name").build(),
u32::MIN,
u32::MAX,
0,
ParamFlags::READWRITE | ParamFlags::CONSTRUCT_ONLY,
),
glib::ParamSpecString::new("name", "name", "name", None, ParamFlags::READWRITE),
] ]
}); });
PROPERTIES.as_ref() PROPERTIES.as_ref()
} }
fn property(&self, _obj: &Self::Type, _id: usize, pspec: &glib::ParamSpec) -> glib::Value { fn property(&self, _id: usize, pspec: &glib::ParamSpec) -> glib::Value {
match pspec.name() { match pspec.name() {
"pipewire-id" => self.pipewire_id.get().unwrap().to_value(), "pipewire-id" => self.pipewire_id.get().unwrap().to_value(),
"name" => self.label.text().to_value(), "name" => self.label.text().to_value(),
@@ -103,13 +97,7 @@ mod imp {
} }
} }
fn set_property( fn set_property(&self, _id: usize, value: &glib::Value, pspec: &glib::ParamSpec) {
&self,
_obj: &Self::Type,
_id: usize,
value: &glib::Value,
pspec: &glib::ParamSpec,
) {
match pspec.name() { match pspec.name() {
"name" => self.label.set_text(value.get().unwrap()), "name" => self.label.set_text(value.get().unwrap()),
"pipewire-id" => self.pipewire_id.set(value.get().unwrap()).unwrap(), "pipewire-id" => self.pipewire_id.set(value.get().unwrap()).unwrap(),
@@ -119,13 +107,9 @@ mod imp {
fn signals() -> &'static [Signal] { fn signals() -> &'static [Signal] {
static SIGNALS: Lazy<Vec<Signal>> = Lazy::new(|| { static SIGNALS: Lazy<Vec<Signal>> = Lazy::new(|| {
vec![Signal::builder( vec![Signal::builder("port-toggled")
"port-toggled",
// Provide id of output port and input port to signal handler. // Provide id of output port and input port to signal handler.
&[<u32>::static_type().into(), <u32>::static_type().into()], .param_types([<u32>::static_type(), <u32>::static_type()])
// signal handler sends back nothing.
<()>::static_type().into(),
)
.build()] .build()]
}); });
@@ -143,13 +127,14 @@ glib::wrapper! {
impl Port { impl Port {
pub fn new(id: u32, name: &str, direction: Direction, media_type: Option<MediaType>) -> Self { pub fn new(id: u32, name: &str, direction: Direction, media_type: Option<MediaType>) -> Self {
// Create the widget and initialize needed fields // Create the widget and initialize needed fields
let res: Self = glib::Object::new(&[("pipewire-id", &id), ("name", &name)]) let res: Self = glib::Object::builder()
.expect("Failed to create Port"); .property("pipewire-id", &id)
.property("name", &name)
.build();
let private = imp::Port::from_instance(&res); let imp = res.imp();
private imp.direction
.direction
.set(direction) .set(direction)
.expect("Port direction already set"); .expect("Port direction already set");
@@ -172,7 +157,7 @@ impl Port {
trace!("Drag from port {} was cancelled", id); trace!("Drag from port {} was cancelled", id);
false false
}); });
res.add_controller(&drag_src); res.add_controller(drag_src);
// The drop target will accept either a `ForwardLink` or `ReversedLink` depending in its own direction, // The drop target will accept either a `ForwardLink` or `ReversedLink` depending in its own direction,
// and use it to emit its `port-toggled` signal. // and use it to emit its `port-toggled` signal.
@@ -217,7 +202,7 @@ impl Port {
); );
} }
} }
res.add_controller(&drop_target); res.add_controller(drop_target);
// Display a grab cursor when the mouse is over the port so the user knows it can be dragged to another port. // Display a grab cursor when the mouse is over the port so the user knows it can be dragged to another port.
res.set_cursor(gtk::gdk::Cursor::from_name("grab", None).as_ref()); res.set_cursor(gtk::gdk::Cursor::from_name("grab", None).as_ref());
@@ -248,7 +233,9 @@ impl Port {
} }
pub fn direction(&self) -> &Direction { pub fn direction(&self) -> &Direction {
let private = imp::Port::from_instance(self); self.imp()
private.direction.get().expect("Port direction is not set") .direction
.get()
.expect("Port direction is not set")
} }
} }

View File

@@ -61,87 +61,78 @@ mod imp {
} }
impl ObjectImpl for ZoomEntry { impl ObjectImpl for ZoomEntry {
fn constructed(&self, obj: &Self::Type) { fn constructed(&self) {
self.parent_constructed(obj); self.parent_constructed();
self.zoom_out_button self.zoom_out_button
.connect_clicked(clone!(@weak obj => move |_| { .connect_clicked(clone!(@weak self as imp => move |_| {
let graphview = obj.imp().graphview.borrow(); let graphview = imp.graphview.borrow();
if let Some(ref graphview) = *graphview { if let Some(ref graphview) = *graphview {
graphview.set_zoom_factor(graphview.zoom_factor() - 0.1, None); graphview.set_zoom_factor(graphview.zoom_factor() - 0.1, None);
} }
})); }));
self.zoom_in_button self.zoom_in_button
.connect_clicked(clone!(@weak obj => move |_| { .connect_clicked(clone!(@weak self as imp => move |_| {
let graphview = obj.imp().graphview.borrow(); let graphview = imp.graphview.borrow();
if let Some(ref graphview) = *graphview { if let Some(ref graphview) = *graphview {
graphview.set_zoom_factor(graphview.zoom_factor() + 0.1, None); graphview.set_zoom_factor(graphview.zoom_factor() + 0.1, None);
} }
})); }));
self.entry self.entry
.connect_activate(clone!(@weak obj => move |entry| { .connect_activate(clone!(@weak self as imp => move |entry| {
if let Ok(zoom_factor) = entry.text().trim_matches('%').parse::<f64>() { if let Ok(zoom_factor) = entry.text().trim_matches('%').parse::<f64>() {
let graphview = obj.imp().graphview.borrow(); let graphview = imp.graphview.borrow();
if let Some(ref graphview) = *graphview { if let Some(ref graphview) = *graphview {
graphview.set_zoom_factor(zoom_factor / 100.0, None); graphview.set_zoom_factor(zoom_factor / 100.0, None);
} }
} }
})); }));
self.entry self.entry
.connect_icon_press(clone!(@weak obj => move |_, pos| { .connect_icon_press(clone!(@weak self as imp => move |_, pos| {
if pos == gtk::EntryIconPosition::Secondary { if pos == gtk::EntryIconPosition::Secondary {
obj.imp().popover.show(); imp.popover.show();
} }
})); }));
self.popover.set_parent(&self.entry.get()); self.popover.set_parent(&self.entry.get());
} }
fn dispose(&self, obj: &Self::Type) { fn dispose(&self) {
self.popover.unparent(); self.popover.unparent();
while let Some(child) = obj.first_child() { while let Some(child) = self.obj().first_child() {
child.unparent(); child.unparent();
} }
} }
fn properties() -> &'static [glib::ParamSpec] { fn properties() -> &'static [glib::ParamSpec] {
static PROPERTIES: Lazy<Vec<glib::ParamSpec>> = Lazy::new(|| { static PROPERTIES: Lazy<Vec<glib::ParamSpec>> = Lazy::new(|| {
vec![glib::ParamSpecObject::new( vec![
"zoomed-widget", glib::ParamSpecObject::builder::<view::GraphView>("zoomed-widget")
"zoomed widget", .flags(glib::ParamFlags::READWRITE | glib::ParamFlags::CONSTRUCT)
"Zoomed Widget", .build(),
view::GraphView::static_type(), ]
glib::ParamFlags::READWRITE | glib::ParamFlags::CONSTRUCT,
)]
}); });
PROPERTIES.as_ref() PROPERTIES.as_ref()
} }
fn property(&self, _obj: &Self::Type, _id: usize, pspec: &glib::ParamSpec) -> glib::Value { fn property(&self, _id: usize, pspec: &glib::ParamSpec) -> glib::Value {
match pspec.name() { match pspec.name() {
"zoomed-widget" => self.graphview.borrow().to_value(), "zoomed-widget" => self.graphview.borrow().to_value(),
_ => unimplemented!(), _ => unimplemented!(),
} }
} }
fn set_property( fn set_property(&self, _id: usize, value: &glib::Value, pspec: &glib::ParamSpec) {
&self,
obj: &Self::Type,
_id: usize,
value: &glib::Value,
pspec: &glib::ParamSpec,
) {
match pspec.name() { match pspec.name() {
"zoomed-widget" => { "zoomed-widget" => {
let widget: view::GraphView = value.get().unwrap(); let widget: view::GraphView = value.get().unwrap();
widget.connect_notify_local( widget.connect_notify_local(
Some("zoom-factor"), Some("zoom-factor"),
clone!(@weak obj => move |graphview, _| { clone!(@weak self as imp => move |graphview, _| {
let imp = obj.imp();
imp.update_zoom_factor_text(graphview.zoom_factor()); imp.update_zoom_factor_text(graphview.zoom_factor());
}), }),
); );
@@ -174,6 +165,8 @@ glib::wrapper! {
impl ZoomEntry { impl ZoomEntry {
pub fn new(zoomed_widget: &view::GraphView) -> Self { pub fn new(zoomed_widget: &view::GraphView) -> Self {
glib::Object::new(&[("zoomed-widget", zoomed_widget)]).expect("Failed to create ZoomEntry") glib::Object::builder()
.property("zoomed-widget", zoomed_widget)
.build()
} }
} }