Skip to content

Commit 4b98f15

Browse files
authored
Fix minimap updating the viewport without having the mouse captured (#169)
1 parent 138de2a commit 4b98f15

File tree

1 file changed

+39
-22
lines changed

1 file changed

+39
-22
lines changed

Nodify/Minimap/Minimap.cs

Lines changed: 39 additions & 22 deletions
Original file line numberDiff line numberDiff line change
@@ -98,6 +98,11 @@ public event ZoomEventHandler Zoom
9898
/// </summary>
9999
protected internal Panel ItemsHost { get; private set; } = default!;
100100

101+
/// <summary>
102+
/// Whether the user is currently dragging the minimap.
103+
/// </summary>
104+
protected bool IsDragging { get; private set; }
105+
101106
static Minimap()
102107
{
103108
DefaultStyleKeyProperty.OverrideMetadata(typeof(Minimap), new FrameworkPropertyMetadata(typeof(Minimap)));
@@ -111,19 +116,31 @@ public override void OnApplyTemplate()
111116
ItemsHost = GetTemplateChild(ElementItemsHost) as Panel ?? throw new InvalidOperationException($"{ElementItemsHost} is missing or is not of type {nameof(Panel)}.");
112117
}
113118

114-
protected bool IsDragging { get; private set; }
119+
protected override DependencyObject GetContainerForItemOverride()
120+
=> new MinimapItem();
121+
122+
protected override bool IsItemItsOwnContainerOverride(object item)
123+
=> item is MinimapItem;
124+
125+
protected override void OnLostMouseCapture(MouseEventArgs e)
126+
=> IsDragging = false;
115127

116128
protected override void OnMouseDown(MouseButtonEventArgs e)
117129
{
118130
var gestures = EditorGestures.Mappings.Minimap;
119131
if (!IsReadOnly && gestures.DragViewport.Matches(this, e))
120132
{
121-
this.CaptureMouseSafe();
122133
IsDragging = true;
123134

124135
SetViewportLocation(e.GetPosition(ItemsHost));
125136

126137
e.Handled = true;
138+
139+
if (Mouse.Captured == null || IsMouseCaptured)
140+
{
141+
Focus();
142+
CaptureMouse();
143+
}
127144
}
128145
}
129146

@@ -135,28 +152,13 @@ protected override void OnMouseMove(MouseEventArgs e)
135152
}
136153
}
137154

138-
private void SetViewportLocation(Point location)
139-
{
140-
var position = location - new Vector(ViewportSize.Width / 2, ViewportSize.Height / 2) + (Vector)Extent.Location;
141-
142-
if (MaxViewportOffset.Width != 0 || MaxViewportOffset.Height != 0)
143-
{
144-
double maxRight = ResizeToViewport ? ItemsExtent.Right : Math.Max(ItemsExtent.Right, ItemsExtent.Left + ViewportSize.Width);
145-
double maxBottom = ResizeToViewport ? ItemsExtent.Bottom : Math.Max(ItemsExtent.Bottom, ItemsExtent.Top + ViewportSize.Height);
146-
147-
position.X = position.X.Clamp(ItemsExtent.Left - ViewportSize.Width / 2 - MaxViewportOffset.Width, maxRight - ViewportSize.Width / 2 + MaxViewportOffset.Width);
148-
position.Y = position.Y.Clamp(ItemsExtent.Top - ViewportSize.Height / 2 - MaxViewportOffset.Height, maxBottom - ViewportSize.Height / 2 + MaxViewportOffset.Height);
149-
}
150-
151-
ViewportLocation = position;
152-
}
153-
154155
protected override void OnMouseUp(MouseButtonEventArgs e)
155156
{
156157
var gestures = EditorGestures.Mappings.Minimap;
157158
if (IsDragging && gestures.DragViewport.Matches(this, e))
158159
{
159160
IsDragging = false;
161+
e.Handled = true;
160162
}
161163

162164
if (IsMouseCaptured && e.RightButton == MouseButtonState.Released && e.LeftButton == MouseButtonState.Released && e.MiddleButton == MouseButtonState.Released)
@@ -169,6 +171,11 @@ protected override void OnMouseWheel(MouseWheelEventArgs e)
169171
{
170172
if (!IsReadOnly && !e.Handled && EditorGestures.Mappings.Minimap.ZoomModifierKey == Keyboard.Modifiers)
171173
{
174+
if (!ResizeToViewport)
175+
{
176+
SetViewportLocation(e.GetPosition(ItemsHost));
177+
}
178+
172179
double zoom = Math.Pow(2.0, e.Delta / 3.0 / Mouse.MouseWheelDeltaForOneLine);
173180
var location = ViewportLocation + (Vector)ViewportSize / 2;
174181

@@ -183,10 +190,20 @@ protected override void OnMouseWheel(MouseWheelEventArgs e)
183190
}
184191
}
185192

186-
protected override DependencyObject GetContainerForItemOverride()
187-
=> new MinimapItem();
193+
private void SetViewportLocation(Point location)
194+
{
195+
var position = location - new Vector(ViewportSize.Width / 2, ViewportSize.Height / 2) + (Vector)Extent.Location;
188196

189-
protected override bool IsItemItsOwnContainerOverride(object item)
190-
=> item is MinimapItem;
197+
if (MaxViewportOffset.Width != 0 || MaxViewportOffset.Height != 0)
198+
{
199+
double maxRight = ResizeToViewport ? ItemsExtent.Right : Math.Max(ItemsExtent.Right, ItemsExtent.Left + ViewportSize.Width);
200+
double maxBottom = ResizeToViewport ? ItemsExtent.Bottom : Math.Max(ItemsExtent.Bottom, ItemsExtent.Top + ViewportSize.Height);
201+
202+
position.X = position.X.Clamp(ItemsExtent.Left - ViewportSize.Width / 2 - MaxViewportOffset.Width, maxRight - ViewportSize.Width / 2 + MaxViewportOffset.Width);
203+
position.Y = position.Y.Clamp(ItemsExtent.Top - ViewportSize.Height / 2 - MaxViewportOffset.Height, maxBottom - ViewportSize.Height / 2 + MaxViewportOffset.Height);
204+
}
205+
206+
ViewportLocation = position;
207+
}
191208
}
192209
}

0 commit comments

Comments
 (0)