Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Handle mouse events on PlotController instead of PlotModel (and elements) #111

Open
objorke opened this issue Aug 14, 2014 · 18 comments
Open

Comments

@objorke
Copy link
Member

objorke commented Aug 14, 2014

Imported from http://oxyplot.codeplex.com/workitem/10132

objo 2014-02-17 08:08
We can achieve the same functionality by using a PlotController

https://oxyplot.codeplex.com/workitem/9625

  • Better separation of controller logic and model
  • Less code
  • Better performance of PlotController

objo 2014-03-19 22:57
It seems to be quite convenient to use the events. Or is that valid only for the simple demos?

objo 2014-03-21 09:02
An alternative could be to add an EnableMouseEventsInModel property on the
PlotController. The default value could be false. When the value is false, the mouse events should not be raised on the
PlotModel and PlotElements.

tibel 2014-04-12 08:43
Hmm, still don't like it. The PlotModel and its child elements should not know anything about a mouse, keyboard or touch. Also it is easy to create memory leaks by events on child elements of the PlotModel when your plot is more dynamic (e.g. adding and
removing annotations).

Therefore I would prefer following:

  • mouse/keyboard events exist only on PlotController and the event will tell you what element of the plot was e.g. clicked
  • similar the AxisChanged should be on PlotModel and tell you what axis changed
  • Ultimately no child element of the plotmodel should expose any events

With this approach I don't have problems with adding/removing elements from the plotmodel and my event handlers.

@mcmatze
Copy link

mcmatze commented Aug 19, 2014

In Microsoft Charting i guess there were events of the Chart. If you clicked it (for example Click event) and wanted something about the clicked series or axes, there was the HitTest(Mouse) method that gave you all the hitted elements and further information. Correct me if i'm wrong but as far as i remember, no child elements of Chart had events.

Related to the issue i have following question: what are the PlotView events, PlotModel events and other events are for? Without any further knowledge, i guess PlotView event MouseDown is the same like PlotModel MouseDown. If they are redundant, it would be better to remove one of them to make a better consistency.

@objorke
Copy link
Member Author

objorke commented Aug 19, 2014

Yes, we could consider to add more information to the event arguments! But that must be a different issue. This issue is about removing the events.

The events in the PlotView are standard routed events. The events in the PlotModel are standard events and makes it possible to handle such events in portable code. I like this feature for small demos, but agree that it may not be a good pattern for larger applications.

@mcmatze
Copy link

mcmatze commented Aug 19, 2014

How about this?

User presses mouse button (platform dependend)
 --> PlotView (internal event triggered)
  --> PlotController (
      get event calls from PlotViews (PlotView -> PlotController.PointerDown(Args));
      do some internal stuff with Model;
      maybe save hit tests?)
   --> PlotView (PlotController says that a Pointer (platform independend) was pressed)

    --> PlotView.MouseDown(Argument: sender, MouseDownEventArgs))

(Example pseudocode for handling by user)
{
  if(Mouse.Buttons.Left == ButtonState.Pressed) //platform dependent
  {
    BarSeriesInformation[] info = (sender as PlotView).PlotController.GetHittedElements<BarSeries>();
    if(info.Length != 0)
      ShowMessage("You hitted the bar at"+info[0].XVal+" from series "+info[0].SeriesTitle);
  }
}

No events needed in the classes except PlotView (platform dependent) and PlotController (platform independend)

So the PlotController handles all the events that is currently in PlotModel. I guess these events should be private/protected because they are only for internal handling? External you get all needed information from the PlotView event.

@tibel
Copy link
Contributor

tibel commented May 12, 2015

I like the suggested solution.
A nice and clean way to handle all user interaction in the plot controller.

@tibel tibel changed the title Remove mouse events from plot elements Hanlde mouse events on PlotController instead of PlotModel (and elements) May 12, 2015
@tibel tibel changed the title Hanlde mouse events on PlotController instead of PlotModel (and elements) Handle mouse events on PlotController instead of PlotModel (and elements) May 14, 2015
@objorke objorke removed the CodePlex label Oct 4, 2015
@objorke objorke added this to the v2.0 milestone Oct 16, 2016
@malambika
Copy link

malambika commented Nov 25, 2016

hello tibel im new to this xamairn..how to handle mouse evnt in oxyplot using plotcontroller?

@objorke objorke removed this from the v2.0 milestone Sep 4, 2019
@objorke objorke added this to the v3.0 milestone Oct 17, 2019
objorke added a commit to objorke/oxyplot that referenced this issue Oct 27, 2019
@VisualMelon
Copy link
Contributor

Would it be possible to discuss how existing usage of mouse events could be refitted? For example, if there is a plot-annotation that the user should be able click-and-drag, how do we imagine that would be achieved? Currently this is easily achieved with events, and can be done without the risk of memory leaks easily. A controller/module separation would require a way to register a per-component (or per-type-of-component) controller along with a way for this controller to 'take control' (e.g. when the component is clicked, or some other UI action outside of the library), and this doesn't seem to be provided. That is, there is no native provision for doing anything other than displaying the tracker when a left-mouse button is pressed: the controller does not have a composable extension point that lets us combine controllers for the left-mouse down gesture.

Without such a system, it'll be infeasible to produce portable and cross-platform interactive plot components.

For the record, I do use mouse events for work, so I have a vested interest in the existing functionality. I'd be happy to 'update' my existing code to a better system, but it would need to provide the same capabilities we enjoy at the moment.

@Doeharrrck
Copy link
Contributor

