示例#1
0
        private bool FindTabPageCollection(
            TabGroupSequence nodeGroup,
            Crownwood.DotNetMagic.Controls.TabPage tabPage,
            out TabPageCollection containingCollection)
        {
            for (var i = 0; i < nodeGroup.Count; i++)
            {
                var node = nodeGroup[i];

                if (node.IsSequence)
                {
                    var found = FindTabPageCollection(node as TabGroupSequence, tabPage, out containingCollection);

                    if (found)
                    {
                        return(true);
                    }
                }

                if (node.IsLeaf)
                {
                    var leaf = (TabGroupLeaf)node;
                    if (leaf.TabPages.Contains(tabPage))
                    {
                        containingCollection = leaf.TabPages;
                        return(true);
                    }
                }
            }

            containingCollection = null;
            return(false);
        }
示例#2
0
		internal void GroupRemoved(TabGroupBase tgb) {
			// Only modify leaf count when not suspended
			if (_suspendLeafCount == 0) {
				// Decrease count of leafs entries for each leaf that exists
				// which in the hierarchy that is being removed
                
				if (tgb.IsLeaf) {
					_numLeafs--;

					// Was last leaf removed?
					if (_numLeafs == 0) {
						// If at least one leaf then set the value manually so that when the
						// new one is created and set as active it does not try to process the
						// old value that has already been destroyed.
						if (_atLeastOneLeaf) {
							// Need to get rid of active leaf value
							ActiveLeaf = null;
						}
					}
				}
				else {
					TabGroupSequence tgs = tgb as TabGroupSequence;
                
					// Recurse into processing each child item
					for(int i=0; i<tgs.Count; i++)
						GroupRemoved(tgs[i]);
				}
                
				// Mark layout as dirty
				if (_autoCalculateDirty)
					_dirty = true;
			}
		}
示例#3
0
		protected void InternalConstruct(VisualStyle style) {
			// Prevent flicker with double buffering and all painting inside WM_PAINT
			SetStyle(ControlStyles.DoubleBuffer | 
				ControlStyles.AllPaintingInWmPaint |
				ControlStyles.UserPaint, true);
		
			// We want to act as a drop target
			this.AllowDrop = true;
		
			// Remember parameters
			_style = style;
		    
			// Define initial state
			_numLeafs = 0;
			_compacting = false;
			_initializing = false;
			_suspendLeafCount = 0;
		    
			// Create the root sequence that always exists
			_root = new TabGroupSequence(this);
		    
			// Define default settings
			ResetProminentLeaf();
			ResetResizeBarVector();
			ResetResizeBarColor();
			ResetResizeBarLock();
			ResetLayoutLock();
			ResetCompactOptions();
			ResetDefaultGroupMinimumWidth();
			ResetDefaultGroupMinimumHeight();
			ResetActiveLeaf();
			ResetAutoCompact();
			ResetAtLeastOneLeaf();
			ResetCloseMenuText();
			ResetProminentMenuText();
			ResetRebalanceMenuText();
			ResetMovePreviousMenuText();
			ResetMoveNextMenuText();
			ResetNewVerticalMenuText();
			ResetNewHorizontalMenuText();
			ResetCloseShortcut();
			ResetProminentShortcut();
			ResetRebalanceShortcut();
			ResetMovePreviousShortcut();
			ResetMoveNextShortcut();
			ResetSplitVerticalShortcut();
			ResetSplitHorizontalShortcut();
			ResetImageList();
			ResetDisplayTabMode();
			ResetSaveControls();
			ResetAutoCalculateDirty();
			ResetDirty();
			ResetPageCloseWhenEmpty();
            
			// Add ourself to the application filtering list 
			// (to snoop for shortcut combinations)
			Application.AddMessageFilter(this);
            
		}
示例#4
0
		public TabGroupLeaf PreviousLeaf(TabGroupLeaf current) {
			// Get parent of the provided leaf
			TabGroupSequence tgs = current.Parent as TabGroupSequence;
            
			// Must have a valid parent sequence
			if (tgs != null)
				return RecursiveFindLeafInSequence(tgs, current, false);
			else
				return null;
		}
