I want to use RX to enable mouse dragging behaviour to select areas in a plot. (Oxyplot) It should be possible to select multiple areas in a plot and their should be a live update of the select area.
So far i have set up three observables from events:
var mouseDownObservable = Observable.FromEventPattern<OxyMouseDownEventArgs>(tmp, nameof(tmp.MouseDown))
.Where(e => e.EventArgs.ChangedButton == OxyMouseButton.Left)
.Where(e => e.EventArgs.IsControlDown == true);
var mouseMoveObservable = Observable.FromEventPattern<OxyMouseEventArgs>(tmp, nameof(tmp.MouseMove));
var mouseUpObservable = Observable.FromEventPattern<OxyMouseEventArgs>(tmp, nameof(tmp.MouseUp));
Iam new to RX, so my first attempt was:
var result = mouseDownObservable
.Select(m => m.EventArgs.Position)
.Merge(mouseMoveObservable
.SkipUntil(mouseDownObservable.Select(e => e.EventArgs.Position).Do(e1 =>
{
// .. create annotation in plot
}))
.TakeUntil(mouseUpObservable)
.Select(m => m.EventArgs.Position)
.Repeat());
.CombineLatest(mouseDownObservable.Select(e => e.EventArgs.Position),
(endPoint, startPoint) => new List<ScreenPoint>() { endPoint, startPoint })
.Do(e =>
{
// .. update actual annotation to current endPoint
})
.Subscribe();
I didnt know how to preserve the state (startPoint of mouseDown) so i choose to use CombineLatest.
The first i select an area it works quite well. If i want to select another area i get the correct startPoint (d1) but the endpoint is still the last element of (r). Marble Diagram
- What is a good approach to preserve the information of the starting point? I feel a bit clumsy about that.
- How can i group the result, so that there will be exactly one mouseDragObservable per combined mouse drag interaction?
I think you're overthinking things a bit.
Here's the query you need:
So this is simply waiting for a mouse down and then recording all moves that happen after that until there's a mouse up. So, basically a drag operation.
Because the first part is
from down in mouseDownObservable
you have a record of theX
/Y
coordinates at the time of the mouse down. It's very easy to then produce a series of coordinate deltas based on the position during each move.