Recent

Author Topic: [SOLVED] Problem with popup and panning  (Read 4536 times)

VitalArt

  • New Member
  • *
  • Posts: 26
[SOLVED] Problem with popup and panning
« on: May 25, 2016, 11:36:07 am »
  Okay, I have a problem with using a popup menu on a TGraph. There's been similar topics, but not quite the same.
  So I have a graph with default panning and zooming functionality, and I'm content with it. The problem is the following: I want to have a popup menu on rightclick, but it shows up not only on righclick, but also after right-click pan finishes, which is mildly annoying.
  I tried to workaround this bu disabling Autopopup and doing it manually, however Graph.OnClick does not understand right-clicks. Then I tried OnMouseDown and OnMouseUp, but for some reason they only react to double-clicks. (Because of built-in tools?)
  Then I tried TPopupMenu.OnPopup with TGraph.ExtentChanged. I thought I'd TPopupMenu.Close the popup immediately if the extent did indeed change, but that doesn't work since the popup menu doesn't open until after OnPopup. Also I'm pretty sure Close doesn't do anything.
  If anyone has a neat solution for this, I would really appreciate it. Otherwise, I might try to do something with a toolset, but really I don't think this should be necessary for such a minor problem. IMO the default behaviour should be to not show the Popup menu after panning the graph, especially since panning is enabled by default.
« Last Edit: June 02, 2016, 04:02:38 pm by VitalArt »

Michl

  • Full Member
  • ***
  • Posts: 226
Re: Problem with popup and panning
« Reply #1 on: May 25, 2016, 12:10:58 pm »
If your TChartToolset1PanDragTool.Shift is ssRight and your TPopupMenu.Autopopup is false. You could do:
Code: Pascal  [Select][+][-]
  1.   TForm1 = class(TForm)
  2. ...
  3.   private
  4.     FRightMouseDown: Boolean;
  5. ...
  6. procedure TForm1.ChartToolset1PanDragTool1AfterMouseDown(
  7.   ATool: TChartTool; APoint: TPoint);
  8. begin
  9.   FRightMouseDown := True;
  10. end;
  11.  
  12. procedure TForm1.ChartToolset1PanDragTool1AfterMouseMove(
  13.   ATool: TChartTool; APoint: TPoint);
  14. begin
  15.   FRightMouseDown := False;
  16. end;
  17.  
  18. procedure TForm1.ChartToolset1PanDragTool1AfterMouseUp(
  19.   ATool: TChartTool; APoint: TPoint);
  20. begin
  21.   if FRightMouseDown then
  22.   begin
  23.     APoint := Chart1.ClientToScreen(APoint);
  24.     PopupMenu1.PopUp(APoint.x, APoint.y);
  25.   end;
  26. end;    
Code: [Select]
type
  TLiveSelection = (lsMoney, lsChilds, lsTime);
  TLive = Array[0..1] of TLiveSelection;

wp

  • Hero Member
  • *****
  • Posts: 11923
Re: Problem with popup and panning
« Reply #2 on: May 25, 2016, 02:37:25 pm »
I think it is not possible to solve this issue with keeping the built-in tools in place because the chart does not see the basic mouse events this way.

Here's my solution, the effort to restore zoom/pan capabilities with an external ChartToolset is minimal:
  • Add a ChartToolset and link it to the chart
  • Add a TPanDragTool. Set its Shift to ssRight.
  • If you need zooming, add a TZoomDragTool, set its Shift to ssLeft
  • Add a boolean state variable "FMouseMoved" to the form
  • In the OnAfterMouseDown event of the TPanDragTool set FMouseMoved to false.
  • In the OnAfterMouseMove event of the TPanDragTool set FMouseMoved to false.
  • Add an event handler for the OnContextPopup event. This event has a boolean parameter "Handled" which prevents the popup to show. Set Handled to FMouseMoved. I just published this event for the Lazarus trunk version. In older versions assign this code manually as shown here (you must cast the chart to some derived class in order to access the protected property):
Code: Pascal  [Select][+][-]
  1. procedure TForm1.Chart1ContextPopup(Sender: TObject; MousePos: TPoint;
  2.   var Handled: Boolean);
  3. begin
  4.   Handled := FMouseMoved;
  5. end;  
  6.  
  7. procedure TForm1.ChartToolset1PanDragTool1AfterMouseDown(ATool: TChartTool;
  8.   APoint: TPoint);
  9. begin
  10.   FMouseMoved := false;
  11. end;
  12.  
  13. procedure TForm1.ChartToolset1PanDragTool1AfterMouseMove(ATool: TChartTool;
  14.   APoint: TPoint);
  15. begin
  16.   FMouseMoved := true;
  17. end;
  18.  
  19. // Next is not required with the trunk version of Lazarus:
  20.  
  21. type
  22.   TMyChart = class(TChart);
  23.  
  24. procedure TForm1.FormCreate(Sender: TObject);
  25. begin
  26.   TMyChart(Chart1).OnContextPopup := @Chart1ContextPopup;
  27. end;
  28.  