It is definitely needed to keep some events on the model layer that allow the plot model or it's children to notify about changes to keep the current functionality. For instance, I implemented the functionality of the Mouse Events - LineAnnotation example by implementing a manipulator to achieve the same functionality. But what if I want to display the current position of the cursor line OUTSIDE the plot. Another example is coupling axes among several plots like here.
I think there must be a separation between events that handle user input like mouse or keyboard events on the one hand, and events that notify what's going on inside the plot on the other hand. Only the first group of events can be easily replaced by manipulator instances.

@nzain
Copy link
Contributor

nzain commented Oct 4, 2021

Many PlotModel.MouseX are now obsolete and link to this ticket. That doesn't help me... what is the new alternative? I read that the controller should be used. How? Even worse: the examples of this repository suggest the same deprecated code.

So much code is broken now, events being only one of the non-trivial topics. We have a large code base on top of OxyPlot, turned into a nightmare of compiler errors and warnings.

@VisualMelon
Copy link
Contributor

VisualMelon commented Oct 4, 2021

@nzain this is a good and important question, and I'm afraid I can't give you a good answer. The link to this is just as an indication of why the events are so annotated. Indeed, we need to provide better examples for this, and for many events there is presently no obvious alternative.

https://github.com/oxyplot/oxyplot/blob/develop/Source/Examples/ExampleLibrary/Examples/PlotControllerExamples.cs is the canonical plot controller example. Note that you can use hittesting to determine which plot elements have been clicked etc. and dispatch accordingly. The default controller implementation is also instructive: https://github.com/oxyplot/oxyplot/tree/develop/Source/OxyPlot/PlotController

Note that you can disable the warnings locally with #pragma warning disable CS0618 (re-enable with #pragma warning disable CS0618) and the events are not going anywhere soon so I would not worry about continuing to use them for the time being.

If you have specific use-cases which are not well supported by the plot controller (or it's not obvious how they can be supported), please do open individual issues for then. This will help inform which examples we provide and motivate further development of the controller system if necessary.

@nzain
Copy link
Contributor

nzain commented Oct 4, 2021

Thanks for the link to the PlotControllerExample. We are actually using PlotController already, mixed with PlotModel.MouseX events in the very same objects. I don't remember why, but it looks like some functionality was only accessible through either events XOR controller.

Too much of my code is not working anymore. I can't even see some very basic RectangleAnnotation objects anymore. Before I can investigate (and eventually create issues) I'll need a large time slot. For now we have to stick to version 2.0. I'll monitor this issue for updates.

@VisualMelon
Copy link
Contributor

Too much of my code is not working anymore. I can't even see some very basic RectangleAnnotation objects anymore. Before I can investigate (and eventually create issues) I'll need a large time slot. For now we have to stick to version 2.0. I'll monitor this issue for updates.

No problem. If you think there are any regressions in 2.1, or anything that should be mentioned in the release notes but isn't, please do report them as well as separate issues or ping me on the gitter.

@trockefeller-pathway
Copy link

I think I have figured out how to replace the event handlers for MouseDown with something like below

Controller.BindMouseDown(OxyMouseButton.Left, new DelegateViewCommand<OxyMouseDownEventArgs>(myPlot_HandleMouseDown));

private void myPlot_HandleMouseDown(IView view, IController controller, OxyMouseDownEventArgs e)
{
    //handle mouse down stuff
}

But when trying to do something similar for MouseUp and MouseMove, I am finding that there is no BindMouseUp or BindMouseMove, but instead there are methods HandleMouseUp and HandleMouseMove

How do I replace those event handlers that were originally written something like this

myPlotModel.MouseUp += myPlotModel_MouseUp;
myPlotModel.MouseMove += myPlotModel_MouseMove;

@VisualMelon
Copy link
Contributor

VisualMelon commented Feb 7, 2022

@trockefeller-pathway I don't think you can: the idea is that MoustDown, MouseMove, and MouseUp are all handled by a single manipulator with methods Started, Delta, and Completed as part of a single 'gesture'.

@trockefeller-pathway
Copy link

@VisualMelon should that look something like this?

_myPlot.Controller.BindMouseDown(OxyMouseButton.Left, new DelegatePlotCommand<OxyMouseDownEventArgs>(myPlot_MouseDown));

private void myPlot_MouseDown(IPlotView view, IController controller, OxyMouseDownEventArgs e)
{
    view.ActualController.AddMouseManipulator(view, new MyCustomPlotMouseManipulator(view), e);
}

class MyCustomPlotMouseManipulator : MouseManipulator
{
    public MyCustomPlotMouseManipulator(IPlotView view) : base(view) { }

    public override void Started(OxyMouseEventArgs e)
    {
        //do my on mouse down logic
    }

    public override void Delta(OxyMouseEventArgs e)
    {
        //do my on mouse move logic
    }

    public override void Completed(OxyMouseEventArgs e)
    {
        //do my on mouse up logic
    }
}

@VisualMelon
Copy link
Contributor

@trockefeller-pathway yeah, that's the idea. See https://github.com/oxyplot/oxyplot/blob/develop/Source/OxyPlot/PlotController/Manipulators/PanManipulator.cs for a full example of a mouse manipulator implementation.

@Jkallus
Copy link

Jkallus commented Jun 2, 2022

@trockefeller-pathway Did you find a path forward?

@TimurVa
Copy link

TimurVa commented Dec 11, 2023

@VisualMelon It's still unclear for me. How we should handle mouse down/move/up on Line annotation for example with AddMouseManipulator as all events are deprecated?

@Spordoz
Copy link

Spordoz commented May 15, 2024

@TimurVa You can handle them in the manipulator as displayed above and do a hit test on your Annotation during the respective function (started for down, delta for move, completed for up)

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Projects
None yet
Development

No branches or pull requests