[gnome-break-timer/gtk-4: 2/2] Fix OverlayArrow being misaligned when offscreen
- From: Dylan McCall <dylanmccall src gnome org>
- To: commits-list gnome org
- Cc:
- Subject: [gnome-break-timer/gtk-4: 2/2] Fix OverlayArrow being misaligned when offscreen
- Date: Sun, 31 Jul 2022 07:09:35 +0000 (UTC)
commit 89b265085f2b60484397faa724ab4a5d100813a0
Author: Dylan McCall <dylan dylanmccall ca>
Date: Sun Jul 31 00:04:39 2022 -0700
Fix OverlayArrow being misaligned when offscreen
The coordinates of the target widget were being calculated from the
arrow widget, which is drawn inside a leaflet page that slides across
the screen. To solve this problem, we calculate the coordinates based on
the leaflet page's parent widget.
This is a bit crude, but there is a reasonable path from this state to
something more broadly useful.
src/settings/panels/WelcomePanel.vala | 2 +-
src/settings/widgets/OverlayArrow.vala | 92 ++++++++++++++++++----------------
2 files changed, 51 insertions(+), 43 deletions(-)
---
diff --git a/src/settings/panels/WelcomePanel.vala b/src/settings/panels/WelcomePanel.vala
index 9a8e70c..9354f7c 100644
--- a/src/settings/panels/WelcomePanel.vala
+++ b/src/settings/panels/WelcomePanel.vala
@@ -93,7 +93,7 @@ private class WelcomePanel : Gtk.Box {
}
private void build_overlay_arrow (Gtk.Overlay overlay, Gtk.Widget arrow_source, Gtk.Widget arrow_target)
{
- var arrow = new OverlayArrow (arrow_source, arrow_target);
+ var arrow = new OverlayArrow (arrow_source, arrow_target, this.stack);
overlay.add_overlay (arrow);
}
}
diff --git a/src/settings/widgets/OverlayArrow.vala b/src/settings/widgets/OverlayArrow.vala
index 1f84f95..8351283 100644
--- a/src/settings/widgets/OverlayArrow.vala
+++ b/src/settings/widgets/OverlayArrow.vala
@@ -20,38 +20,46 @@
namespace BreakTimer.Settings.Widgets {
-/* FIXME: This widget is stealing clicks when it is used in an overlay */
-
public class OverlayArrow : Gtk.DrawingArea {
private Gtk.Widget from_widget;
private Gtk.Widget to_widget;
+ private Gtk.Widget align_widget;
- public OverlayArrow (Gtk.Widget from_widget, Gtk.Widget to_widget) {
- GLib.Object ();
+ private enum ArrowDirection {
+ UP,
+ RIGHT,
+ DOWN,
+ LEFT
+ }
- // this.set_has_window (false);
+ /**
+ * Creates an OverlayArrow, which draws an arrow from one widget to another.
+ * from_widget: a widget to start the arrow from
+ * to_widget: a widget to end the arrow at
+ * align_widget: a widget to measure coordinates for the target widget, if
+ * in case from_widget slides into view from elsewhere.
+ */
+ public OverlayArrow (Gtk.Widget from_widget, Gtk.Widget to_widget, Gtk.Widget align_widget) {
+ GLib.Object (sensitive: false);
this.set_halign (Gtk.Align.FILL);
this.set_valign (Gtk.Align.FILL);
this.from_widget = from_widget;
this.to_widget = to_widget;
+ this.align_widget = align_widget;
this.set_draw_func (this.on_draw_cb);
}
private void on_draw_cb (Gtk.DrawingArea widget, Cairo.Context cr, int width, int height) {
- // FIXME: ARE THESE THE SAME AS GIVEN WIDTH AND HEIGHT?
int max_width = this.get_allocated_width ();
int max_height = this.get_allocated_height ();
- double from_x, from_y;
- this.get_from_coordinates (out from_x, out from_y);
+ double from_x, from_y, to_x, to_y;
+ this.get_from_to_coordinates (out from_x, out from_y, out to_x, out to_y);
from_x = from_x.clamp (0, max_width);
from_y = from_y.clamp (0, max_height);
-
- double to_x, to_y;
- this.get_to_coordinates (out to_x, out to_y);
to_x = to_x.clamp (0, max_width);
to_y = to_y.clamp (0, max_height);
@@ -75,48 +83,48 @@ public class OverlayArrow : Gtk.DrawingArea {
cr.stroke ();
}
- private void get_points_offset (out double offset_x, out double offset_y) {
+ private void get_from_to_coordinates (out double from_x, out double from_y, out double to_x, out double
to_y) {
+ Gtk.Allocation from_allocation;
Gtk.Allocation to_allocation;
+ this.from_widget.get_allocation (out from_allocation);
this.to_widget.get_allocation (out to_allocation);
- this.from_widget.translate_coordinates (this.to_widget, to_allocation.width/2,
to_allocation.width/2, out offset_x, out offset_y);
- }
- private void get_from_coordinates (out double from_x, out double from_y) {
- // Is to_widget to the right or to the left?
- Gtk.Allocation from_allocation;
- this.from_widget.get_allocation (out from_allocation);
+ double from_middle_y, from_start_x, from_end_x;
+ double to_middle_x, to_top_y, to_bottom_y;
+
+ this.from_widget.translate_coordinates (this, 0, from_allocation.height/2, null, out from_middle_y);
+ this.from_widget.translate_coordinates (this, -this.from_widget.margin_start, 0, out from_start_x,
null);
+ this.from_widget.translate_coordinates (this, from_allocation.width + this.from_widget.margin_end,
0, out from_end_x, null);
- double offset_x, offset_y;
- this.get_points_offset (out offset_x, out offset_y);
+ this.to_widget.translate_coordinates (this.align_widget, to_allocation.width/2, 0, out to_middle_x,
null);
+ this.to_widget.translate_coordinates (this.align_widget, 0, -this.to_widget.margin_top, null, out
to_top_y);
+ this.to_widget.translate_coordinates (this.align_widget, 0, to_allocation.height +
this.to_widget.margin_bottom, null, out to_bottom_y);
- double from_local_x, from_local_y;
- if (offset_x > 0) {
- from_local_x = 0;
- from_local_y = from_allocation.height / 2;
+ double distance_from_start = to_middle_x - from_start_x;
+ double distance_from_end = from_end_x - to_middle_x;
+
+ if (distance_from_start < distance_from_end) {
+ // Draw an arrow to the left
+ from_x = from_start_x;
+ to_x = to_middle_x;
} else {
- from_local_x = from_allocation.width;
- from_local_y = from_allocation.height / 2;
+ // Draw an arrow to the right
+ from_x = from_end_x;
+ to_x = to_middle_x;
}
- this.from_widget.translate_coordinates (this, from_local_x, from_local_y, out from_x, out from_y);
- }
-
- private void get_to_coordinates (out double to_x, out double to_y) {
- // Is to_widget to the right or to the left?
- Gtk.Allocation to_allocation;
- this.to_widget.get_allocation (out to_allocation);
- double offset_x, offset_y;
- this.get_points_offset (out offset_x, out offset_y);
+ double distance_to_top = from_middle_y - to_top_y;
+ double distance_to_bottom = to_bottom_y - from_middle_y;
- double to_local_x, to_local_y;
- if (offset_y > 0) {
- to_local_x = to_allocation.width / 2;
- to_local_y = to_allocation.height;
+ if (distance_to_top < distance_to_bottom) {
+ // Draw an arrow to the bottom
+ from_y = from_middle_y;
+ to_y = to_top_y;
} else {
- to_local_x = to_allocation.width / 2;
- to_local_y = 0;
+ // Draw an arrow to the top
+ from_y = from_middle_y;
+ to_y = to_bottom_y;
}
- this.to_widget.translate_coordinates (this, to_local_x, to_local_y, out to_x, out to_y);
}
}
[
Date Prev][
Date Next] [
Thread Prev][
Thread Next]
[
Thread Index]
[
Date Index]
[
Author Index]