示例#5
0
        internal void NewHorizontalGroup(TabGroupLeaf sourceLeaf, bool before)
        {
            TabGroupSequence tgs = this.Parent as TabGroupSequence;

            // We must have a parent sequence!
            if (tgs != null)
            {
                tgs.Direction = Direction.Horizontal;
                AddGroupToSequence(tgs, sourceLeaf, before);
            }
        }
示例#6
0
        /// <summary>
        /// Set the Space of this item so it occupies the specified number of pixels, if possible.
        /// </summary>
        /// <param name="pixelSize">Pixel length requested.</param>
        public void SetPixelLength(int pixelSize)
        {
            // Must use parent sequence to actually perform operation
            if (_parent != null)
            {
                // Parent must always be a sequence
                TabGroupSequence tgs = _parent as TabGroupSequence;

                // Resizing this object is requires knowledge of other siblings
                tgs.SetPixelLengthOfChild(this, pixelSize);
            }
        }
示例#7
0
        internal static void DebugStructure(TabGroupSequence tgs, int indent)
        {
            int parentId = -1;

            if (tgs.Parent != null)
            {
                parentId = tgs.Parent.Unique;
            }

            Decimal total = 0;

            for (int l = 0; l < tgs.Count; l++)
            {
                total += tgs[l].Space;
            }

            for (int k = 0; k < indent; k++)
            {
                Console.Write(" ");
            }

            Console.WriteLine("Sequence({0}) %:{1} ID:{2} P:{3} nChild:{4} Dir:{5}",
                              total, tgs.Space, tgs.Unique, parentId, tgs.Count, tgs.Direction);

            indent++;

            for (int i = 0; i < tgs.Count; i++)
            {
                TabGroupBase tgb = tgs[i];

                if (tgb is TabGroupSequence)
                {
                    DebugStructure(tgb as TabGroupSequence, indent);
                }
                else
                {
                    if (tgb.Parent != null)
                    {
                        parentId = tgb.Parent.Unique;
                    }

                    for (int j = 0; j < indent; j++)
                    {
                        Console.Write(" ");
                    }

                    Console.WriteLine("Leaf %:{0} ID:{1} P:{2} nChild:{3}",
                                      tgb.Space, tgb.Unique, parentId, (tgb.GroupControl as TabControl).TabPages.Count);
                }
            }
        }
示例#8
0
        protected void AddGroupToSequence(TabGroupSequence tgs, TabGroupLeaf sourceLeaf, bool before)
        {
            // Remember original auto compact mode
            bool autoCompact = _tabbedGroups.AutoCompact;

            // Turn mode off as it interferes with reorganisation
            _tabbedGroups.AutoCompact = false;

            // Find our index into parent collection
            int pos = tgs.IndexOf(this);

            TabGroupLeaf newGroup = null;

            // New group inserted before existing one?
            if (before)
            {
                newGroup = tgs.InsertNewLeaf(pos);
            }
            else
            {
                // No, are we at the end of the collection?
                if (pos == (tgs.Count - 1))
                {
                    newGroup = tgs.AddNewLeaf();
                }
                else
                {
                    newGroup = tgs.InsertNewLeaf(pos + 1);
                }
            }

            // Get tab control for source leaf
            Controls.TabControl tc = sourceLeaf.GroupControl as Controls.TabControl;

            TabPage tp = tc.SelectedTab;

            // Remove page from ourself
            tc.TabPages.Remove(tp);

            // Add into the new leaf
            newGroup.TabPages.Add(tp);

            // Reset compacting mode as we have updated the structure
            _tabbedGroups.AutoCompact = autoCompact;

            // Do we need to compact?
            if (_tabbedGroups.AutoCompact)
            {
                _tabbedGroups.Compact();
            }
        }
示例#9
0
		internal void MoveActiveToNearestFromLeaf(TabGroupBase oldLeaf) {
			// Must have a reference to begin movement
			if (oldLeaf != null) {
				// Find the parent sequence of leaf, remember that a 
				// leaf must be contained within a sequence instance
				TabGroupSequence tgs = oldLeaf.Parent as TabGroupSequence;
                
				// Must be valid, but had better check anyway
				if (tgs != null) {
					// Move relative to given base in the sequence
					MoveActiveInSequence(tgs, oldLeaf);
				}
			}
		}
