KiXforms Forum Index KiXforms
The Forum for the KiXforms Community
 
 FAQFAQ   SearchSearch   MemberlistMemberlist   UsergroupsUsergroups   RegisterRegister 
 ProfileProfile   Log in to check your private messagesLog in to check your private messages   Log inLog in 
 Quick Links 
Site News
Downloads
Documentation
Donations
Script Archive
Tracking Systems

ContextMenu on Treeview

 
Post new topic   Reply to topic    KiXforms Forum Index -> Discussion
View previous topic :: View next topic  
Author Message
benny69
KiXforms Advocate
KiXforms Advocate


Joined: 30 Oct 2003
Posts: 567
Location: Lincoln, Ne

PostPosted: Tue Feb 01, 2005 5:41 pm    Post subject: ContextMenu on Treeview Reply with quote

Shawn,
After all the discussions about ContextMenus I thought I would test it on the TreeView control. My thoughts behind this code is that you would be able to alter the content of the ContextMenu depending on the Node you right clicked on. To test this thought I decided to enable/disable one or another MenuItem. I started with the thought of the .show(control,X,Y) as you explained it. Here is the code with that thought in mind:

Code:
$System = CreateObject("Kixtart.System")

$root = $System.Form()
$form = $System.Form($root)
$form.size = 600,300
$form.Text = "Blank Form"
$form.center
$form.OnResize = "OnResize()"
$form.Icon = $System.BuiltinIcons(0)
$form.ShowInTaskBar = "False"

$NotifyIcon = $System.NotifyIcon()
$NotifyIcon.Icon = $form.Icon
$NotifyIcon.Visible = true
$NotifyIcon.OnMouseDown = "NotifyIconOnMouseDown()"
$NotifyIcon.OnDoubleClick = "OnDoubleClick()"

$NotifyIcon.ContextMenu = $System.ContextMenu()
$NotifyIcon.ContextMenu.Open = $NotifyIcon.ContextMenu.MenuItems.Add("Open")
$NotifyIcon.ContextMenu.Open.Onclick = "OnDoubleClick()"

$StatusBar = $Form.StatusBar()
$StatusBar.Dock = "Bottom"

$Treeview = $form.controls.treeview()
$Treeview.Dock = "Left"
$Treeview.ImageList = $System.BuiltinImageList()
$Treeview.ImageIndex = 45
$Treeview.SelectedImageIndex = 46
$Treeview.OnMouseDown = "OnMouseDown()"

$Treeview.ContextMenu = $System.ContextMenu()

$Treeview.ContextMenu.Expand = $Treeview.ContextMenu.MenuItems.Add("Expand")
$Treeview.ContextMenu.Expand.Visible = 1
$Treeview.ContextMenu.Expand.Enabled = true
$Treeview.ContextMenu.Expand.Onclick = "OnExpandClick()"

$Treeview.ContextMenu.Collapse = $Treeview.ContextMenu.MenuItems.Add("Collapse")
$Treeview.ContextMenu.Collapse.Visible = 1
$Treeview.ContextMenu.Collapse.Enabled = false
$Treeview.ContextMenu.Collapse.OnClick = "OnCollapseClick()"

$Node1 = $Treeview.Nodes.Add("Node 1")
$Node2 = $Treeview.Nodes.Add("Node 2")
$Node3 = $Treeview.Nodes.Add("Node 3")
$N1Child1 = $Node1.Nodes.Add("N1Child 1")
$N1Child2 = $Node1.Nodes.Add("N1Child 2")
$N1Child3 = $Node1.Nodes.Add("N1Child 3")
$N2Child1 = $Node2.Nodes.Add("N2Child 1")
$N2Child2 = $Node2.Nodes.Add("N2Child 2")
$N2Child3 = $Node2.Nodes.Add("N2Child 3")
$N3Child1 = $Node3.Nodes.Add("N3Child 1")
$N3Child2 = $Node3.Nodes.Add("N3Child 2")
$N3Child3 = $Node3.Nodes.Add("N3Child 3")
;$Node1.Expand()

$Listview = $Form.ListView()
$Listview.Dock = "left"
$Listview.SmallImageList = $System.BuiltinImageList

