Skip to content

Commit a067e00

Browse files
committed
Touch support in PlotBase
1 parent 1eb365c commit a067e00

File tree

2 files changed

+84
-65
lines changed

2 files changed

+84
-65
lines changed

Source/Examples/Avalonia/AvaloniaExamples/Examples/ControllerDemo/CustomPlotController.cs

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -18,6 +18,7 @@ public CustomPlotController()
1818
this.UnbindAll();
1919
this.BindKeyDown(OxyKey.Left, PlotCommands.PanRight);
2020
this.BindKeyDown(OxyKey.Right, PlotCommands.PanLeft);
21+
this.BindTouchDown(PlotCommands.PanZoomByTouch);
2122
}
2223
}
2324
}

Source/OxyPlot.Avalonia/PlotBase.Events.cs

Lines changed: 83 additions & 65 deletions
Original file line numberDiff line numberDiff line change
@@ -13,6 +13,8 @@ namespace OxyPlot.Avalonia
1313
{
1414
using global::Avalonia.Input;
1515
using System;
16+
using System.Collections.Generic;
17+
using System.Linq;
1618

1719
/// <summary>
1820
/// Represents a control that displays a <see cref="PlotModel" />.
@@ -35,53 +37,6 @@ protected override void OnKeyDown(KeyEventArgs e)
3537
e.Handled = ActualController.HandleKeyDown(this, args);
3638
}
3739

38-
/*
39-
/// <summary>
40-
/// Called when the <see cref="E:System.Windows.UIElement.ManipulationStarted" /> event occurs.
41-
/// </summary>
42-
/// <param name="e">The data for the event.</param>
43-
protected override void OnManipulationStarted(ManipulationStartedEventArgs e)
44-
{
45-
base.OnManipulationStarted(e);
46-
if (e.Handled)
47-
{
48-
return;
49-
}
50-
51-
e.Handled = ActualController.HandleTouchStarted(this, e.ToTouchEventArgs(this));
52-
}
53-
54-
/// <summary>
55-
/// Called when the <see cref="E:System.Windows.UIElement.ManipulationDelta" /> event occurs.
56-
/// </summary>
57-
/// <param name="e">The data for the event.</param>
58-
protected override void OnManipulationDelta(ManipulationDeltaEventArgs e)
59-
{
60-
base.OnManipulationDelta(e);
61-
if (e.Handled)
62-
{
63-
return;
64-
}
65-
66-
e.Handled = ActualController.HandleTouchDelta(this, e.ToTouchEventArgs(this));
67-
}
68-
69-
/// <summary>
70-
/// Called when the <see cref="E:System.Windows.UIElement.ManipulationCompleted" /> event occurs.
71-
/// </summary>
72-
/// <param name="e">The data for the event.</param>
73-
protected override void OnManipulationCompleted(ManipulationCompletedEventArgs e)
74-
{
75-
base.OnManipulationCompleted(e);
76-
if (e.Handled)
77-
{
78-
return;
79-
}
80-
81-
e.Handled = ActualController.HandleTouchCompleted(this, e.ToTouchEventArgs(this));
82-
}
83-
*/
84-
8540
/// <summary>
8641
/// Called before the <see cref="E:System.Windows.UIElement.MouseWheel" /> event occurs to provide handling for the event in a derived class without attaching a delegate.
8742
/// </summary>
@@ -97,6 +52,11 @@ protected override void OnPointerWheelChanged(PointerWheelEventArgs e)
9752
e.Handled = ActualController.HandleMouseWheel(this, e.ToMouseWheelEventArgs(this));
9853
}
9954

55+
/// <summary>
56+
/// Gets the dictionary of locations of touch pointers.
57+
/// </summary>
58+
private SortedDictionary<int, ScreenPoint> TouchPositions { get; } = new SortedDictionary<int, ScreenPoint>();
59+
10060
/// <summary>
10161
/// Invoked when an unhandled MouseDown attached event reaches an element in its route that is derived from this class. Implement this method to add class handling for this event.
10262
/// </summary>
@@ -112,10 +72,32 @@ protected override void OnPointerPressed(PointerPressedEventArgs e)
11272
Focus();
11373
e.Pointer.Capture(this);
11474

115-
// store the mouse down point, check it when mouse button is released to determine if the context menu should be shown
116-
mouseDownPoint = e.GetPosition(this).ToScreenPoint();
75+
if (e.Pointer.Type == PointerType.Touch)
76+
{
77+
var position = e.GetPosition(this).ToScreenPoint();
78+
79+
var touchEventArgs = new OxyTouchEventArgs()
80+
{
81+
ModifierKeys = e.KeyModifiers.ToModifierKeys(),
82+
Position = position,
83+
DeltaTranslation = new ScreenVector(0, 0),
84+
DeltaScale = new ScreenVector(1, 1),
85+
};
86+
87+
TouchPositions[e.Pointer.Id] = position;
88+
89+
if (TouchPositions.Count == 1)
90+
{
91+
e.Handled = ActualController.HandleTouchStarted(this, touchEventArgs);
92+
}
93+
}
94+
else
95+
{
96+
// store the mouse down point, check it when mouse button is released to determine if the context menu should be shown
97+
mouseDownPoint = e.GetPosition(this).ToScreenPoint();
11798

118-
e.Handled = ActualController.HandleMouseDown(this, e.ToMouseDownEventArgs(this));
99+
e.Handled = ActualController.HandleMouseDown(this, e.ToMouseDownEventArgs(this));
100+
}
119101
}
120102