VitalArt

  • New Member
  • *
  • Posts: 26
Re: Problem with popup and panning
« Reply #3 on: May 25, 2016, 04:17:45 pm »
  Thank you for your quick responses! I have another question, though. I have two graphs on a form. They both use the same toolset and popup menu, but have different contents during runtime, therefore the content of popupmenu is different depending on which graph you click. I load the contents of the popup menu in OnPopup, reading the PopupComponent property. Previously this wasn't a problem, because AutoPopup took care of PopupComponent. Now that I'm calling PopupMenu manually, I understand that I have to also set PopupComponent manually in, say, ChartToolset1PanDragTool1AfterMouseUp. How can I determine which graph called the toolset from inside this method? Owner is set to the form, GetParentComponent returns nil. If it's impossible to do this, I think I'll have to have 2 different popupmenus and 2 different toolsets. Or maybe there's a method like Form.GetComponent(APoint: TPoint) that I can use?
  I'm sorry if this is maybe an obvious question, I'm relatively new to LCL, and I'd like to get to the bottom of this.
  I don't have time to compile another example right now, but you can get an idea of what I'm doing here: https://github.com/VitalyArtemiev/Generator-Amplifier-Control/blob/master/readingsf.pas

wp

  • Hero Member
  • *****
  • Posts: 11923
Re: Problem with popup and panning
« Reply #4 on: May 25, 2016, 04:42:48 pm »
Oh, I should have said explicitly that my solution works with AutoPopup left at true. Find a working demo with two charts sharing the same tools and the same popup menu in the attachment. One minor weakness, though: If a popup is open in one chart and you right-click on the other chart, the new popup does not open immediately, but requires a second right-click.

VitalArt

  • New Member
  • *
  • Posts: 26
Re: Problem with popup and panning
« Reply #5 on: May 25, 2016, 05:00:57 pm »
  Nevermind, I found a solution. Thanks for all your help!
Code: Pascal  [Select][+][-]
  1. procedure tReadingsForm.PanDragToolAfterMouseDown(ATool: TChartTool;
  2.   APoint: TPoint);
  3. begin
  4.   pmChart.AutoPopup:= true;
  5. end;
  6.  
  7. procedure tReadingsForm.PanDragToolAfterMouseMove(ATool: TChartTool;
  8.   APoint: TPoint);
  9. begin
  10.   pmChart.AutoPopup:= false;
  11. end;    

wp

  • Hero Member
  • *****
  • Posts: 11923
Re: Problem with popup and panning
« Reply #6 on: May 25, 2016, 05:02:37 pm »
I think it is not possible to solve this issue with keeping the built-in tools in place
I should not say "is not possible"...

In the new revision some changes were applied to the chart and the basic chart tools which finally avoid the popup menu to appear. It works with the built-in tools, and the OnContextPopup is not needed (but I'll keep it published, who knows...).

Please test. It works also for the two charts sharing the same toolset, and the dual-right-click-glitch mentioned in the previous post is gone as well.

BTW: A question to the experts out there: Is the right-mouse button used for the popupmenu in all operating systems?
« Last Edit: May 25, 2016, 05:07:34 pm by wp »

VitalArt

  • New Member
  • *
  • Posts: 26
Re: Problem with popup and panning
« Reply #7 on: May 25, 2016, 05:47:06 pm »
  I don't understand. Are you asking me to test your solution with the derived class? Or come back to this problem after a new Lazarus release? Either way I can only do that tomorrow.

wp

  • Hero Member
  • *****
  • Posts: 11923
Re: Problem with popup and panning
« Reply #8 on: May 25, 2016, 06:34:41 pm »
  I don't understand. Are you asking me to test your solution with the derived class? Or come back to this problem after a new Lazarus release?
When you install Lazarus from trunk you will have the new version immediately. Since it is more or less a bug fix I put it on the list with merge requests for Lazarus 1.6.2. But I don't know when this one will be released.

VitalArt

  • New Member
  • *
  • Posts: 26
Re: Problem with popup and panning
« Reply #9 on: May 27, 2016, 06:36:06 pm »
   I downloaded trunk and recompiled my original project, without custom tools or any crutches. Works as intended, with multiple charts and everything. Popup only activates if there was no pan, and you don't have to click an extra time to have the popup transfer from one chart to the other. Thank you again, I did not anticipate such a rapid response.

 

TinyPortal © 2005-2018