示例#10
0
		internal void MoveActiveToNearestFromSequence(TabGroupSequence tgs) {
			// Is active leaf being moved from root sequence
			if (_root == tgs) {
				// Then make nothing active
				ActiveLeaf = null;
			}
			else {
				// Find the parent sequence of given sequence
				TabGroupSequence tgsParent = tgs.Parent as TabGroupSequence;
            
				// Must be valid, but had better check anyway
				if (tgs != null) {
					// Move relative to given base in the sequence
					MoveActiveInSequence(tgsParent, tgs);
				}
			}
		}
示例#11
0
		protected TabGroupLeaf RecursiveFindLeafInSequence(TabGroupSequence tgs, bool forwards) {
			int count = tgs.Count;
        
			for(int i=0; i<count; i++) {
				// Index depends on which direction we are processing
				int index = (forwards == true) ? i : (tgs.Count - i - 1);
                
				// Is this the needed leaf node?
				if (tgs[index].IsLeaf)
					return tgs[index] as TabGroupLeaf;
				else {
					// Need to make a recursive check inside group
					TabGroupLeaf leaf = RecursiveFindLeafInSequence(tgs[index] as TabGroupSequence, forwards);

					if (leaf != null)
						return leaf;
				}
			}
            
			// Still no luck
			return null;
		}
示例#12
0
		protected TabGroupLeaf RecursiveFindLeafInSequence(TabGroupSequence tgs, TabGroupBase tgb, bool forwards) {
			int count = tgs.Count;
			int index = tgs.IndexOf(tgb);
        
			// Are we look for entries after the provided one?
			if (forwards) {
				for(int i=index+1; i<count; i++) {
					// Is this the needed leaf node?
					if (tgs[i].IsLeaf)
						return tgs[i] as TabGroupLeaf;
					else {
						TabGroupLeaf leaf = RecursiveFindLeafInSequence(tgs[i] as TabGroupSequence, forwards);
                    
						if (leaf != null)
							return leaf;
					}
				}
			}
			else {
				// Now try each entry before that given
				for(int i=index-1; i>=0; i--) {
					// Is this the needed leaf node?
					if (tgs[i].IsLeaf)
						return tgs[i] as TabGroupLeaf;
					else {
						TabGroupLeaf leaf = RecursiveFindLeafInSequence(tgs[i] as TabGroupSequence, forwards);
                    
						if (leaf != null)
							return leaf;
					}
				}
			}
                        
			// Still no luck, try our own parent
			if (tgs.Parent != null)
				return RecursiveFindLeafInSequence(tgs.Parent as TabGroupSequence, tgs, forwards);
			else
				return null;
		}
示例#13
0
		protected void MoveActiveInSequence(TabGroupSequence tgs, TabGroupBase child) {
			int count = tgs.Count;
			int index = tgs.IndexOf(child);
        
			// First try each entry after that given
			for(int i=index+1; i<count; i++) {
				// Is this the needed leaf node?
				if (tgs[i].IsLeaf) {
					// Make it active, and finish
					ActiveLeaf = tgs[i] as TabGroupLeaf;
					return;  
				}
				else {
					// Need to make a recursive check inside group
					if (RecursiveActiveInSequence(tgs[i] as TabGroupSequence, true))
						return;
				}
			}
            
			// Now try each entry before that given
			for(int i=index-1; i>=0; i--) {
				// Is this the needed leaf node?
				if (tgs[i].IsLeaf) {
					// Make it active, and finish
					ActiveLeaf = tgs[i] as TabGroupLeaf;
					return;  
				}
				else {
					// Need to make a recursive check inside group
					if (RecursiveActiveInSequence(tgs[i] as TabGroupSequence, false))
						return;
				}
			}
            
			// Still no luck, try our own parent
			if (tgs.Parent != null)
				MoveActiveInSequence(tgs.Parent as TabGroupSequence, tgs);
		}
示例#14
0
        internal static void DebugSpace(TabGroupSequence tgs)
        {
            Decimal total = 0;

            for (int l = 0; l < tgs.Count; l++)
            {
                total += tgs[l].Space;
            }

            if ((total != 100m) && (total != 0m))
            {
                Console.WriteLine("** ERROR ** Inaccurate Space = {0}", total);

                for (int l = 0; l < tgs.Count; l++)
                {
                    Console.WriteLine("Base %:{0} ID:{1}", tgs[l].Space, tgs[l].Unique);
                }

                Console.WriteLine("");

                System.Diagnostics.Debug.Assert(false);
            }
        }
