public TabGroupBase Add(TabGroupBase value) { // Use base class to process actual collection operation base.List.Add(value as object); return value; }
public bool Contains(TabGroupBase value) { // Value comparison foreach(String s in base.List) if (value.Equals(s)) return true; return false; }
protected void InternalConstruct(TabbedGroups tabbedGroups, TabGroupBase parent) { // Assign initial values _tabbedGroups = tabbedGroups; _parent = parent; _unique = _count++; // Defaults _tag = null; _space = 100m; _minSize = new Size(_tabbedGroups.DefaultGroupMinimumWidth, _tabbedGroups.DefaultGroupMinimumHeight); }
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); } } }
public TabGroupLeaf(TabbedGroups tabbedGroups, TabGroupBase parent) : base(tabbedGroups, parent) { // Create our managed tab control instance _tabControl = new Controls.TabControl(); // We need page drag to begin when mouse dragged a small distance _tabControl.DragFromControl = false; // We need to monitor attempts to drag into the tab control _dragEntered = false; _tabControl.AllowDrop = true; _tabControl.DragDrop += new DragEventHandler(OnControlDragDrop); _tabControl.DragEnter += new DragEventHandler(OnControlDragEnter); _tabControl.DragLeave += new EventHandler(OnControlDragLeave); // Need notification when page drag begins _tabControl.PageDragStart += new MouseEventHandler(OnPageDragStart); _tabControl.PageDragMove += new MouseEventHandler(OnPageDragMove); _tabControl.PageDragEnd += new MouseEventHandler(OnPageDragEnd); _tabControl.PageDragQuit += new MouseEventHandler(OnPageDragQuit); // Hook into tab page collection events _tabControl.TabPages.Cleared += new CollectionClear(OnTabPagesCleared); _tabControl.TabPages.Inserted += new CollectionChange(OnTabPagesInserted); _tabControl.TabPages.Removed += new CollectionChange(OnTabPagesRemoved); // Hook into page level events _tabControl.GotFocus += new EventHandler(OnGainedFocus); _tabControl.PageGotFocus += new EventHandler(OnGainedFocus); _tabControl.ClosePressed += new EventHandler(OnClose); // Manager only created at start of drag operation _targetManager = null; DefinePopupMenuForControl(_tabControl); // Setup the correct 'HideTabsMode' for the control Notify(TabGroupBase.NotifyCode.DisplayTabMode); // Define the default setup of TabControl and allow developer to customize _tabbedGroups.OnTabControlCreated(_tabControl); }
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; }
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); }
internal void SetParent(TabGroupBase tgb) { _parent = tgb; }
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; } }
protected TabGroupBase Add(TabGroupBase group) { // Remember reference _children.Add(group); // First group added to sequence? if (_children.Count == 1) { // Add new child control _control.Controls.Add(group.GroupControl); } else { // Create a resizing bar ResizeBar bar = new ResizeBar(_direction, this); // Append resize bar between existing entries and new entry _control.Controls.Add(bar); // Append new group control _control.Controls.Add(group.GroupControl); } if (!_tabbedGroups.Initializing) { // Allocate space for the new child AllocateSpace(group); // Update child layout to reflect new proportional spacing values RepositionChildren(); } // Mark layout as dirty if (_tabbedGroups.AutoCalculateDirty) _tabbedGroups.Dirty = true; return group; }
public TabGroupSequence(TabbedGroups tabbedGroups, TabGroupBase parent, Direction direction) : base(tabbedGroups, parent) { InternalConstruct(null, direction); }
public int IndexOf(TabGroupBase value) { // Find the 0 based index of the requested entry return base.List.IndexOf(value); }
public void AddRange(TabGroupBase[] values) { // Use existing method to add each array entry foreach(TabGroupBase item in values) Add(item); }
public void Remove(TabGroupBase group) { // Convert from reference to index to use existing RemoveAt implementation RemoveAt(_children.IndexOf(group)); }
public TabGroupSequence(TabbedGroups tabbedGroups, TabGroupBase parent) : base(tabbedGroups, parent) { InternalConstruct(null, Direction.Horizontal); }
public void Insert(int index, TabGroupBase value) { // Use base class to process actual collection operation base.List.Insert(index, value as object); }
internal void Replace(TabGroupBase orig, TabGroupBase replace) { // Find array position of old item int origPos = _children.IndexOf(orig); // Transfer across the space occupied replace.RealSpace = orig.RealSpace; // Is this the only Window entry? if (_children.Count == 1) { // Remove Window from appearance // Use helper method to circumvent form Close bug ControlHelper.RemoveAt(_control.Controls, 0); } else { int pos = 0; // Calculate position of Window to remove if (origPos != 0) pos = origPos * 2 - 1; // Remove Window and bar // Use helper method to circumvent form Close bug ControlHelper.RemoveAt(_control.Controls, pos); ControlHelper.RemoveAt(_control.Controls, pos); } // Inserting at start of collection? if (origPos == 0) { if (_children.Count > 1) { // Create a resizing bar ResizeBar bar = new ResizeBar(_direction, this); // Append resize bar between existing entries and new entry _control.Controls.Add(bar); // Reposition the bar and group to start of collection _control.Controls.SetChildIndex(bar, 0); } // Append new group control _control.Controls.Add(replace.GroupControl); // Reposition the bar and group to start of collection _control.Controls.SetChildIndex(replace.GroupControl, 0); } else { // Create a resizing bar ResizeBar bar = new ResizeBar(_direction, this); // Append resize bar between existing entries and new entry _control.Controls.Add(bar); // Append new group control _control.Controls.Add(replace.GroupControl); // Find correct index taking into account number of resize bars int pos = origPos * 2 - 1; // Reposition the bar and Window to correct relative ordering _control.Controls.SetChildIndex(bar, pos++); _control.Controls.SetChildIndex(replace.GroupControl, pos); } // Update parentage replace.SetParent(this); // Replace the entry _children[origPos] = replace; // Update child layout to reflect new proportional spacing values RepositionChildren(); // Mark layout as dirty if (_tabbedGroups.AutoCalculateDirty) _tabbedGroups.Dirty = true; }
public void Remove(TabGroupBase value) { // Use base class to process actual collection operation base.List.Remove(value as object); }
protected void AllocateSpace(TabGroupBase newGroup) { // Is this the only group? if (_children.Count == 1) { // Give it all the space newGroup.Space = 100m; } else { // Calculate how much space it should have Decimal newSpace = 100m / _children.Count; // How much space should we steal from each of the others Decimal reduceSpace = newSpace / (_children.Count - 1); // Actual space acquired so far Decimal allocatedSpace = 0m; foreach(TabGroupBase group in _children) { // Only process existing entries, not the new one if (group != newGroup) { // How much space does the group currently have Decimal currentSpace = group.Space; // How much space to steal from it Decimal xferSpace = reduceSpace; // If group has less space then we want, just steal all it has if (currentSpace < xferSpace) xferSpace = currentSpace; // Transfer the space across currentSpace -= xferSpace; // Round the sensible number of decimal places currentSpace = Decimal.Round(currentSpace, SPACE_PRECISION); // Update window with new space allocation group.Space = currentSpace; // Total up total space of all entries except new one allocatedSpace += currentSpace; } } // Assign all remaining space to new entry newGroup.Space = 100m - allocatedSpace; } }
public TabGroupBase(TabbedGroups tabbedGroups, TabGroupBase parent) { InternalConstruct(tabbedGroups, parent); }
protected void Notify(TabGroupBase.NotifyCode notifyCode) { // Propogate change notification only is we have a root sequence if (_root != null) _root.Notify(notifyCode); }
protected void DeltaGroupSpace(TabGroupBase group, int vector) { Rectangle clientRect = _control.ClientRectangle; // Space available for allocation int space; // New pixel length of the modified group int newLength = vector; if (_direction == Direction.Vertical) { space = clientRect.Height; // New pixel size is requested change plus original // height minus the minimal size that is always added newLength += group.GroupControl.Height; newLength -= group.MinimumSize.Height; } else { space = clientRect.Width; // New pixel size is requested change plus original // width minus the minimal size that is always added newLength += group.GroupControl.Width; newLength -= group.MinimumSize.Width; } int barSpace = 0; // Create temporary array of working values int[] positions = new int[_control.Controls.Count]; // Pass 1, allocate all the space needed for each ResizeBar and the // minimal amount of space that each Window requests. AllocateMandatorySizes(ref positions, ref barSpace, ref space); // What is the new percentage it needs? Decimal newPercent = 0m; // Is there any room to allow a percentage calculation if ((newLength > 0) && (space > 0)) newPercent = (Decimal)newLength / (Decimal)space * 100m; // What is the change in area Decimal reallocate = newPercent - group.Space; // Find the group after this one TabGroupBase nextGroup = _children[_children.IndexOf(group) + 1]; if ((nextGroup.Space - reallocate) < 0m) reallocate = nextGroup.Space; // Modify the Window in question group.Space += reallocate; // Reverse modify the Window afterwards nextGroup.Space -= reallocate; // Update the visual appearance RepositionChildren(); }
protected TabGroupBase Insert(int index, TabGroupBase group) { // Range check index if (index < 0) throw new ArgumentOutOfRangeException("index", index, "Insert index must be at least 0"); if (index >= _children.Count) throw new ArgumentOutOfRangeException("index", index, "Cannot insert after end of current entries"); // Remember reference _children.Insert(index, group); // Create a resizing bar ResizeBar bar = new ResizeBar(_direction, this); // Append resize bar between existing entries and new entry _control.Controls.Add(bar); // Append new group control _control.Controls.Add(group.GroupControl); // Inserting at start of collection? if (index == 0) { // Reposition the bar and group to start of collection _control.Controls.SetChildIndex(bar, 0); _control.Controls.SetChildIndex(group.GroupControl, 0); } else { // Find correct index taking into account number of resize bars int pos = index * 2 - 1; // Reposition the bar and Window to correct relative ordering _control.Controls.SetChildIndex(bar, pos++); _control.Controls.SetChildIndex(group.GroupControl, pos); } // Allocate space for the new child AllocateSpace(group); // Update child layout to reflect new proportional spacing values RepositionChildren(); // Mark layout as dirty if (_tabbedGroups.AutoCalculateDirty) _tabbedGroups.Dirty = true; return group; }
public int IndexOf(TabGroupBase group) { return _children.IndexOf(group); }