* * *

Author Topic: Detect mouse position in Virtual Tree View  (Read 443 times)

Tommi

  • Full Member
  • ***
  • Posts: 171
Detect mouse position in Virtual Tree View
« on: May 13, 2018, 08:21:43 am »
As you can see in attached figure I would need to create hyperlink in virtualTreeView.

To do this I need to detect in which position is the mouse respect to the content, not respecto to the width of the control.

My idea is to use OnMouseMove event to see if it is on an hyperlink and so change the mouse icon with an image of an hand. (Like in Internet Explorer or Firefox). At that point I should detect the click.

But if I use onMouseEvent I just obtain coordinates relative to the upper-left corner.

Zoran

  • Hero Member
  • *****
  • Posts: 1220
    • http://wiki.lazarus.freepascal.org/User:Zoran
Re: Detect mouse position in Virtual Tree View
« Reply #1 on: May 13, 2018, 08:47:56 am »
This should get the tree node the mouse is on:

Code: Pascal  [Select]
  1. var
  2.   TN: TTreeNode;
  3.   P: TPoint;
  4. begin
  5.   P := TreeView1.ScreenToClient(Mouse.CursorPos);
  6.   TN := GetNodeAt(P.x, P.y);
  7.   if Assigned(TN) then begin
  8.     ...
  9.  

Edit: Now I see you are talking about VirtualTreeView. My code is for TreeView, I have never used VirtualTreeView, I hope this can be of help anyway.
« Last Edit: May 13, 2018, 08:52:41 am by Zoran »

wp

  • Hero Member
  • *****
  • Posts: 4486
Re: Detect mouse position in Virtual Tree View
« Reply #2 on: May 13, 2018, 10:46:04 am »
See the following excerpt from the VT sources:
Code: Pascal  [Select]
  1. type
  2.   THitPosition = (
  3.     hiAbove,             // above the client area (if relative) or the absolute tree area
  4.     hiBelow,             // below the client area (if relative) or the absolute tree area
  5.     hiNowhere,           // no node is involved (possible only if the tree is not as tall as the client area)
  6.     hiOnItem,            // on the bitmaps/buttons or label associated with an item
  7.     hiOnItemButton,      // on the button associated with an item
  8.     hiOnItemButtonExact, // exactly on the button associated with an item
  9.     hiOnItemCheckbox,    // on the checkbox if enabled
  10.     hiOnItemIndent,      // in the indentation area in front of a node
  11.     hiOnItemLabel,       // on the normal text area associated with an item
  12.     hiOnItemLeft,        // in the area to the left of a node's text area (e.g. when right aligned or centered)
  13.     hiOnItemRight,       // in the area to the right of a node's text area (e.g. if left aligned or centered)
  14.     hiOnNormalIcon,      // on the "normal" image
  15.     hiOnStateIcon,       // on the state image
  16.     hiToLeft,            // to the left of the client area (if relative) or the absolute tree area
  17.     hiToRight,           // to the right of the client area (if relative) or the absolute tree area
  18.     hiUpperSplitter,     // in the upper splitter area of a node
  19.     hiLowerSplitter      // in the lower splitter area of a node
  20.   );
  21.   THitPositions = set of THitPosition;
  22.  
  23.   THitInfo = record
  24.     HitNode: PVirtualNode;
  25.     HitPositions: THitPositions;
  26.     HitColumn: TColumnIndex;
  27.     HitPoint: TPoint;
  28.   end;
  29.  
  30. type
  31.   TBaseVirtualTree = class(TCustomControl)
  32.     ...
  33.     procedure GetHitTestInfoAt(X, Y: Integer; Relative: Boolean; var HitInfo: THitInfo); virtual;

This means that you could try this (untested):
Code: Pascal  [Select]
  1. function NodeUnderMouse(VT: TBaseVirtualTree; x, y: Integer): PVirtualNode;
  2. var
  3.   hitinfo: THitInfo;
  4. begin
  5.   Result := nil;
  6.   if VT <> nil then begin
  7.     VT.GetHitTestInfoAt(x, y, true, hitinfo);
  8.     if htOnItem in hitInfo.HitPositions then
  9.       Result := hitinfo.HitNode;
  10.   end;
  11. end;

Alternatively you can enable toHotTrack in the PaintOptions then the node underneath the mouse will be accessible via property HotNode.

I've got this information from https://github.com/Virtual-TreeView/Virtual-TreeView/blob/master/Help/VirtualTreeview.chm. There is also a virtualtreeview.pdf - google for it.
« Last Edit: May 13, 2018, 10:59:24 am by wp »
Lazarus trunk / fpc 3.0.4 / all 32-bit on Win-10

Tommi

  • Full Member
  • ***
  • Posts: 171
Re: Detect mouse position in Virtual Tree View
« Reply #3 on: May 13, 2018, 04:53:08 pm »
Thank you.

your code works (there's a sintax error: hiOnItem and not htOnItem ), any way it cannot give an uniquely determinate coordinate of the string under the mouse.

If I read hitinfo.HitPoint I receive unuseful coordinates.

wp

  • Hero Member
  • *****
  • Posts: 4486
Re: Detect mouse position in Virtual Tree View
« Reply #4 on: May 13, 2018, 05:59:02 pm »
Once you know the node underneath the mouse you can call GetDisplayRect to determine the rectangle covered by the node. If you subtract the top/left coordinates of this rectangle from the mouse coordinates (relative to the treeview) you get the coordinates relative to the node. And from the text layout in the cell - which VTV does not know - you can determine the word underneath the mouse. This appears to me to be the toughest step...

Here's the signature of the function GetDisplayRect along with the comments which can be found in the VTV sources:
Code: Pascal  [Select]
  1. function TBaseVirtualTree.GetDisplayRect(Node: PVirtualNode; Column: TColumnIndex; TextOnly: Boolean;
  2.   Unclipped: Boolean = False; ApplyCellContentMargin: Boolean = False): TRect;
  3.  
  4. // Determines the client coordinates the given node covers, depending on scrolling, expand state etc.
  5. // If the given node cannot be found (because one of its parents is collapsed or it is invisible) then an empty
  6. // rectangle is returned.
  7. // If TextOnly is True then only the text bounds are returned, that is, the resulting rectangle's left and right border
  8. // are updated according to bidi mode, alignment and text width of the node.
  9. // If Unclipped is True (which only makes sense if also TextOnly is True) then the calculated text rectangle is
  10. // not clipped if the text does not entirely fit into the text space. This is special handling needed for hints.
  11. // If ApplyCellContentMargin is True (which only makes sense if also TextOnly is True) then the calculated text
  12. // rectangle respects the cell content margin.
  13. // If Column is -1 then the entire client width is used before determining the node's width otherwise the bounds of the
  14. // particular column are used.
  15. // Note: Column must be a valid column and is used independent of whether the header is visible or not.
                                                                                                       
Lazarus trunk / fpc 3.0.4 / all 32-bit on Win-10

Tommi

  • Full Member
  • ***
  • Posts: 171
Re: Detect mouse position in Virtual Tree View
« Reply #5 on: May 14, 2018, 07:14:56 pm »
I am going to try. Thank you.

 

Recent

Get Lazarus at SourceForge.net. Fast, secure and Free Open Source software downloads Open Hub project report for Lazarus