示例#15
0
		protected bool RecursiveActiveInSequence(TabGroupSequence tgs, bool forwards) {
			int count = tgs.Count;
        
			for(int i=0; i<count; i++) {
				// Index depends on which direction we are processing
				int index = (forwards == true) ? i : (tgs.Count - i - 1);
                
				// Is this the needed leaf node?
				if (tgs[index].IsLeaf) {
					// Make it active, and finish
					ActiveLeaf = tgs[index] as TabGroupLeaf;
					return true;
				}
				else {
					// Need to make a recursive check inside group
					if (RecursiveActiveInSequence(tgs[index] as TabGroupSequence, forwards))
						return true;
				}
			}
            
			// Still no luck
			return false;
		}
示例#16
0
		internal void SetRootSequence(TabGroupSequence tgs) {
			// Use the new sequence as the root
			_root = tgs;
		}
示例#17
0
 internal static void DebugStruct(TabGroupSequence tgs, string title)
 {
     Console.WriteLine("Structure {0}", title);
     DebugStructure(tgs, 0);
     Console.WriteLine("");
 }
示例#18
0
        protected void OnPopupMenuDisplay(object sender, CancelEventArgs e)
        {
            // Remove all existing menu items
            _tabControl.ContextPopupMenu.MenuCommands.Clear();

            // Add our standard set of menus
            _tabControl.ContextPopupMenu.MenuCommands.AddRange(new MenuCommand[] { _mcClose, _mcSep1,
                                                                                   _mcProm, _mcReba,
                                                                                   _mcSep2, _mcHorz,
                                                                                   _mcVert, _mcNext,
                                                                                   _mcPrev });
            if (!_tabbedGroups.LayoutLock)
            {
                // Are any pages selected
                bool valid = (_tabControl.SelectedIndex != -1);

                // Define the latest text string
                _mcClose.Text = _tabbedGroups.CloseMenuText;
                _mcProm.Text  = _tabbedGroups.ProminentMenuText;
                _mcReba.Text  = _tabbedGroups.RebalanceMenuText;
                _mcPrev.Text  = _tabbedGroups.MovePreviousMenuText;
                _mcNext.Text  = _tabbedGroups.MoveNextMenuText;
                _mcVert.Text  = _tabbedGroups.NewVerticalMenuText;
                _mcHorz.Text  = _tabbedGroups.NewHorizontalMenuText;

                // Only need to close option if the tab has close defined
                _mcClose.Visible = _tabControl.ShowClose && valid;
                _mcSep1.Visible  = _tabControl.ShowClose && valid;

                // Update the radio button for prominent
                _mcProm.Checked = (_tabbedGroups.ProminentLeaf == this);

                // Can only create new group if at least two pages exist
                bool split = valid && (_tabControl.TabPages.Count > 1);

                bool vertSplit = split;
                bool horzSplit = split;

                TabGroupSequence tgs = _parent as TabGroupSequence;

                // If we are not the only leaf, then can only split in
                // the same direction as the group we are in
                if (tgs.Count > 1)
                {
                    if (tgs.Direction == Direction.Vertical)
                    {
                        vertSplit = false;
                    }
                    else
                    {
                        horzSplit = false;
                    }
                }

                _mcVert.Visible = vertSplit;
                _mcHorz.Visible = horzSplit;

                // Can only how movement if group exists in that direction
                _mcNext.Visible = valid && (_tabbedGroups.NextLeaf(this) != null);
                _mcPrev.Visible = valid && (_tabbedGroups.PreviousLeaf(this) != null);
                _mcSep2.Visible = _mcNext.Visible | _mcPrev.Visible | vertSplit | horzSplit;
            }
            else
            {
                // Make sure that none of the menu commands are visible
                _mcClose.Visible = false;
                _mcProm.Visible  = false;
                _mcReba.Visible  = false;
                _mcPrev.Visible  = false;
                _mcNext.Visible  = false;
                _mcVert.Visible  = false;
                _mcHorz.Visible  = false;
                _mcSep1.Visible  = false;
                _mcSep2.Visible  = false;
            }

            TGContextMenuEventArgs tge = new TGContextMenuEventArgs(this,
                                                                    _tabControl,
                                                                    _tabControl.SelectedTab,
                                                                    _tabControl.ContextPopupMenu);

            // Generate event so handlers can add/remove/cancel menu
            _tabbedGroups.OnPageContextMenu(tge);

            int visibleCommands = 0;

            // Count how many visible commands left
            foreach (MenuCommand mc in _tabControl.ContextPopupMenu.MenuCommands)
            {
                if (mc.Visible)
                {
                    visibleCommands++;
                }
            }

            // Pass back cancel value or always cancel if no commands are visible
            e.Cancel = (tge.Cancel || (visibleCommands == 0));
        }
