Previously, the allocated height and width to a node on the graph was divided by the zoom factor,
to account for the changed size from them being zoomed.
To zoom each node, we `size_allocate` it with a GskTransform that scales it.
However, using a scaling transform to allocate the node already takes care of scaling the height and
width, so us also scaling the height and width manually means we were overcompensating.
This resulted in the allocation becoming to big when zooming out, and to small when zooming in.
This is observable as labels will become smaller when zooming in and ellipsize their content.
The commit removes the extra manual scaling so nodes get allocated properly when zoomed.
This sets a maximum width of 20 chars on labels on nodes and ports.
Longer labels will wrap to a second line.
For labels longer than two lines, the label is ellipsized at the end.
The full label can still be viewed via hovering for a tooltip.
Co-authored-by: Roger Roger <me@rogerrogert.de>
The new widget sits in the headerbar, and allows for changing the zoom level with "+" and "-" buttons, via text entry, and a dropdown where a list of predefined levels can be clicked.
The graphview widget now implements the gtk::Scrollable interface, so it is no longer wrapped inside a gtk::Viewport when used in a gtk::ScrollWindow anymore.
Instead, it repositions its content itself when scrolled, and also skips rendering any content that is not inside the visible area, which should improve performance
when the graph becomes big.
This commit also makes the canvas a fixed size, with much space to each side from the starting area.
This will hopefully improve user experience, as the view can now be moved around more freely, and nodes can be dragged left and above the starting area.
This makes gtk draw the background grid for us via CSS, instead of manually drawing each line via cairo.
This improves performance, as the grid may now be drawn via GPU, and gets rid of the custom drawing code we had.
This removes the manual painting of the background via cairo and adds the correct color to CSS instead,
which should hopefully improve performance as we do less cpu painting like this.
For good contrast in both dark and light mode, the link color is now a semi-light gray instead of complete black, which had bad contrast in dark mode and good constrast in light mode.
Later, we can seperate color palettes for light and dark mode, but only together with a dark mode toggle button or system-wide darkmode toggle.
Previously, these were defined directly in the code,
but defining them in the css helps seperating theming and behaviour
and makes the colors easier to tweak.
While the position of a node not on the graph should never be requested, this seems to occur sometimes,
so instead of panicking, we only log an error now, or ignore that node if it wasn't
important.
to the left side of the screen. So by adding a constant offset,
we can avoid having possible links that are partly out of the view
just after starting the program
Links can now created by dragging in both directions, so now from an input port to an output port, too.
The drag-n-drop handlers now use dedicated types for each direction, so that no mismatched things can be dropped on each other.
Control points are now offset by half the x distance of the start and end points instead of a constant,
which makes the curve scale better with varying distance.
While the properties for a links node ids are not always set, they always are in the link info.
Also, the work done in this commit will easily allow to get the format of links and ports later,
so that we can get the format of them much more reliably,
and we can also get notified of changes to an existing global via the info callback.
This is more reliable than assuming the link carries the id of its nodes, as there have been cases where a link was created without those
properties set.
Instead, we can just pull them from the state via the port ids of the link.
Glib MainContext is now aquired manually because a change in gtk-rs would lead to
a panic when attaching the receiver otherwise, because gtk::init() doesn't
"leak" the default main context anymore.
Revamp the node dragging implementation, moving it into the GraphView
widget.
When a drag is initiated, the node widget's current position is stored.
Whenever the drag gesture is updated, the node widget's position is set
by adding the relative drag vector to the position at the start of the
drag.
A drag gesture on the node widget rather than the GraphView widget was
considered, but this seems to lead to a weird flickering effect when the
node is moved while the drag gesture on the node is active.
To avoid interfering with the drag handlers on the ports, check if the
GraphView drag gesture targets a port, in which case the handler does
nothing.
This extends the `Application` struct to keep more advanced state.
This state is then used to determine the needed information to create
or delete a link between the two connected ports.
A message to create/delete the link is then send to the pipewire thread,
which executed the request.