121103
/// <summary>
@@ -130,7 +112,21 @@ protected override void OnPointerMoved(PointerEventArgs e)
130112
return;
131113
}
132114

133-
e.Handled = ActualController.HandleMouseMove(this, e.ToMouseEventArgs(this));
115+
if (e.Pointer.Type == PointerType.Touch)
116+
{
117+
var point = e.GetPosition(this).ToScreenPoint();
118+
var oldTouchPoints = TouchPositions.Values.ToArray();
119+
TouchPositions[e.Pointer.Id] = point;
120+
var newTouchPoints = TouchPositions.Values.ToArray();
121+
122+
var touchEventArgs = new OxyTouchEventArgs(newTouchPoints, oldTouchPoints);
123+
124+
e.Handled = ActualController.HandleTouchDelta(this, touchEventArgs);
125+
}
126+
else
127+
{
128+
e.Handled = ActualController.HandleMouseMove(this, e.ToMouseEventArgs(this));
129+
}
134130
}
135131

136132
/// <summary>
@@ -149,28 +145,50 @@ protected override void OnPointerReleased(PointerReleasedEventArgs e)
149145

150146
e.Pointer.Capture(null);
151147

152-
e.Handled = ActualController.HandleMouseUp(this, releasedArgs.ToMouseReleasedEventArgs(this));
148+
if (e.Pointer.Type == PointerType.Touch)
149+
{
150+
var position = e.GetPosition(this).ToScreenPoint();
153151

154-
// Open the context menu
155-
var p = e.GetPosition(this).ToScreenPoint();
156-
var d = p.DistanceTo(mouseDownPoint);
152+
var touchEventArgs = new OxyTouchEventArgs()
153+
{
154+
ModifierKeys = e.KeyModifiers.ToModifierKeys(),
155+
Position = position,
156+
DeltaTranslation = new ScreenVector(0, 0),
157+
DeltaScale = new ScreenVector(1, 1),
158+
};
157159

158-
if (ContextMenu != null)
159-
{
160-
if (Math.Abs(d) < 1e-8 && releasedArgs.InitialPressMouseButton == MouseButton.Right)
160+
TouchPositions.Remove(e.Pointer.Id);
161+
162+
if (TouchPositions.Count == 0)
161163
{
162-
ContextMenu.DataContext = DataContext;
163-
ContextMenu.IsVisible = true;
164+
e.Handled = ActualController.HandleTouchCompleted(this, touchEventArgs);
164165
}
165-
else
166+
}
167+
else
168+
{
169+
e.Handled = ActualController.HandleMouseUp(this, releasedArgs.ToMouseReleasedEventArgs(this));
170+
171+
// Open the context menu
172+
var p = e.GetPosition(this).ToScreenPoint();
173+
var d = p.DistanceTo(mouseDownPoint);
174+
175+
if (ContextMenu != null)
166176
{
167-
ContextMenu.IsVisible = false;
177+
if (Math.Abs(d) < 1e-8 && releasedArgs.InitialPressMouseButton == MouseButton.Right)
178+
{
179+
ContextMenu.DataContext = DataContext;
180+
ContextMenu.IsVisible = true;
181+
}
182+
else
183+
{
184+
ContextMenu.IsVisible = false;
185+
}
168186
}
169187
}
170188
}
171189

172190
/// <summary>
173-
/// Invoked when an unhandled <see cref="E:System.Windows.Input.Mouse.MouseEnter" /> attached event is raised on this element. Implement this method to add class handling for this event.
191+
/// Invoked when an unhandled <see cref="E:System.Windows.Input.Mouse.MouseEnter" /> attached event is raised on this element. Implement this method to add class handling for this event.
174192
/// </summary>
175193
/// <param name="e">The <see cref="T:System.Windows.Input.MouseEventArgs" /> that contains the event data.</param>
176194
protected override void OnPointerEnter(PointerEventArgs e)
@@ -185,7 +203,7 @@ protected override void OnPointerEnter(PointerEventArgs e)
185203
}
186204

187205
/// <summary>
188-
/// Invoked when an unhandled <see cref="E:System.Windows.Input.Mouse.MouseLeave" /> attached event is raised on this element. Implement this method to add class handling for this event.
206+
/// Invoked when an unhandled <see cref="E:System.Windows.Input.Mouse.MouseLeave" /> attached event is raised on this element. Implement this method to add class handling for this event.
189207
/// </summary>
190208
/// <param name="e">The <see cref="T:System.Windows.Input.MouseEventArgs" /> that contains the event data.</param>
191209
protected override void OnPointerLeave(PointerEventArgs e)
@@ -199,4 +217,4 @@ protected override void OnPointerLeave(PointerEventArgs e)
199217
e.Handled = ActualController.HandleMouseLeave(this, e.ToMouseEventArgs(this));
200218
}
201219
}
202-
}
220+
}

0 commit comments

Comments
 (0)