mirror of
https://gitlab.freedesktop.org/pipewire/helvum
synced 2026-03-15 03:26:10 +08:00
graph: Move port link anchor calculation into port widget
This commit is contained in:
@@ -432,8 +432,15 @@ mod imp {
|
|||||||
|
|
||||||
for link in self.links.borrow().iter() {
|
for link in self.links.borrow().iter() {
|
||||||
// TODO: Do not draw links when they are outside the view
|
// TODO: Do not draw links when they are outside the view
|
||||||
if let Some((from_x, from_y, to_x, to_y)) = self.get_link_coordinates(link) {
|
let Some((output_anchor, input_anchor)) = self.get_link_coordinates(link) else {
|
||||||
link_cr.move_to(from_x, from_y);
|
warn!("Could not get allocation of ports of link: {:?}", link);
|
||||||
|
continue;
|
||||||
|
};
|
||||||
|
|
||||||
|
let output_x: f64 = output_anchor.x().into();
|
||||||
|
let output_y: f64 = output_anchor.y().into();
|
||||||
|
let input_x: f64 = input_anchor.x().into();
|
||||||
|
let input_y: f64 = input_anchor.y().into();
|
||||||
|
|
||||||
// Use dashed line for inactive links, full line otherwise.
|
// Use dashed line for inactive links, full line otherwise.
|
||||||
if link.active() {
|
if link.active() {
|
||||||
@@ -445,8 +452,8 @@ mod imp {
|
|||||||
// If the output port is farther right than the input port and they have
|
// If the output port is farther right than the input port and they have
|
||||||
// a similar y coordinate, apply a y offset to the control points
|
// a similar y coordinate, apply a y offset to the control points
|
||||||
// so that the curve sticks out a bit.
|
// so that the curve sticks out a bit.
|
||||||
let y_control_offset = if from_x > to_x {
|
let y_control_offset = if output_x > input_x {
|
||||||
f64::max(0.0, 25.0 - (from_y - to_y).abs())
|
f64::max(0.0, 25.0 - (output_y - input_y).abs())
|
||||||
} else {
|
} else {
|
||||||
0.0
|
0.0
|
||||||
};
|
};
|
||||||
@@ -454,55 +461,40 @@ mod imp {
|
|||||||
// Place curve control offset by half the x distance between the two points.
|
// Place curve control offset by half the x distance between the two points.
|
||||||
// This makes the curve scale well for varying distances between the two ports,
|
// This makes the curve scale well for varying distances between the two ports,
|
||||||
// especially when the output port is farther right than the input port.
|
// especially when the output port is farther right than the input port.
|
||||||
let half_x_dist = f64::abs(from_x - to_x) / 2.0;
|
let half_x_dist = f64::abs(output_x - input_x) / 2.0;
|
||||||
|
link_cr.move_to(output_x, output_y);
|
||||||
link_cr.curve_to(
|
link_cr.curve_to(
|
||||||
from_x + half_x_dist,
|
output_x + half_x_dist,
|
||||||
from_y - y_control_offset,
|
output_y - y_control_offset,
|
||||||
to_x - half_x_dist,
|
input_x - half_x_dist,
|
||||||
to_y - y_control_offset,
|
input_y - y_control_offset,
|
||||||
to_x,
|
input_x,
|
||||||
to_y,
|
input_y,
|
||||||
);
|
);
|
||||||
|
|
||||||
if let Err(e) = link_cr.stroke() {
|
if let Err(e) = link_cr.stroke() {
|
||||||
warn!("Failed to draw graphview links: {}", e);
|
warn!("Failed to draw graphview links: {}", e);
|
||||||
};
|
};
|
||||||
} else {
|
|
||||||
warn!("Could not get allocation of ports of link: {:?}", link);
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
/// Get coordinates for the drawn link to start at and to end at.
|
/// Get coordinates for the drawn link to start at and to end at.
|
||||||
///
|
///
|
||||||
/// # Returns
|
/// # Returns
|
||||||
/// `Some((from_x, from_y, to_x, to_y))` if all objects the links refers to exist as widgets.
|
/// `Some((output_anchor, input_anchor))` if all objects the links refers to exist as widgets
|
||||||
fn get_link_coordinates(&self, link: &Link) -> Option<(f64, f64, f64, f64)> {
|
/// and those widgets are contained by the graph.
|
||||||
|
///
|
||||||
|
/// The returned coordinates are in screen-space of the graph.
|
||||||
|
fn get_link_coordinates(&self, link: &Link) -> Option<(graphene::Point, graphene::Point)> {
|
||||||
let widget = &*self.obj();
|
let widget = &*self.obj();
|
||||||
|
|
||||||
let output_port = link.output_port()?;
|
let output_port = link.output_port()?;
|
||||||
|
let output_anchor = output_port.compute_point(widget, &output_port.link_anchor())?;
|
||||||
let output_port_padding =
|
|
||||||
(output_port.allocated_width() - output_port.width()) as f64 / 2.0;
|
|
||||||
|
|
||||||
let (from_x, from_y) = output_port.translate_coordinates(
|
|
||||||
widget,
|
|
||||||
output_port.width() as f64 + output_port_padding,
|
|
||||||
(output_port.height() / 2) as f64,
|
|
||||||
)?;
|
|
||||||
|
|
||||||
let input_port = link.input_port()?;
|
let input_port = link.input_port()?;
|
||||||
|
let input_anchor = input_port.compute_point(widget, &input_port.link_anchor())?;
|
||||||
|
|
||||||
let input_port_padding =
|
Some((output_anchor, input_anchor))
|
||||||
(input_port.allocated_width() - input_port.width()) as f64 / 2.0;
|
|
||||||
|
|
||||||
let (to_x, to_y) = input_port.translate_coordinates(
|
|
||||||
widget,
|
|
||||||
-input_port_padding,
|
|
||||||
(input_port.height() / 2) as f64,
|
|
||||||
)?;
|
|
||||||
|
|
||||||
Some((from_x, from_y, to_x, to_y))
|
|
||||||
}
|
}
|
||||||
|
|
||||||
fn set_adjustment(
|
fn set_adjustment(
|
||||||
|
|||||||
@@ -17,6 +17,7 @@
|
|||||||
use gtk::{
|
use gtk::{
|
||||||
gdk,
|
gdk,
|
||||||
glib::{self, clone, subclass::Signal},
|
glib::{self, clone, subclass::Signal},
|
||||||
|
graphene,
|
||||||
prelude::*,
|
prelude::*,
|
||||||
subclass::prelude::*,
|
subclass::prelude::*,
|
||||||
};
|
};
|
||||||
@@ -223,4 +224,20 @@ impl Port {
|
|||||||
.get()
|
.get()
|
||||||
.expect("Port direction is not set")
|
.expect("Port direction is not set")
|
||||||
}
|
}
|
||||||
|
|
||||||
|
pub fn link_anchor(&self) -> graphene::Point {
|
||||||
|
let style_context = self.style_context();
|
||||||
|
let padding_right: f32 = style_context.padding().right().into();
|
||||||
|
let border_right: f32 = style_context.border().right().into();
|
||||||
|
let padding_left: f32 = style_context.padding().left().into();
|
||||||
|
let border_left: f32 = style_context.border().left().into();
|
||||||
|
|
||||||
|
graphene::Point::new(
|
||||||
|
match self.direction() {
|
||||||
|
Direction::Output => self.width() as f32 + padding_right + border_right,
|
||||||
|
Direction::Input => 0.0 - padding_left - border_left,
|
||||||
|
},
|
||||||
|
self.height() as f32 / 2.0,
|
||||||
|
)
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|||||||
Reference in New Issue
Block a user