$= $Listview.Columns.Add("Child",100,$System.HorizontalAlignment.Left )

$ExitButton = $form.controls.button("Exit",$form.width-70,10,50,25)
$ExitButton.OnClick = "OnExit()"

$form.Show
$form.Running = 1
While $form.Running
   $=Execute($form.DoEvents())
Loop
Exit

Function NotifyIconOnMouseDown()
   If $NotifyIcon.ContextMenu.mousebutton = 2
      $NotifyIcon.ContextMenu.Show($NotifyIcon.ContextMenu.MouseX,$NotifyIcon.ContextMenu.MouseY)
   EndIf
EndFunction

Function OnDoubleClick()
   If Not $form.Visible Or $form.WindowState = $System.FormWindowState.Minimized
      $form.WindowState = $System.FormWindowState.Normal
      $form.Show()
      $form.Activate()
   Else
      $form.WindowState = $System.FormWindowState.Minimized
      $form.Hide()
   EndIf
EndFunction

Function OnResize()
   If $form.WindowState = $System.FormWindowState.Minimized
      $form.Hide()
   EndIf
EndFunction

Function OnExit()
   $Form.Running = 0
EndFunction

Function OnMouseDown()
   Dim $Node
   $Treeview.ContextMenu.Show($Treeview,$Treeview.MouseX,$Treeview.MouseY)
   $Treeview.BeingUpdate()
   $Node = $Treeview.EventNode
   If Not $Node Return EndIf
   $Treeview.SelectedNode = $Node
   $NodeState = $Treeview.EventNode.Expanded
   If $Treeview.EventNode.Expanded = 0
      $Treeview.ContextMenu.Expand.Enabled = true
      $Treeview.ContextMenu.Collapse.Enabled = false
   EndIf
   If $Treeview.EventNode.Expanded = -1
      $Treeview.ContextMenu.Expand.Enabled = false
      $Treeview.ContextMenu.Collapse.Enabled = true
   EndIf
   ? "OnMouseDown " + $Node.text + "," + $NodeState + "," + $Treeview.MouseButton
   ?
   $Treeview.EndUpdate()
   $Treeview.Refresh()
EndFunction

Function OnExpandClick()
   Dim $Node
   $Treeview.BeingUpdate()
   $Form.Cursor = $System.CursorStyle.WaitCursor
   $StatusBar.Text = "OnExpandClick Please wait..."
   $Node = $Treeview.EventNode
   $Treeview.SelectedNode = $Node
   If Not $Node Return EndIf
   $NodeState = $Treeview.EventNode.Expanded
   ? "Before Expand " + $Node.Text + "," + $NodeState + "," + $Treeview.MouseButton
   $Node.Expand()
   If $NodeState = 0
      $Treeview.ContextMenu.Expand.Enabled = true
      $Treeview.ContextMenu.Collapse.Enabled = false
   EndIf
   If $NodeState = -1
      $Treeview.ContextMenu.Expand.Enabled = false
      $Treeview.ContextMenu.Collapse.Enabled = true
   EndIf
   $NodeState = $Treeview.EventNode.Expanded
   ? "After Expand " + $Node.Text + "," + $NodeState + "," + $Treeview.MouseButton
   ?
   $Form.Cursor = $System.CursorStyle.Default
   $StatusBar.Text = ""
   $Treeview.EndUpdate()
   $Treeview.Refresh()
EndFunction

Function OnCollapseClick()
   Dim $Node
   $Treeview.BeingUpdate()
   $Form.Cursor = $System.CursorStyle.WaitCursor
   $StatusBar.Text = "OnCollapseClick Please wait..."
   $Node = $Treeview.EventNode
   $Treeview.SelectedNode = $Node
   If Not $Node Return EndIf
   $NodeState = $Treeview.EventNode.Expanded
   ? "Before Collapse " + $Node.Text + "," + $NodeState + "," + $Treeview.MouseButton
   $Node.Collapse()
   If $NodeState = 0
      $Treeview.ContextMenu.Expand.Enabled = true
      $Treeview.ContextMenu.Collapse.Enabled = false
   EndIf
   If $NodeState = -1
      $Treeview.ContextMenu.Expand.Enabled = false
      $Treeview.ContextMenu.Collapse.Enabled = true
   EndIf
   $NodeState = $Treeview.EventNode.Expanded
   ? "After Collapse " + $Node.Text + "," + $NodeState + "," + $Treeview.MouseButton
   ?
   $Form.Cursor = $System.CursorStyle.Default
   $StatusBar.Text = ""
   $Treeview.EndUpdate()
   $Treeview.Refresh()