示例#19
0
        private bool FindTabPageCollection(
                TabGroupSequence nodeGroup,
                Crownwood.DotNetMagic.Controls.TabPage tabPage,
                out TabPageCollection containingCollection)
        {
            for (var i = 0; i < nodeGroup.Count; i++)
            {
                var node = nodeGroup[i];

                if (node.IsSequence)
                {
                    var found = FindTabPageCollection(node as TabGroupSequence, tabPage, out containingCollection);

                    if (found)
                        return true;
                }

                if (node.IsLeaf)
                {
                    var leaf = (TabGroupLeaf)node;
                    if (leaf.TabPages.Contains(tabPage))
                    {
                        containingCollection = leaf.TabPages;
                        return true;
                    }
                }
            }

            containingCollection = null;
            return false;
        }
示例#20
0
        protected void CreateTargets(TabGroupLeaf leaf)
        {
            // Grab the underlying tab control
            Controls.TabControl tc = leaf.GroupControl as Controls.TabControl;

            // Get the total size of the tab control itself in screen coordinates
            Rectangle totalSize = tc.RectangleToScreen(tc.ClientRectangle);

            // We do not allow a page to be transfered to its own leaf!
            if (leaf != _leaf)
            {
                Rectangle tabsSize = tc.RectangleToScreen(tc.TabsAreaRect);

                // Give priority to the tabs area being used to transfer page
                _targets.Add(new Target(tabsSize, totalSize, leaf, Target.TargetActions.Transfer));
            }

            // Can only create new groups if moving relative to a new group
            // or we have more than one page in the originating group
            if ((leaf != _leaf) || ((leaf == _leaf) && _leaf.TabPages.Count > 1))
            {
                int horzThird = totalSize.Width / 3;
                int vertThird = totalSize.Height / 3;

                // Create the four spacing rectangle
                Rectangle leftRect   = new Rectangle(totalSize.X, totalSize.Y, horzThird, totalSize.Height);
                Rectangle rightRect  = new Rectangle(totalSize.Right - horzThird, totalSize.Y, horzThird, totalSize.Height);
                Rectangle topRect    = new Rectangle(totalSize.X, totalSize.Y, totalSize.Width, vertThird);
                Rectangle bottomRect = new Rectangle(totalSize.X, totalSize.Bottom - vertThird, totalSize.Width, vertThird);

                TabGroupSequence tgs = _leaf.Parent as TabGroupSequence;

                // Can only create new groups in same direction, unless this is the only leaf
                if (tgs.Count <= 1)
                {
                    // Add each new target
                    _targets.Add(new Target(leftRect, leftRect, leaf, Target.TargetActions.GroupLeft));
                    _targets.Add(new Target(rightRect, rightRect, leaf, Target.TargetActions.GroupRight));
                    _targets.Add(new Target(topRect, topRect, leaf, Target.TargetActions.GroupTop));
                    _targets.Add(new Target(bottomRect, bottomRect, leaf, Target.TargetActions.GroupBottom));
                }
                else
                {
                    if (tgs.Direction == Direction.Vertical)
                    {
                        _targets.Add(new Target(topRect, topRect, leaf, Target.TargetActions.GroupTop));
                        _targets.Add(new Target(bottomRect, bottomRect, leaf, Target.TargetActions.GroupBottom));
                    }
                    else
                    {
                        _targets.Add(new Target(leftRect, leftRect, leaf, Target.TargetActions.GroupLeft));
                        _targets.Add(new Target(rightRect, rightRect, leaf, Target.TargetActions.GroupRight));
                    }
                }
            }

            // We do not allow a page to be transfered to its own leaf!
            if (leaf != _leaf)
            {
                // Any remaining space is used to
                _targets.Add(new Target(totalSize, totalSize, leaf, Target.TargetActions.Transfer));
            }
        }