using System; using System.Collections; using System.ComponentModel; using System.ComponentModel.Design; using System.Drawing; using System.Windows.Forms; using System.Windows.Forms.Design; namespace DevComponents.Tree.Design { /// /// Represents windows forms designer for the control. /// public class TreeGXDesigner:ParentControlDesigner { #region Private Variables // private Point m_MouseDownPosition=Point.Empty; // private bool m_IgnoreMouseUp=false; // private bool m_Capture=false; private bool m_DragDropStarted=false; const string TEMP_NAME="tempDragDropItem"; const int WM_RBUTTONDOWN=0x0204; const int WM_LBUTTONDOWN=0x0201; // const int WM_LBUTTONUP=0x0202; // const int WM_RBUTTONUP=0x0205; // const int WM_MOUSEMOVE=0x0200; const int WM_LBUTTONDBLCLK=0x0203; private Timer m_TimerAdded=null; private Timer m_TimerDragDrop=null; private bool m_DragLeave=false; private bool m_ControlRemoved=false; private DateTime m_JustAdded=DateTime.MinValue; private bool m_NewControlAdded=false; private Point m_MouseDownPoint=Point.Empty; #endregion #region Designer Implementation /// Initializes designer with given component. /// Component to initialize designer with. public override void Initialize(IComponent component) { base.Initialize(component); if(!component.Site.DesignMode) return; ISelectionService ss =(ISelectionService)GetService(typeof(ISelectionService)); if(ss!=null) ss.SelectionChanged+=new EventHandler(OnSelectionChanged); // If our component is removed we need to clean-up IComponentChangeService cc=(IComponentChangeService)GetService(typeof(IComponentChangeService)); if(cc!=null) { cc.ComponentRemoving+=new ComponentEventHandler(this.OnComponentRemoving); } if(component is Control) { ((Control)component).ControlAdded+=new ControlEventHandler(this.ControlAdded); ((Control)component).ControlRemoved+=new ControlEventHandler(this.ControlRemoved); } #if !TRIAL IDesignerHost dh = this.GetService(typeof (IDesignerHost)) as IDesignerHost; if(dh!=null) dh.LoadComplete+=new EventHandler(dh_LoadComplete); #endif } protected override void Dispose(bool disposing) { ISelectionService ss =(ISelectionService)GetService(typeof(ISelectionService)); if(ss!=null) ss.SelectionChanged-=new EventHandler(OnSelectionChanged); // If our component is removed we need to clean-up IComponentChangeService cc=(IComponentChangeService)GetService(typeof(IComponentChangeService)); if(cc!=null) cc.ComponentRemoving-=new ComponentEventHandler(this.OnComponentRemoving); if(this.Control!=null) { this.Control.ControlAdded-=new ControlEventHandler(this.ControlAdded); this.Control.ControlRemoved-=new ControlEventHandler(this.ControlRemoved); } base.Dispose (disposing); } internal void HookControl(Control c) { this.HookChildControls(c); } // public override DesignerVerbCollection Verbs // { // get // { // DesignerVerb[] verbs = new DesignerVerb[] // { // new DesignerVerb("Create Node", new EventHandler(CreateNode))}; // return new DesignerVerbCollection(verbs); // } // } public override void InitializeNewComponent(IDictionary defaultValues) { base.InitializeNewComponent(defaultValues); SetDefaults(); } private void SetDefaults() { CreateNode(null,true); IDesignerHost dh=(IDesignerHost)GetService(typeof(IDesignerHost)); if(dh==null) return; Utilites.InitializeTree(this.Control as TreeGX,new ComponentFactory(dh)); #if !TRIAL string key=GetLicenseKey(); TreeGX tree=this.Control as TreeGX; tree.LicenseKey=key; #endif } private Node CreateNode(Node parentNode, bool addToCollections) { TreeGX tree=this.Control as TreeGX; IDesignerHost dh=(IDesignerHost)GetService(typeof(IDesignerHost)); if(dh==null) return null; Node node=null; tree.BeginUpdate(); try { IComponentChangeService change=this.GetService(typeof(IComponentChangeService)) as IComponentChangeService; if(addToCollections) { if(change!=null) { if(parentNode!=null) change.OnComponentChanging(this.Component,TypeDescriptor.GetProperties(parentNode).Find("Nodes",true)); else change.OnComponentChanging(this.Component,TypeDescriptor.GetProperties(tree).Find("Nodes",true)); } } node=dh.CreateComponent(typeof(Node)) as Node; if(node!=null) { node.Text=node.Name; node.Expanded = true; if(addToCollections) { if(parentNode==null) tree.Nodes.Add(node); else parentNode.Nodes.Add(node); if(change!=null) { if(parentNode!=null) change.OnComponentChanged(this.Component,TypeDescriptor.GetProperties(parentNode).Find("Nodes",true),null,null); else change.OnComponentChanged(this.Component,TypeDescriptor.GetProperties(tree).Find("Nodes",true),null,null); } } } } finally { tree.EndUpdate(); } return node; } private void OnSelectionChanged(object sender,EventArgs e) { ISelectionService ss = (ISelectionService)sender; if(ss.PrimarySelection==this.Component) { TreeGX tree=this.Control as TreeGX; tree.SelectedNode=null; } } /// Called when component is about to be removed from designer. /// Event sender. /// Event arguments. public void OnComponentRemoving(object sender,ComponentEventArgs e) { if(e.Component==this.Component) { IDesignerHost dh=(IDesignerHost)GetService(typeof(IDesignerHost)); if(dh==null) return; ArrayList list = new ArrayList(this.AssociatedComponents); foreach(IComponent c in list) dh.DestroyComponent(c); } else if(e.Component is Node && ((Node)e.Component).TreeControl==this.Control) { OnNodeRemoving(e.Component as Node); } } private void OnNodeRemoving(Node node) { IComponentChangeService cc=this.GetService(typeof(IComponentChangeService)) as IComponentChangeService; IDesignerHost dh=(IDesignerHost)GetService(typeof(IDesignerHost)); if(node.Parent!=null) { Node parent=node.Parent; if(cc!=null) cc.OnComponentChanging(parent,TypeDescriptor.GetProperties(parent)["Nodes"]); node.Remove(); if(cc!=null) cc.OnComponentChanged(parent,TypeDescriptor.GetProperties(parent)["Nodes"],null,null); } if(node.Nodes.Count>0) { Node[] nodes=new Node[node.Nodes.Count]; node.Nodes.CopyTo(nodes); foreach(Node n in nodes) { n.Remove(); if(n.ParentConnector!=null && dh!=null) dh.DestroyComponent(n.ParentConnector); if(dh!=null) dh.DestroyComponent(n); } } this.RecalcLayout(); } /// /// Returns all components associated with this control /// public override ICollection AssociatedComponents { get { ArrayList c=new ArrayList(base.AssociatedComponents); TreeGX tree=this.Control as TreeGX; if(tree!=null) { foreach(Node node in tree.Nodes) GetNodesRecursive(node,c); foreach(ElementStyle style in tree.Styles) c.Add(style); if(tree.NodesConnector!=null) c.Add(tree.NodesConnector); if(tree.RootConnector!=null) c.Add(tree.RootConnector); if(tree.LinkConnector!=null) c.Add(tree.LinkConnector); if(tree.SelectedPathConnector!=null) c.Add(tree.SelectedPathConnector); } return c; } } private void GetNodesRecursive(Node parent,ArrayList c) { c.Add(parent); if(parent.ParentConnector!=null) c.Add(parent.ParentConnector); foreach(Node node in parent.Nodes) { c.Add(node); if (node.Cells.Count > 1) { for (int i = 1; i < node.Cells.Count; i++) { c.Add(node.Cells[i]); } } if (node.NodesColumns.Count > 0) { foreach (ColumnHeader ch in node.NodesColumns) { c.Add(ch); } } GetNodesRecursive(node,c); } } /// /// Selection support for items on container. /// protected override void WndProc(ref Message m) { switch(m.Msg) { case WM_LBUTTONDOWN: { if(OnMouseDown(ref m,MouseButtons.Left)) return; break; } case WM_RBUTTONDOWN: { if(OnMouseDown(ref m,MouseButtons.Right)) return; break; } // case WM_LBUTTONUP: // { // if(OnMouseUp(ref m,MouseButtons.Left)) // return; // break; // } // case WM_RBUTTONUP: // { // if(OnMouseUp(ref m,MouseButtons.Right)) // return; // break; // } // case WM_MOUSEMOVE: // { // if(OnMouseMove(ref m)) // return; // break; // } case WM_LBUTTONDBLCLK: { if(OnMouseDoubleClick()) return; break; } } base.WndProc(ref m); } private bool OnMouseDoubleClick() { bool processed=false; ISelectionService selection = (ISelectionService) this.GetService(typeof(ISelectionService)); if(selection.PrimarySelection is Node && ((Node)selection.PrimarySelection).TreeControl==this.Control) { IDesignerHost host=(IDesignerHost) this.GetService(typeof(IDesignerHost)); if(host!=null) { IDesigner designer=host.GetDesigner(selection.PrimarySelection as IComponent); if(designer!=null) { designer.DoDefaultAction(); processed=true; } } } return processed; } protected virtual bool OnMouseDown(ref Message m, MouseButtons button) { TreeGX tree=this.Control as TreeGX; if(tree==null) return false; Point pos=tree.PointToClient(System.Windows.Forms.Control.MousePosition); //m_MouseDownPosition=pos; Node node=tree.GetNodeAt(pos); if(node!=null && button==MouseButtons.Right) { ISelectionService selection = (ISelectionService) this.GetService(typeof(ISelectionService)); ArrayList arr=new ArrayList(1); arr.Add(node); selection.SetSelectedComponents(arr,SelectionTypes.Primary); tree.SelectedNode=node; this.OnContextMenu(System.Windows.Forms.Control.MousePosition.X,System.Windows.Forms.Control.MousePosition.Y); return true; } return false; } /// Specifies selection rules for designer. public override SelectionRules SelectionRules { get { return (SelectionRules.AllSizeable | SelectionRules.Moveable | SelectionRules.Visible); } } #endregion #region Drag & Drop External Control Support private void DestroyComponent(IComponent c) { IDesignerHost dh=(IDesignerHost)GetService(typeof(IDesignerHost)); if(dh==null) return; dh.DestroyComponent(c); } private void RecalcLayout() { TreeGX tree = this.Control as TreeGX; if(tree!=null) { tree.RecalcLayout(); tree.Refresh(); } } private void ControlAdded(object sender, ControlEventArgs e) { if(!m_NewControlAdded) { if(!m_NewControlAdded) { if(!OnControlAdded(e)) return; } else return; } m_TimerAdded=new Timer(); m_TimerAdded.Tick+=new EventHandler(this.TimerTick); m_TimerAdded.Interval=50; m_TimerAdded.Enabled=true; m_TimerAdded.Start(); m_NewControlAdded=false; } /// /// Called after control has been added to container but not through drag & drop. Control added could also be /// internal control by the bar container. /// /// Event arguments /// true if acted upon this new control otherwise false. protected virtual bool OnControlAdded(ControlEventArgs e) { return false; } private void ControlRemoved(object sender, ControlEventArgs e) { IDesignerHost dh=(IDesignerHost)GetService(typeof(IDesignerHost)); if(dh==null || dh.Loading) return; if(m_JustAdded!=DateTime.MinValue && DateTime.Now.Subtract(m_JustAdded).Seconds<2) { m_JustAdded=DateTime.MinValue; return; } m_JustAdded=DateTime.MinValue; if(m_DragLeave) ControlRemoved(e.Control); else if(m_TimerDragDrop!=null) m_ControlRemoved=true; else { ISelectionService ss =(ISelectionService)GetService(typeof(ISelectionService)); if(ss!=null && ss.PrimarySelection==e.Control && Utilites.FindNodeForControl(this.Control as TreeGX, e.Control)!=null) { ControlRemoved(e.Control); } } } private void ControlRemoved(Control control) { TreeGX tree = this.Control as TreeGX; if(control!=null) { Node node=Utilites.FindNodeForControl(tree,control); if(node!=null) { if(m_DragDropStarted) { tree.InternalDragLeave(); m_DragDropStarted = false; } if(node.Parent!=null) { Node parent=node.Parent; IComponentChangeService cc = this.GetService(typeof (IComponentChangeService)) as IComponentChangeService; if(cc!=null) cc.OnComponentChanging(parent, TypeDescriptor.GetProperties(parent)["Nodes"]); node.Remove(); if(cc!=null) cc.OnComponentChanged(parent, TypeDescriptor.GetProperties(parent)["Nodes"],null,null); } this.DestroyComponent(node); this.RecalcLayout(); } } } private void TimerTick(object sender, EventArgs e) { m_TimerAdded.Stop(); m_TimerAdded.Enabled=false; m_TimerAdded=null; this.RecalcLayout(); ISelectionService sel=(ISelectionService)this.GetService(typeof(ISelectionService)); if(sel!=null && sel.PrimarySelection is Control && this.Control.Controls.Contains((Control)sel.PrimarySelection)) { IComponentChangeService cc=this.GetService(typeof(IComponentChangeService)) as IComponentChangeService; cc.OnComponentChanged(sel.PrimarySelection,null,null,null); } } private void TimerTickDragDrop(object sender, EventArgs e) { Point p=this.Control.PointToClient(System.Windows.Forms.Control.MousePosition); if(this.Control.Bounds.Contains(p)) m_DragLeave=false; else m_DragLeave=true; if(System.Windows.Forms.Control.MouseButtons!=MouseButtons.Left) { m_TimerDragDrop.Enabled=false; m_TimerDragDrop.Stop(); m_TimerDragDrop.Tick-=new EventHandler(TimerTickDragDrop); m_TimerDragDrop.Dispose(); m_TimerDragDrop=null; if(m_ControlRemoved) { m_ControlRemoved=false; ISelectionService sel=this.GetService(typeof(ISelectionService)) as ISelectionService; if(sel!=null && sel.PrimarySelection is Control) ControlRemoved((Control)sel.PrimarySelection); } } } protected override void OnDragLeave(EventArgs e) { if(m_DragDropStarted) { TreeGX tree=this.Control as TreeGX; tree.InternalDragLeave(); m_DragDropStarted = false; } base.OnDragLeave (e); } protected override void OnDragOver(DragEventArgs de) { TreeGX tree=this.Control as TreeGX; if(tree==null) { base.OnDragOver(de); return; } if(m_DragDropStarted) { DragEventArgs d=new DragEventArgs(null,de.KeyState,de.X,de.Y,DragDropEffects.All,DragDropEffects.Move); tree.InternalDragOver(d); de.Effect=DragDropEffects.Move; return; } ISelectionService sel=(ISelectionService)this.GetService(typeof(ISelectionService)); if(sel!=null && sel.PrimarySelection!=this.Component) { if(sel.PrimarySelection is Control && this.Control.Controls.Contains((Control)sel.PrimarySelection)) { Node node=Utilites.FindNodeForControl(tree,sel.PrimarySelection as Control); if(node!=null) { if(tree.StartDragDrop(node)) { if(m_TimerDragDrop==null) { m_TimerDragDrop=new Timer(); m_TimerDragDrop.Tick+=new EventHandler(this.TimerTickDragDrop); m_TimerDragDrop.Interval=100; m_TimerDragDrop.Enabled=true; m_TimerDragDrop.Start(); } m_DragDropStarted = true; } } return; } else if(sel.SelectionCount>1) { de.Effect=DragDropEffects.None; return; } else if(sel.PrimarySelection is Control && ((Control)sel.PrimarySelection).Parent!=null) { // New control being added to the container Node node=new Node(); node.Name=TEMP_NAME; node.Text = ((Control) sel.PrimarySelection).Name; if(tree.StartDragDrop(node)) m_DragDropStarted = true; } } base.OnDragOver (de); } protected override void OnDragDrop(DragEventArgs de) { TreeGX tree=this.Control as TreeGX; if(tree==null) { base.OnDragDrop(de); return; } ISelectionService sel=(ISelectionService)this.GetService(typeof(ISelectionService)); if(sel!=null && sel.PrimarySelection is Control && this.Control.Controls.Contains((Control)sel.PrimarySelection)) { de.Effect=DragDropEffects.Move; tree.InternalDragDrop(new DragEventArgs(null,0,0,0,DragDropEffects.Move,DragDropEffects.All)); } else { if(sel.SelectionCount>1) { de.Effect=DragDropEffects.None; return; } else { Node node = tree.GetDragNode(); if(node!=null && node.Tag is Node && ((Node)node.Tag).Name==TEMP_NAME) { m_JustAdded=DateTime.Now; Node dragNode=CreateNode(null,false); TypeDescriptor.GetProperties(dragNode)["HostedControl"].SetValue(dragNode,sel.PrimarySelection as Control); TypeDescriptor.GetProperties(dragNode)["Text"].SetValue(dragNode,dragNode.HostedControl.Name); node.Tag = dragNode; tree.InternalDragDrop(new DragEventArgs(null,0,0,0,DragDropEffects.Move,DragDropEffects.All)); m_NewControlAdded=true; m_DragDropStarted = false; } } } base.OnDragDrop(de); } #endregion #region Drag & Drop support /// /// Called after node has been selected by designer as response to mouse action /// /// Node that is selected protected virtual void OnNodeSelected(Node node) { } /// /// Returns whether specified node can be dragged and dropped /// /// Node to verify /// true if node can be dragged and dropped protected virtual bool CanDragNode(Node node) { return true; } protected override void OnMouseDragBegin(int x, int y) { TreeGX tree=this.Control as TreeGX; if(tree==null) { base.OnMouseDragBegin(x,y); return; } Point pos=tree.PointToClient(new Point(x,y)); Node node = tree.GetNodeAt(pos); if(node!=null) { Rectangle expandedRect=Display.NodeDisplay.GetNodeRectangle(eNodeRectanglePart.ExpandBounds,node,tree.NodeDisplay.Offset); if(!expandedRect.IsEmpty && expandedRect.Contains(pos)) { node.Expanded=!node.Expanded; return; } ISelectionService selection = (ISelectionService) this.GetService(typeof(ISelectionService)); if(selection!=null) { ArrayList arr=new ArrayList(1); arr.Add(node); selection.SetSelectedComponents(arr,SelectionTypes.Primary); OnNodeSelected(node); } tree.SelectedNode = node; } else tree.SelectedNode = null; if(node==null || !CanDragNode(node)) { if(node==null) base.OnMouseDragBegin(x,y); else this.Control.Capture = true; // Does same as base implementation return; } m_MouseDownPoint=new Point(x,y); this.Control.Capture = true; } protected override void OnMouseDragMove(int x, int y) { TreeGX tree=this.Control as TreeGX; if(!m_MouseDownPoint.IsEmpty && tree.SelectedNode!=null) { if(Math.Abs(m_MouseDownPoint.X-x)>=SystemInformation.DragSize.Width || Math.Abs(m_MouseDownPoint.Y-y)>=SystemInformation.DragSize.Height) { tree.StartDragDrop(tree.SelectedNode); m_MouseDownPoint=Point.Empty; m_DragDropStarted=true; return; } } if(m_DragDropStarted) { DragEventArgs de=new DragEventArgs(null,(int)Control.ModifierKeys,x,y,DragDropEffects.All,DragDropEffects.Move); tree.InternalDragOver(de); } } protected override void OnMouseDragEnd(bool cancel) { this.Control.Capture = false; Cursor.Clip = Rectangle.Empty; TreeGX tree=this.Control as TreeGX; if(m_DragDropStarted) { if(tree!=null && tree.IsDragDropInProgress) { if(cancel) tree.InternalDragLeave(); else if(tree.GetDragNode()!=null) { IComponentChangeService change=this.GetService(typeof(IComponentChangeService)) as IComponentChangeService; Node dragNode=tree.GetDragNode().Tag as Node; if(dragNode!=null) { Node newParent=tree.GetDragNode().Parent; Node parent=dragNode.Parent; if(change!=null) { if(parent!=null) change.OnComponentChanging(this.Component,TypeDescriptor.GetProperties(parent).Find("Nodes",true)); else change.OnComponentChanging(this.Component,TypeDescriptor.GetProperties(tree).Find("Nodes",true)); if(newParent!=null) change.OnComponentChanging(this.Component,TypeDescriptor.GetProperties(newParent).Find("Nodes",true)); else change.OnComponentChanging(this.Component,TypeDescriptor.GetProperties(tree).Find("Nodes",true)); } tree.InternalDragDrop(new DragEventArgs(null,0,0,0,DragDropEffects.None,DragDropEffects.None)); newParent = dragNode.Parent; if(change!=null) { if(parent!=null) change.OnComponentChanged(this.Component,TypeDescriptor.GetProperties(parent).Find("Nodes",true),null,null); else change.OnComponentChanged(this.Component,TypeDescriptor.GetProperties(tree).Find("Nodes",true),null,null); if(newParent!=null) change.OnComponentChanged(this.Component,TypeDescriptor.GetProperties(newParent).Find("Nodes",true),null,null); else change.OnComponentChanged(this.Component,TypeDescriptor.GetProperties(tree).Find("Nodes",true),null,null); } } } } cancel=true; } else { if(tree.SelectedNode!=null) cancel=true; } m_DragDropStarted = false; base.OnMouseDragEnd(cancel); } #endregion #region Licensing Stuff #if !TRIAL private string GetLicenseKey() { string key=""; Microsoft.Win32.RegistryKey regkey=Microsoft.Win32.Registry.LocalMachine; regkey=regkey.OpenSubKey("Software\\DevComponents\\Licenses",false); if(regkey!=null) { object keyValue=regkey.GetValue("DevComponents.Tree.TreeGX"); if(keyValue!=null) key=keyValue.ToString(); } return key; } private void dh_LoadComplete(object sender, EventArgs e) { IDesignerHost dh = this.GetService(typeof (IDesignerHost)) as IDesignerHost; if(dh!=null) dh.LoadComplete-=new EventHandler(dh_LoadComplete); string key=GetLicenseKey(); TreeGX tree=this.Control as TreeGX; if(key!="" && tree!=null && tree.LicenseKey=="" && tree.LicenseKey!=key) TypeDescriptor.GetProperties(tree)["LicenseKey"].SetValue(tree,key); } #endif #endregion } }