EndFunction

As you probably already noticed, as I quickly did, I forgot that the TreeView control already had a context menu built in. Its kind of funny though that with this code you end up with two ContextMenus one after the other. In response to the results I simply rem'ed out this line of code:
Code:

$Treeview.ContextMenu.Show($Treeview,$Treeview.MouseX,$Treeview.MouseY)

located in the OnMouseDown Function. I then proceeded to see how the code responded. If you right click on a unexpanded node the ContextMenu should popup with Expand enabled and Collapse disabled, then click on Expand and the node should expand. Right click on Collapse,... bla,bla,bla you get the idea. This theory works as long as the node you right click on is the SelectedNode. If you right click on a node that is not the SelectedNode the ContextMenu comes up with the opposite state of the SelectedNode not the EventNode, if you click on Expand/Collapse it will Expand/Collapse the EventNode as it should. I also noticed that the OnMouseDown doesn't seem to register the .mousebutton click(no way to know what mouse button is being pressed), but it does execute the OnMouseDown function. There are a few other strange things going on but I am wondering if I am doing something wrong in the code, as well as the fact that I'm not sure if OnMouseDown is suppose to even exist in the TreeView control. I'm not sure, but if OnMouseDown isnít an option how would one control the ContextMenu with just the EventNode?
Run this code and tell me if there is a problem with my code and or the control/objects.

_________________
Wait don't order yet,... get KiXforms Designer .NET 2.0 (Beta)
KiXforms Designer .NET 2.0 (Beta)
Back to top
View user's profile Send private message Send e-mail
Shawn
KiXforms Developer
KiXforms Developer


Joined: 22 Feb 2003
Posts: 1983
Location: Canada

PostPosted: Tue Feb 01, 2005 6:43 pm    Post subject: Reply with quote

ja, I was mildly aware of the context-menu issue with treeview ... the crux of the issue is that the OnMouseDown event is being discarded because the context-menu is being displayed (the event is buried) ...

History ... up until recently, Kixforms could not respond to multiple events or multiple things happening at once ... its a limitation of Kixtart + Kixforms together really - but when I did Socket support - I started "queuing" events, and have yet to go back and queue-up events from the older controls.

ContextMenus in general were (and still are somewhat) experimental ... think I need to re-visit them ...

Let me make a few modifiations to the latest dev. build, to see if we can grow-up context-menus somewhat ... stay-tuned.
Back to top
View user's profile Send private message
Shawn
KiXforms Developer
KiXforms Developer


Joined: 22 Feb 2003
Posts: 1983
Location: Canada

PostPosted: Wed Feb 02, 2005 3:58 pm    Post subject: Reply with quote

ok, after digging quite deep - realized that there were a few problems with trapping mouse-events for the tree-view.

1) For some reason (and I verified this in .net), MouseDown's are mostly always followed by a MouseMove (idk why), and the MouseMove was wiping-out the MouseDown MouseButton property (because the Button for a mousemove is zero).

2) TreeView take special processing for a right mouse down event - TreeView enters a special modal-loop (to do with drag-drop) and basically doesn't release until after the next mouse-up (I've seen this before with other controls).

Anyways, I have made some rather drastic changes to the event-model in KF, but I think I have maintained backward-compat. What follows is the hand-jobbed approached to handling context-menu's for TreeViews (will be reviweing the other controls soon).

Basically ... in the OnMouseDown we get "the node at" the mouse coordinates ... if we have a node, we have to set it to the selected node, then show the context-menu ...

