internal void NewHorizontalGroup(TabGroupLeaf sourceLeaf, bool before) { TabGroupSequence tgs = this.Parent as TabGroupSequence; // We must have a parent sequence! if (tgs != null) { tgs.Direction = Common.Direction.Horizontal; AddGroupToSequence(tgs, sourceLeaf, before); } }
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; River.Orqa.Controls.Controls.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(); } }
protected void CompactRemoveEmptyTabSequences(TabbedGroups.CompactFlags flags) { // Should we check for empty sequence nodes? if ((flags & TabbedGroups.CompactFlags.RemoveEmptyTabSequence) != 0) { int count = _children.Count; for (int index = 0; index < count; index++) { // Only interested in sequence entries if (_children[index].IsSequence) { TabGroupSequence tgs = (TabGroupSequence)_children[index]; // Is this an empty sequence node? if (tgs.Count == 0) { // Need to remove the redundant entry RemoveAt(index); // Reduce number of entries left to check count--; // Move backwards so the next increment stays on same index index--; // Mark layout as dirty if (_tabbedGroups.AutoCalculateDirty) { _tabbedGroups.Dirty = true; } } } } } }
protected void CompactReduceSameDirection(TabbedGroups.CompactFlags flags) { bool changed = false; // Should we check for same direction sub-sequences? if ((flags & TabbedGroups.CompactFlags.ReduceSameDirection) != 0) { int count = _children.Count; for (int index = 0; index < count; index++) { // Only interested in sequence entries if (_children[index].IsSequence) { TabGroupSequence tgs = (TabGroupSequence)_children[index]; // Does it run in same direction as ourself? if (_direction == tgs.Direction) { // Remember how much space the base entry occupies Decimal temp = tgs.RealSpace; // Find the child control to be replaced int childPos = _control.Controls.IndexOf(tgs.GroupControl); // Need to remove a resize bar before the control? if (childPos > 0) { ControlHelper.RemoveAt(_control.Controls, childPos); } // Remove the actual control ControlHelper.RemoveAt(_control.Controls, childPos); // Remove the intermediate group _children.RemoveAt(index); // Reflect change in size count--; Decimal totalAllocated = 0m; // Add in each sub group in turn int subCount = tgs.Count; bool firstInsert = true; for (int subIndex = 0; subIndex < subCount; subIndex++) { TabGroupBase tgb = tgs[subIndex]; // What percentage of original space did it have? Decimal orig = tgb.RealSpace; // Give it the same proportion of new space Decimal update = Decimal.Round(temp / 100 * orig, SPACE_PRECISION); // Keep total actually allocated totalAllocated += update; // Use new proportion tgb.RealSpace = update; // Update parentage tgb.SetParent(this); // Does new child control need a resizing bar? if ((childPos > 0) && !firstInsert) { // Create a resizing bar ResizeBar bar = new ResizeBar(_direction, this); _control.Controls.Add(bar); _control.Controls.SetChildIndex(bar, childPos++); } // Add new child control in its place _control.Controls.Add(tgb.GroupControl); _control.Controls.SetChildIndex(tgb.GroupControl, childPos++); // Insert at current position _children.Insert(index, tgb); // Adjust variables to reflect increased size index++; count++; firstInsert = false; } // Assign any remainder to last group _children[index - 1].RealSpace += temp - totalAllocated; // Need controls repositioned changed = true; // Mark layout as dirty if (_tabbedGroups.AutoCalculateDirty) { _tabbedGroups.Dirty = true; } } } } } // Change in contents requires entries to be repositioned if (changed) { RepositionChildren(); } }
protected void CompactReduceSingleEntries(TabbedGroups.CompactFlags flags) { bool changed = false; // Should we check for single instance nodes? if ((flags & TabbedGroups.CompactFlags.ReduceSingleEntries) != 0) { int count = _children.Count; for (int index = 0; index < count; index++) { // Only interested in sequence entries if (_children[index].IsSequence) { TabGroupSequence tgs = (TabGroupSequence)_children[index]; // Does this entry only have a single child if (tgs.Count == 1) { // Remember how much space the base entry occupies Decimal temp = tgs.RealSpace; // Get reference to only child TabGroupBase child = tgs[0]; // Update parentage child.SetParent(this); // Find the child control to be replaced int childPos = _control.Controls.IndexOf(tgs.GroupControl); // Remove it ControlHelper.RemoveAt(_control.Controls, childPos); // Add new child control in its place _control.Controls.Add(child.GroupControl); _control.Controls.SetChildIndex(child.GroupControl, childPos); // Replace the middle object with the child _children.RemoveAt(index); _children.Insert(index, child); // Restore its correct spacing child.RealSpace = temp; // Need controls repositioned changed = true; // Mark layout as dirty if (_tabbedGroups.AutoCalculateDirty) { _tabbedGroups.Dirty = true; } } } } } // Change in contents requires entries to be repositioned if (changed) { RepositionChildren(); } }
public override void LoadFromXml(XmlTextReader xmlIn) { // Grab the expected attributes string rawCount = xmlIn.GetAttribute(0); string rawUnique = xmlIn.GetAttribute(1); string rawSpace = xmlIn.GetAttribute(2); string rawDirection = xmlIn.GetAttribute(3); // Convert to correct types int count = Convert.ToInt32(rawCount); int unique = Convert.ToInt32(rawUnique); Decimal space = Convert.ToDecimal(rawSpace); Common.Direction direction = (rawDirection == "Horizontal" ? Common.Direction.Horizontal : Common.Direction.Vertical); // Update myself with new values _unique = unique; _space = space; _direction = direction; // Load each of the children for (int i = 0; i < count; i++) { // Read the next Element if (!xmlIn.Read()) { throw new ArgumentException("An element was expected but could not be read in"); } TabGroupBase newElement = null; // Is it another sequence? if (xmlIn.Name == "Sequence") { newElement = new TabGroupSequence(_tabbedGroups, this); } else if (xmlIn.Name == "Leaf") { newElement = new TabGroupLeaf(_tabbedGroups, this); } else { throw new ArgumentException("Unknown element was encountered"); } bool expectEndElement = !xmlIn.IsEmptyElement; // Load its config newElement.LoadFromXml(xmlIn); // Add new element to the collection Add(newElement); // Do we expect and end element to occur? if (expectEndElement) { // Move past the end element if (!xmlIn.Read()) { throw new ArgumentException("Could not read in next expected node"); } // Check it has the expected name if (xmlIn.NodeType != XmlNodeType.EndElement) { throw new ArgumentException("EndElement expected but not found"); } } } }
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 }); // 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 == Common.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); TGContextMenuEventArgs tge = new TGContextMenuEventArgs(this, _tabControl, _tabControl.SelectedTab, _tabControl.ContextPopupMenu); // Generate event so handlers can add/remove/cancel menu _tabbedGroups.OnPageContextMenu(tge); // Pass back cancel value e.Cancel = tge.Cancel; }
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 == Common.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)); } }