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 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(); }
// public byte[] SaveConfigToArray() // { // return SaveConfigToArray(Encoding.Unicode); // } // // public byte[] SaveConfigToArray(Encoding encoding) // { // // Create a memory based stream // MemoryStream ms = new MemoryStream(); // // // Save into the file stream // SaveConfigToStream(ms, encoding); // // // Must remember to close // ms.Close(); // // // Return an array of bytes that contain the streamed XML // return ms.GetBuffer(); // } // public void SaveConfigToFile(string filename) // { // SaveConfigToFile(filename, Encoding.Unicode); // } // public void SaveConfigToFile(string filename, Encoding encoding) // { // // Create/Overwrite existing file // FileStream fs = new FileStream(filename, FileMode.Create); // // // Save into the file stream // SaveConfigToStream(fs, encoding); // // // Must remember to close // fs.Close(); // } // public void SaveConfigToStream(Stream stream, Encoding encoding) // { // XmlTextWriter xmlOut = new XmlTextWriter(stream, encoding); // // // Use indenting for readability // xmlOut.Formatting = Formatting.Indented; // // // Always begin file with identification and warning // xmlOut.WriteStartDocument(); // xmlOut.WriteComment(" SharpClient.UI, The User Interface library for .NET (www.SharpClientUi.com) "); // xmlOut.WriteComment(" Modifying this generated file will probably render it invalid "); // // // Associate a version number with the root element so that future version of the code // // will be able to be backwards compatible or at least recognise out of date versions // xmlOut.WriteStartElement("TabbedGroups"); // xmlOut.WriteAttributeString("FormatVersion", "1"); // // if (_activeLeaf != null) // xmlOut.WriteAttributeString("ActiveLeaf", _activeLeaf.Unique.ToString()); // else // xmlOut.WriteAttributeString("ActiveLeaf", "-1"); // // // Give handlers chance to embed custom data // xmlOut.WriteStartElement("CustomGlobalData"); // OnGlobalSaving(xmlOut); // xmlOut.WriteEndElement(); // // // Save the root sequence // _root.SaveToXml(xmlOut); // // // Terminate the root element and document // xmlOut.WriteEndElement(); // xmlOut.WriteEndDocument(); // // // This should flush all actions and close the file // xmlOut.Close(); // // // Saved, so cannot be dirty any more // if (_autoCalculateDirty) // _dirty = false; // // } // // public void LoadConfigFromArray(byte[] buffer) // { // // Create a memory based stream // MemoryStream ms = new MemoryStream(buffer); // // // Save into the file stream // LoadConfigFromStream(ms); // // // Must remember to close // ms.Close(); // } // // public void LoadConfigFromFile(string filename) // { // // Open existing file // FileStream fs = new FileStream(filename, FileMode.Open); // // // Load from the file stream // LoadConfigFromStream(fs); // // // Must remember to close // fs.Close(); // } // // public void LoadConfigFromStream(Stream stream) // { // XmlTextReader xmlIn = new XmlTextReader(stream); // // // Ignore whitespace, not interested // xmlIn.WhitespaceHandling = WhitespaceHandling.None; // // // Moves the reader to the root element. // xmlIn.MoveToContent(); // // // Double check this has the correct element name // if (xmlIn.Name != "TabbedGroups") // throw new ArgumentException("Root element must be 'TabbedGroups'"); // // // Load the format version number // string version = xmlIn.GetAttribute(0); // string rawActiveLeaf = xmlIn.GetAttribute(1); // // // Convert format version from string to double // int formatVersion = (int)Convert.ToDouble(version); // int activeLeaf = Convert.ToInt32(rawActiveLeaf); // // // We can only load 1 upward version formats // if (formatVersion < 1) // throw new ArgumentException("Can only load Version 1 and upwards TabbedGroups Configuration files"); // // try // { // // Prevent compacting and reposition of children // BeginInit(); // // // Remove all existing contents // _root.Clear(); // // // Read to custom data element // if (!xmlIn.Read()) // throw new ArgumentException("An element was expected but could not be read in"); // // if (xmlIn.Name != "CustomGlobalData") // throw new ArgumentException("Expected 'CustomData' element was not found"); // // bool finished = xmlIn.IsEmptyElement; // // // Give handlers chance to reload custom saved data // OnGlobalLoading(xmlIn); // // // Read everything until we get the end of custom data marker // while(!finished) // { // // Check it has the expected name // if (xmlIn.NodeType == XmlNodeType.EndElement) // finished = (xmlIn.Name == "CustomGlobalData"); // // if (!finished) // { // if (!xmlIn.Read()) // throw new ArgumentException("An element was expected but could not be read in"); // } // } // // // Read the next well known lement // if (!xmlIn.Read()) // throw new ArgumentException("An element was expected but could not be read in"); // // // Is it the expected element? // if (xmlIn.Name != "Sequence") // throw new ArgumentException("Element 'Sequence' was expected but not found"); // // // Reload the root sequence // _root.LoadFromXml(xmlIn); // // // 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"); // } // finally // { // TabGroupLeaf newActive = null; // // // Reset the active leaf correctly // TabGroupLeaf current = FirstLeaf(); // // while(current != null) // { // // Default to the first leaf if we cannot find a match // if (newActive == null) // newActive = current; // // // Find an exact match? // if (current.Unique == activeLeaf) // { // newActive = current; // break; // } // // current = NextLeaf(current); // } // // // Reinstate the active leaf indication // if (newActive != null) // ActiveLeaf = newActive; // // // Allow normal operation // EndInit(); // } // // xmlIn.Close(); // // // Just loaded, so cannot be dirty // if (_autoCalculateDirty) // _dirty = false; // } // 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; }
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; }
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); }
protected void InternalConstruct(VisualStyle style) { // Prevent flicker with double buffering and all painting inside WM_PAINT SetStyle(ControlStyles.DoubleBuffer, true); SetStyle(ControlStyles.AllPaintingInWmPaint, 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; // Create the root sequence that always exists _root = new TabGroupSequence(this); // Define default settings ResetProminentLeaf(); ResetResizeBarVector(); ResetResizeBarColor(); ResetResizeBarLock(); 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(); // Add ourself to the application filtering list // (to snoop for shortcut combinations) Application.AddMessageFilter(this); }
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); } } }