Heres is the code ... I will be making one more enhancement to ContextMenu that will make the code even shorter ... its a feature of the ContextMenuStrip found only in .NET Version 2. The ContextMenu will return the "index" of the selected menuitem, so one can process the click in the mouse-down (which i think is kinda neat) ...

There are some other enhancements to the script we should probably make, like checking if the node has children before show the menu etc. Plus, I need to emulate more closely, the TreeView behavior of simply high-lighting the right-clicked node, not selecting it.


Get yourself the lasest dev. build (46.19)

Code:

Break On

$System = CreateObject("Kixtart.System")

$Form = $System.Form()
$Form.Size = 640,480
$Form.Text = "Blank Form"
$Form.Center
$Form.Font = $System.Font("Verdana",10)

$StatusBar = $Form.StatusBar()
$StatusBar.Dock = "Bottom"

$Treeview = $Form.TreeView()
$Treeview.Dock = "Left"
$Treeview.ImageList = $System.BuiltinImageList()
$Treeview.ImageIndex = 45
$Treeview.SelectedImageIndex = 46
$Treeview.OnMouseDown = "TreeViewMouseDown()"

$Treeview.ContextMenu1 = $System.ContextMenu()

$Treeview.ContextMenu1.ExpandMenu = $Treeview.ContextMenu1.MenuItems.Add("Expand")
$Treeview.ContextMenu1.ExpandMenu.Visible = 1
$Treeview.ContextMenu1.ExpandMenu.Enabled = true
$Treeview.ContextMenu1.ExpandMenu.Onclick = "OnExpandClick()"

$Treeview.ContextMenu1.CollapseMenu = $Treeview.ContextMenu1.MenuItems.Add("Collapse")
$Treeview.ContextMenu1.CollapseMenu.Visible = 1
$Treeview.ContextMenu1.CollapseMenu.Enabled = false
$Treeview.ContextMenu1.CollapseMenu.OnClick = "OnCollapseClick()"

$ROOTCOUNT = 5
$CHILDCOUNT = 5

For $i = 0 to $ROOTCOUNT
 $RootNode = $TreeView.Nodes.Add("Node$i")
 For $j = 0 to $CHILDCOUNT
  $ChildNode = $RootNode.Nodes.Add("Child$j")
 Next
Next

$Listview = $Form.ListView()
$Listview.Dock = "Fill"
$Listview.SmallImageList = $System.BuiltinImageList

$= $Listview.Columns.Add("Child",100,$System.HorizontalAlignment.Left )

$Form.Show
While $Form.Visible
 $= Execute($Form.DoEvents())
Loop

Exit 0

Function TreeViewMouseDown()

 Dim $Node

 If Not ($TreeView.MouseButton & 2) ;; Not right-click ?
  Return
 Endif

 $Node = $TreeView.GetNodeAt($TreeView.MouseX, $TreeView.MouseY)

 If Not $Node
  Return
 Endif

 $TreeView.SelectedNode = $Node

 If $Node.Expanded = 0
  $Treeview.ContextMenu1.ExpandMenu.Enabled = true
  $Treeview.ContextMenu1.CollapseMenu.Enabled = false
 Else
  $Treeview.ContextMenu1.ExpandMenu.Enabled = false
  $Treeview.ContextMenu1.CollapseMenu.Enabled = true
 EndIf

 $= $TreeView.ContextMenu1.Show($TreeView, $TreeView.MouseX, $TreeView.MouseY)

EndFunction

Function OnExpandClick()

 If $TreeView.SelectedNode
  $TreeView.SelectedNode.Expand()
 Endif

EndFunction

Function OnCollapseClick()

 If $TreeView.SelectedNode
  $TreeView.SelectedNode.Collapse()
 Endif

EndFunction
Back to top
View user's profile Send private message
Display posts from previous:   
Post new topic   Reply to topic    KiXforms Forum Index -> Discussion All times are GMT
Page 1 of 1

 
Jump to:  
You cannot post new topics in this forum
You cannot reply to topics in this forum
You cannot edit your posts in this forum
You cannot delete your posts in this forum
You cannot vote in polls in this forum
You cannot attach files in this forum
You can download files in this forum


Powered by phpBB © 2001, 2005 phpBB Group