diff --git a/Labyrinth3.sln b/Labyrinth3.sln new file mode 100644 index 0000000..bc7c2cf --- /dev/null +++ b/Labyrinth3.sln @@ -0,0 +1,25 @@ + +Microsoft Visual Studio Solution File, Format Version 12.00 +# Visual Studio 15 +VisualStudioVersion = 15.0.27428.2037 +MinimumVisualStudioVersion = 10.0.40219.1 +Project("{FAE04EC0-301F-11D3-BF4B-00C04F79EFBC}") = "Labyrinth3", "Labyrinth3\Labyrinth3.csproj", "{B4700781-94F1-41A2-BBD5-4E2E887C66B0}" +EndProject +Global + GlobalSection(SolutionConfigurationPlatforms) = preSolution + Debug|Any CPU = Debug|Any CPU + Release|Any CPU = Release|Any CPU + EndGlobalSection + GlobalSection(ProjectConfigurationPlatforms) = postSolution + {B4700781-94F1-41A2-BBD5-4E2E887C66B0}.Debug|Any CPU.ActiveCfg = Debug|Any CPU + {B4700781-94F1-41A2-BBD5-4E2E887C66B0}.Debug|Any CPU.Build.0 = Debug|Any CPU + {B4700781-94F1-41A2-BBD5-4E2E887C66B0}.Release|Any CPU.ActiveCfg = Release|Any CPU + {B4700781-94F1-41A2-BBD5-4E2E887C66B0}.Release|Any CPU.Build.0 = Release|Any CPU + EndGlobalSection + GlobalSection(SolutionProperties) = preSolution + HideSolutionNode = FALSE + EndGlobalSection + GlobalSection(ExtensibilityGlobals) = postSolution + SolutionGuid = {72F14F84-CEDC-4E45-A381-C26253CFE7FA} + EndGlobalSection +EndGlobal diff --git a/Labyrinth3/Crownwood.Magic/Collections/CollectionWithEvents.cs b/Labyrinth3/Crownwood.Magic/Collections/CollectionWithEvents.cs new file mode 100644 index 0000000..e3e7253 --- /dev/null +++ b/Labyrinth3/Crownwood.Magic/Collections/CollectionWithEvents.cs @@ -0,0 +1,130 @@ +// ***************************************************************************** +// +// (c) Crownwood Consulting Limited 2002-2003 +// All rights reserved. The software and associated documentation +// supplied hereunder are the proprietary information of Crownwood Consulting +// Limited, Crownwood, Bracknell, Berkshire, England and are supplied subject +// to licence terms. +// +// Magic Version 1.7.4.0 www.dotnetmagic.com +// ***************************************************************************** + +using System.Collections; + +namespace Crownwood.Magic.Collections +{ + // Declare the event signatures + public delegate void CollectionClear(); + + public delegate void CollectionChange(int index, object value); + + public class CollectionWithEvents : CollectionBase + { + // Instance fields + private int _suspendCount; + + // Collection change events + public event CollectionClear Clearing; + + public event CollectionClear Cleared; + + public event CollectionChange Inserting; + + public event CollectionChange Inserted; + + public event CollectionChange Removing; + + public event CollectionChange Removed; + + public CollectionWithEvents() + { + // Default to not suspended + _suspendCount = 0; + } + + // Do not generate change events until resumed + public void SuspendEvents() + { + _suspendCount++; + } + + // Safe to resume change events. + public void ResumeEvents() + { + --_suspendCount; + } + + // Are change events currently suspended? + public bool IsSuspended + { + get { return (_suspendCount > 0); } + } + + // Overrides for generating events + protected override void OnClear() + { + if (!IsSuspended) + { + // Any attached event handlers? + if (Clearing != null) + Clearing(); + } + } + + protected override void OnClearComplete() + { + if (!IsSuspended) + { + // Any attached event handlers? + if (Cleared != null) + Cleared(); + } + } + + protected override void OnInsert(int index, object value) + { + if (!IsSuspended) + { + // Any attached event handlers? + if (Inserting != null) + Inserting(index, value); + } + } + + protected override void OnInsertComplete(int index, object value) + { + if (!IsSuspended) + { + // Any attached event handlers? + if (Inserted != null) + Inserted(index, value); + } + } + + protected override void OnRemove(int index, object value) + { + if (!IsSuspended) + { + // Any attached event handlers? + if (Removing != null) + Removing(index, value); + } + } + + protected override void OnRemoveComplete(int index, object value) + { + if (!IsSuspended) + { + // Any attached event handlers? + if (Removed != null) + Removed(index, value); + } + } + + protected int IndexOf(object value) + { + // Find the 0 based index of the requested entry + return base.List.IndexOf(value); + } + } +} \ No newline at end of file diff --git a/Labyrinth3/Crownwood.Magic/Collections/ContentCollection.cs b/Labyrinth3/Crownwood.Magic/Collections/ContentCollection.cs new file mode 100644 index 0000000..f04a5c8 --- /dev/null +++ b/Labyrinth3/Crownwood.Magic/Collections/ContentCollection.cs @@ -0,0 +1,118 @@ +// ***************************************************************************** +// +// (c) Crownwood Consulting Limited 2002-2003 +// All rights reserved. The software and associated documentation +// supplied hereunder are the proprietary information of Crownwood Consulting +// Limited, Crownwood, Bracknell, Berkshire, England and are supplied subject +// to licence terms. +// +// Magic Version 1.7.4.0 www.dotnetmagic.com +// ***************************************************************************** + +using Crownwood.Magic.Docking; +using System; + +namespace Crownwood.Magic.Collections +{ + public class ContentCollection : CollectionWithEvents + { + public Content Add(Content value) + { + // Use base class to process actual collection operation + base.List.Add(value as object); + + return value; + } + + public void AddRange(Content[] values) + { + // Use existing method to add each array entry + foreach (Content page in values) + Add(page); + } + + public void Remove(Content value) + { + // Use base class to process actual collection operation + base.List.Remove(value as object); + } + + public void Insert(int index, Content value) + { + // Use base class to process actual collection operation + base.List.Insert(index, value as object); + } + + public bool Contains(Content value) + { + // Use base class to process actual collection operation + return base.List.Contains(value as object); + } + + public bool Contains(ContentCollection values) + { + foreach (Content c in values) + { + // Use base class to process actual collection operation + if (Contains(c)) + return true; + } + + return false; + } + + public bool Contains(String value) + { + foreach (Content c in base.List) + if (c.Title.Equals(value)) + return true; + + return false; + } + + public bool Contains(StringCollection values) + { + foreach (String s in values) + if (Contains(s)) + return true; + + return false; + } + + public Content this[int index] + { + // Use base class to process actual collection operation + get { return (base.List[index] as Content); } + } + + public Content this[string title] + { + get + { + // Search for a Content with a matching title + foreach (Content c in base.List) + if (c.Title == title) + return c; + + return null; + } + } + + public int IndexOf(Content value) + { + // Find the 0 based index of the requested entry + return base.List.IndexOf(value); + } + + public ContentCollection Copy() + { + ContentCollection clone = new ContentCollection(); + + // Copy each reference across + foreach (Content c in base.List) + clone.Add(c); + + return clone; + } + } +} \ No newline at end of file diff --git a/Labyrinth3/Crownwood.Magic/Collections/HotZoneCollection.cs b/Labyrinth3/Crownwood.Magic/Collections/HotZoneCollection.cs new file mode 100644 index 0000000..5620094 --- /dev/null +++ b/Labyrinth3/Crownwood.Magic/Collections/HotZoneCollection.cs @@ -0,0 +1,75 @@ +// ***************************************************************************** +// +// (c) Crownwood Consulting Limited 2002-2003 +// All rights reserved. The software and associated documentation +// supplied hereunder are the proprietary information of Crownwood Consulting +// Limited, Crownwood, Bracknell, Berkshire, England and are supplied subject +// to licence terms. +// +// Magic Version 1.7.4.0 www.dotnetmagic.com +// ***************************************************************************** + +using Crownwood.Magic.Docking; +using System.Drawing; + +namespace Crownwood.Magic.Collections +{ + public class HotZoneCollection : CollectionWithEvents + { + public HotZone Add(HotZone value) + { + // Use base class to process actual collection operation + base.List.Add(value as object); + + return value; + } + + public void AddRange(HotZone[] values) + { + // Use existing method to add each array entry + foreach (HotZone page in values) + Add(page); + } + + public void Remove(HotZone value) + { + // Use base class to process actual collection operation + base.List.Remove(value as object); + } + + public void Insert(int index, HotZone value) + { + // Use base class to process actual collection operation + base.List.Insert(index, value as object); + } + + public bool Contains(HotZone value) + { + // Use base class to process actual collection operation + return base.List.Contains(value as object); + } + + public HotZone this[int index] + { + // Use base class to process actual collection operation + get { return (base.List[index] as HotZone); } + } + + public int IndexOf(HotZone value) + { + // Find the 0 based index of the requested entry + return base.List.IndexOf(value); + } + + public HotZone Contains(Point pt) + { + foreach (HotZone hz in base.List) + { + if (hz.HotArea.Contains(pt)) + return hz; + } + + return null; + } + } +} \ No newline at end of file diff --git a/Labyrinth3/Crownwood.Magic/Collections/ManagerContentCollection.cs b/Labyrinth3/Crownwood.Magic/Collections/ManagerContentCollection.cs new file mode 100644 index 0000000..a28e9a2 --- /dev/null +++ b/Labyrinth3/Crownwood.Magic/Collections/ManagerContentCollection.cs @@ -0,0 +1,145 @@ +// ***************************************************************************** +// +// (c) Crownwood Consulting Limited 2002-2003 +// All rights reserved. The software and associated documentation +// supplied hereunder are the proprietary information of Crownwood Consulting +// Limited, Crownwood, Bracknell, Berkshire, England and are supplied subject +// to licence terms. +// +// Magic Version 1.7.4.0 www.dotnetmagic.com +// ***************************************************************************** + +using Crownwood.Magic.Docking; +using System; +using System.Windows.Forms; + +namespace Crownwood.Magic.Collections +{ + public class ManagerContentCollection : CollectionWithEvents + { + // Instance fields + protected DockingManager _manager; + + public ManagerContentCollection(DockingManager manager) + { + // Must provide a valid manager instance + if (manager == null) + throw new ArgumentNullException("DockingManager"); + + // Default the state + _manager = manager; + } + + public Content Add() + { + Content c = new Content(_manager); + + // Use base class to process actual collection operation + base.List.Add(c as object); + + return c; + } + + // Should only ever be used by Serialization + public Content Add(Content c) + { + // Assign correct docking manager to object + c.DockingManager = _manager; + + // Use base class to process actual collection operation + base.List.Add(c as object); + + return c; + } + + public Content Add(Control control) + { + Content c = new Content(_manager, control); + + // Use base class to process actual collection operation + base.List.Add(c as object); + + return c; + } + + public Content Add(Control control, string title) + { + Content c = new Content(_manager, control, title); + + // Use base class to process actual collection operation + base.List.Add(c as object); + + return c; + } + + public Content Add(Control control, string title, ImageList imageList, int imageIndex) + { + Content c = new Content(_manager, control, title, imageList, imageIndex); + + // Use base class to process actual collection operation + base.List.Add(c as object); + + return c; + } + + public void Remove(Content value) + { + // Use base class to process actual collection operation + base.List.Remove(value as object); + } + + public bool Contains(Content value) + { + // Use base class to process actual collection operation + return base.List.Contains(value as object); + } + + public Content this[int index] + { + // Use base class to process actual collection operation + get { return (base.List[index] as Content); } + } + + public Content this[string title] + { + get + { + // Search for a Content with a matching title + foreach (Content c in base.List) + if (c.Title == title) + return c; + + return null; + } + } + + public int SetIndex(int newIndex, Content value) + { + SuspendEvents(); + + base.List.Remove(value); + base.List.Insert(newIndex, value); + + ResumeEvents(); + + return newIndex; + } + + public int IndexOf(Content value) + { + // Find the 0 based index of the requested entry + return base.List.IndexOf(value); + } + + public ContentCollection Copy() + { + ContentCollection clone = new ContentCollection(); + + // Copy each reference across + foreach (Content c in base.List) + clone.Add(c); + + return clone; + } + } +} \ No newline at end of file diff --git a/Labyrinth3/Crownwood.Magic/Collections/MenuCommandCollection.cs b/Labyrinth3/Crownwood.Magic/Collections/MenuCommandCollection.cs new file mode 100644 index 0000000..4c25709 --- /dev/null +++ b/Labyrinth3/Crownwood.Magic/Collections/MenuCommandCollection.cs @@ -0,0 +1,166 @@ +// ***************************************************************************** +// +// (c) Crownwood Consulting Limited 2002-2003 +// All rights reserved. The software and associated documentation +// supplied hereunder are the proprietary information of Crownwood Consulting +// Limited, Crownwood, Bracknell, Berkshire, England and are supplied subject +// to licence terms. +// +// Magic Version 1.7.4.0 www.dotnetmagic.com +// ***************************************************************************** + +using Crownwood.Magic.Menus; +using System.Drawing; +using System.Windows.Forms; + +namespace Crownwood.Magic.Collections +{ + public class MenuCommandCollection : CollectionWithEvents + { + // Instance fields + protected string _extraText; + + protected Font _extraFont; + protected Color _extraTextColor; + protected Brush _extraTextBrush; + protected Color _extraBackColor; + protected Brush _extraBackBrush; + protected bool _showInfrequent; + + public MenuCommandCollection() + { + // Define defaults for internal state + _extraText = ""; + _extraFont = SystemInformation.MenuFont; + _extraTextColor = SystemColors.ActiveCaptionText; + _extraTextBrush = null; + _extraBackColor = SystemColors.ActiveCaption; + _extraBackBrush = null; + _showInfrequent = false; + } + + public MenuCommand Add(MenuCommand value) + { + // Use base class to process actual collection operation + base.List.Add(value as object); + + return value; + } + + public void AddRange(MenuCommand[] values) + { + // Use existing method to add each array entry + foreach (MenuCommand page in values) + Add(page); + } + + public void Remove(MenuCommand value) + { + // Use base class to process actual collection operation + base.List.Remove(value as object); + } + + public void Insert(int index, MenuCommand value) + { + // Use base class to process actual collection operation + base.List.Insert(index, value as object); + } + + public bool Contains(MenuCommand value) + { + // Use base class to process actual collection operation + return base.List.Contains(value as object); + } + + public MenuCommand this[int index] + { + // Use base class to process actual collection operation + get { return (base.List[index] as MenuCommand); } + } + + public MenuCommand this[string text] + { + get + { + // Search for a MenuCommand with a matching title + foreach (MenuCommand mc in base.List) + if (mc.Text == text) + return mc; + + return null; + } + } + + public int IndexOf(MenuCommand value) + { + // Find the 0 based index of the requested entry + return base.List.IndexOf(value); + } + + public bool VisibleItems() + { + foreach (MenuCommand mc in base.List) + { + // Is the item visible? + if (mc.Visible) + { + // And its not a separator... + if (mc.Text != "-") + { + // Then should return 'true' except when we are a sub menu item ourself + // in which case there might not be any visible children which means that + // this item would not be visible either. + if ((mc.MenuCommands.Count > 0) && (!mc.MenuCommands.VisibleItems())) + continue; + + return true; + } + } + } + + return false; + } + + public string ExtraText + { + get { return _extraText; } + set { _extraText = value; } + } + + public Font ExtraFont + { + get { return _extraFont; } + set { _extraFont = value; } + } + + public Color ExtraTextColor + { + get { return _extraTextColor; } + set { _extraTextColor = value; } + } + + public Brush ExtraTextBrush + { + get { return _extraTextBrush; } + set { _extraTextBrush = value; } + } + + public Color ExtraBackColor + { + get { return _extraBackColor; } + set { _extraBackColor = value; } + } + + public Brush ExtraBackBrush + { + get { return _extraBackBrush; } + set { _extraBackBrush = value; } + } + + public bool ShowInfrequent + { + get { return _showInfrequent; } + set { _showInfrequent = value; } + } + } +} \ No newline at end of file diff --git a/Labyrinth3/Crownwood.Magic/Collections/StringCollection.cs b/Labyrinth3/Crownwood.Magic/Collections/StringCollection.cs new file mode 100644 index 0000000..7b68a02 --- /dev/null +++ b/Labyrinth3/Crownwood.Magic/Collections/StringCollection.cs @@ -0,0 +1,138 @@ +// ***************************************************************************** +// +// (c) Crownwood Consulting Limited 2002-2003 +// All rights reserved. The software and associated documentation +// supplied hereunder are the proprietary information of Crownwood Consulting +// Limited, Crownwood, Bracknell, Berkshire, England and are supplied subject +// to licence terms. +// +// Magic Version 1.7.4.0 www.dotnetmagic.com +// ***************************************************************************** + +using System; +using System.Xml; + +namespace Crownwood.Magic.Collections +{ + public class StringCollection : CollectionWithEvents + { + public String Add(String value) + { + // Use base class to process actual collection operation + base.List.Add(value as object); + + return value; + } + + public void AddRange(String[] values) + { + // Use existing method to add each array entry + foreach (String item in values) + Add(item); + } + + public void Remove(String value) + { + // Use base class to process actual collection operation + base.List.Remove(value as object); + } + + public void Insert(int index, String value) + { + // Use base class to process actual collection operation + base.List.Insert(index, value as object); + } + + public bool Contains(String value) + { + // Value comparison + foreach (String s in base.List) + if (value.Equals(s)) + return true; + + return false; + } + + public bool Contains(StringCollection values) + { + foreach (String c in values) + { + // Use base class to process actual collection operation + if (Contains(c)) + return true; + } + + return false; + } + + public String this[int index] + { + // Use base class to process actual collection operation + get { return (base.List[index] as String); } + } + + public int IndexOf(String value) + { + // Find the 0 based index of the requested entry + return base.List.IndexOf(value); + } + + public void SaveToXml(string name, XmlTextWriter xmlOut) + { + xmlOut.WriteStartElement(name); + xmlOut.WriteAttributeString("Count", this.Count.ToString()); + + foreach (String s in base.List) + { + xmlOut.WriteStartElement("Item"); + xmlOut.WriteAttributeString("Name", s); + xmlOut.WriteEndElement(); + } + + xmlOut.WriteEndElement(); + } + + public void LoadFromXml(string name, XmlTextReader xmlIn) + { + // Move to next xml node + if (!xmlIn.Read()) + throw new ArgumentException("Could not read in next expected node"); + + // Check it has the expected name + if (xmlIn.Name != name) + throw new ArgumentException("Incorrect node name found"); + + this.Clear(); + + // Grab raw position information + string attrCount = xmlIn.GetAttribute(0); + + // Convert from string to proper types + int count = int.Parse(attrCount); + + for (int index = 0; index < count; index++) + { + // Move to next xml node + if (!xmlIn.Read()) + throw new ArgumentException("Could not read in next expected node"); + + // Check it has the expected name + if (xmlIn.Name != "Item") + throw new ArgumentException("Incorrect node name found"); + + this.Add(xmlIn.GetAttribute(0)); + } + + if (count > 0) + { + // Move over the end element of the collection + if (!xmlIn.Read()) + throw new ArgumentException("Could not read in next expected node"); + + // Check it has the expected name + if (xmlIn.Name != name) + throw new ArgumentException("Incorrect node name found"); + } + } + } +} \ No newline at end of file diff --git a/Labyrinth3/Crownwood.Magic/Collections/TabGroupBaseCollection.cs b/Labyrinth3/Crownwood.Magic/Collections/TabGroupBaseCollection.cs new file mode 100644 index 0000000..da248b8 --- /dev/null +++ b/Labyrinth3/Crownwood.Magic/Collections/TabGroupBaseCollection.cs @@ -0,0 +1,81 @@ +// ***************************************************************************** +// +// (c) Crownwood Consulting Limited 2002-2003 +// All rights reserved. The software and associated documentation +// supplied hereunder are the proprietary information of Crownwood Consulting +// Limited, Crownwood, Bracknell, Berkshire, England and are supplied subject +// to licence terms. +// +// Magic Version 1.7.4.0 www.dotnetmagic.com +// ***************************************************************************** + +using Crownwood.Magic.Controls; +using System; + +namespace Crownwood.Magic.Collections +{ + public class TabGroupBaseCollection : CollectionWithEvents + { + public TabGroupBase Add(TabGroupBase value) + { + // Use base class to process actual collection operation + base.List.Add(value as object); + + return 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 value) + { + // Use base class to process actual collection operation + base.List.Remove(value as object); + } + + public void Insert(int index, TabGroupBase value) + { + // Use base class to process actual collection operation + base.List.Insert(index, value as object); + } + + public bool Contains(TabGroupBase value) + { + // Value comparison + foreach (String s in base.List) + if (value.Equals(s)) + return true; + + return false; + } + + public bool Contains(TabGroupBaseCollection values) + { + foreach (TabGroupBase c in values) + { + // Use base class to process actual collection operation + if (Contains(c)) + return true; + } + + return false; + } + + public TabGroupBase this[int index] + { + // Use base class to process actual collection operation + get { return (base.List[index] as TabGroupBase); } + set { base.List[index] = value; } + } + + public int IndexOf(TabGroupBase value) + { + // Find the 0 based index of the requested entry + return base.List.IndexOf(value); + } + } +} \ No newline at end of file diff --git a/Labyrinth3/Crownwood.Magic/Collections/TabPageCollection.cs b/Labyrinth3/Crownwood.Magic/Collections/TabPageCollection.cs new file mode 100644 index 0000000..a4b0e4f --- /dev/null +++ b/Labyrinth3/Crownwood.Magic/Collections/TabPageCollection.cs @@ -0,0 +1,76 @@ +// ***************************************************************************** +// +// (c) Crownwood Consulting Limited 2002-2003 +// All rights reserved. The software and associated documentation +// supplied hereunder are the proprietary information of Crownwood Consulting +// Limited, Crownwood, Bracknell, Berkshire, England and are supplied subject +// to licence terms. +// +// Magic Version 1.7.4.0 www.dotnetmagic.com +// ***************************************************************************** + +using Crownwood.Magic.Controls; + +namespace Crownwood.Magic.Collections +{ + public class TabPageCollection : CollectionWithEvents + { + public TabPage Add(TabPage value) + { + // Use base class to process actual collection operation + base.List.Add(value as object); + + return value; + } + + public void AddRange(TabPage[] values) + { + // Use existing method to add each array entry + foreach (TabPage page in values) + Add(page); + } + + public void Remove(TabPage value) + { + // Use base class to process actual collection operation + base.List.Remove(value as object); + } + + public void Insert(int index, TabPage value) + { + // Use base class to process actual collection operation + base.List.Insert(index, value as object); + } + + public bool Contains(TabPage value) + { + // Use base class to process actual collection operation + return base.List.Contains(value as object); + } + + public TabPage this[int index] + { + // Use base class to process actual collection operation + get { return (base.List[index] as TabPage); } + } + + public TabPage this[string title] + { + get + { + // Search for a Page with a matching title + foreach (TabPage page in base.List) + if (page.Title == title) + return page; + + return null; + } + } + + public int IndexOf(TabPage value) + { + // Find the 0 based index of the requested entry + return base.List.IndexOf(value); + } + } +} \ No newline at end of file diff --git a/Labyrinth3/Crownwood.Magic/Collections/TargetCollection.cs b/Labyrinth3/Crownwood.Magic/Collections/TargetCollection.cs new file mode 100644 index 0000000..d589ec8 --- /dev/null +++ b/Labyrinth3/Crownwood.Magic/Collections/TargetCollection.cs @@ -0,0 +1,75 @@ +// ***************************************************************************** +// +// (c) Crownwood Consulting Limited 2002-2003 +// All rights reserved. The software and associated documentation +// supplied hereunder are the proprietary information of Crownwood Consulting +// Limited, Crownwood, Bracknell, Berkshire, England and are supplied subject +// to licence terms. +// +// Magic Version 1.7.4.0 www.dotnetmagic.com +// ***************************************************************************** + +using Crownwood.Magic.Controls; +using System.Drawing; + +namespace Crownwood.Magic.Collections +{ + public class TargetCollection : CollectionWithEvents + { + public Target Add(Target value) + { + // Use base class to process actual collection operation + base.List.Add(value as object); + + return value; + } + + public void AddRange(Target[] values) + { + // Use existing method to add each array entry + foreach (Target page in values) + Add(page); + } + + public void Remove(Target value) + { + // Use base class to process actual collection operation + base.List.Remove(value as object); + } + + public void Insert(int index, Target value) + { + // Use base class to process actual collection operation + base.List.Insert(index, value as object); + } + + public bool Contains(Target value) + { + // Use base class to process actual collection operation + return base.List.Contains(value as object); + } + + public Target this[int index] + { + // Use base class to process actual collection operation + get { return (base.List[index] as Target); } + } + + public int IndexOf(Target value) + { + // Find the 0 based index of the requested entry + return base.List.IndexOf(value); + } + + public Target Contains(Point pt) + { + foreach (Target t in base.List) + { + if (t.HotRect.Contains(pt)) + return t; + } + + return null; + } + } +} \ No newline at end of file diff --git a/Labyrinth3/Crownwood.Magic/Collections/WindowCollection.cs b/Labyrinth3/Crownwood.Magic/Collections/WindowCollection.cs new file mode 100644 index 0000000..d8675da --- /dev/null +++ b/Labyrinth3/Crownwood.Magic/Collections/WindowCollection.cs @@ -0,0 +1,63 @@ +// ***************************************************************************** +// +// (c) Crownwood Consulting Limited 2002-2003 +// All rights reserved. The software and associated documentation +// supplied hereunder are the proprietary information of Crownwood Consulting +// Limited, Crownwood, Bracknell, Berkshire, England and are supplied subject +// to licence terms. +// +// Magic Version 1.7.4.0 www.dotnetmagic.com +// ***************************************************************************** + +using Crownwood.Magic.Docking; + +namespace Crownwood.Magic.Collections +{ + public class WindowCollection : CollectionWithEvents + { + public Window Add(Window value) + { + // Use base class to process actual collection operation + base.List.Add(value as object); + + return value; + } + + public void AddRange(Window[] values) + { + // Use existing method to add each array entry + foreach (Window page in values) + Add(page); + } + + public void Remove(Window value) + { + // Use base class to process actual collection operation + base.List.Remove(value as object); + } + + public void Insert(int index, Window value) + { + // Use base class to process actual collection operation + base.List.Insert(index, value as object); + } + + public bool Contains(Window value) + { + // Use base class to process actual collection operation + return base.List.Contains(value as object); + } + + public Window this[int index] + { + // Use base class to process actual collection operation + get { return (base.List[index] as Window); } + } + + public int IndexOf(Window value) + { + // Find the 0 based index of the requested entry + return base.List.IndexOf(value); + } + } +} \ No newline at end of file diff --git a/Labyrinth3/Crownwood.Magic/Collections/WindowDetailCollection.cs b/Labyrinth3/Crownwood.Magic/Collections/WindowDetailCollection.cs new file mode 100644 index 0000000..4f2ea3a --- /dev/null +++ b/Labyrinth3/Crownwood.Magic/Collections/WindowDetailCollection.cs @@ -0,0 +1,63 @@ +// ***************************************************************************** +// +// (c) Crownwood Consulting Limited 2002-2003 +// All rights reserved. The software and associated documentation +// supplied hereunder are the proprietary information of Crownwood Consulting +// Limited, Crownwood, Bracknell, Berkshire, England and are supplied subject +// to licence terms. +// +// Magic Version 1.7.4.0 www.dotnetmagic.com +// ***************************************************************************** + +using Crownwood.Magic.Docking; + +namespace Crownwood.Magic.Collections +{ + public class WindowDetailCollection : CollectionWithEvents + { + public WindowDetail Add(WindowDetail value) + { + // Use base class to process actual collection operation + base.List.Add(value as object); + + return value; + } + + public void AddRange(WindowDetail[] values) + { + // Use existing method to add each array entry + foreach (WindowDetail page in values) + Add(page); + } + + public void Remove(WindowDetail value) + { + // Use base class to process actual collection operation + base.List.Remove(value as object); + } + + public void Insert(int index, WindowDetail value) + { + // Use base class to process actual collection operation + base.List.Insert(index, value as object); + } + + public bool Contains(WindowDetail value) + { + // Use base class to process actual collection operation + return base.List.Contains(value as object); + } + + public WindowDetail this[int index] + { + // Use base class to process actual collection operation + get { return (base.List[index] as WindowDetail); } + } + + public int IndexOf(WindowDetail value) + { + // Find the 0 based index of the requested entry + return base.List.IndexOf(value); + } + } +} \ No newline at end of file diff --git a/Labyrinth3/Crownwood.Magic/Collections/WizardPageCollection.cs b/Labyrinth3/Crownwood.Magic/Collections/WizardPageCollection.cs new file mode 100644 index 0000000..363ff7d --- /dev/null +++ b/Labyrinth3/Crownwood.Magic/Collections/WizardPageCollection.cs @@ -0,0 +1,91 @@ +// ***************************************************************************** +// +// (c) Crownwood Consulting Limited 2002-2003 +// All rights reserved. The software and associated documentation +// supplied hereunder are the proprietary information of Crownwood Consulting +// Limited, Crownwood, Bracknell, Berkshire, England and are supplied subject +// to licence terms. +// +// Magic Version 1.7.4.0 www.dotnetmagic.com +// ***************************************************************************** + +using Crownwood.Magic.Controls; + +namespace Crownwood.Magic.Collections +{ + public class WizardPageCollection : CollectionWithEvents + { + public WizardPage Add(TabPage value) + { + // Create a WizardPage from the TabPage + WizardPage wp = new WizardPage(); + wp.Title = value.Title; + wp.Control = value.Control; + wp.ImageIndex = value.ImageIndex; + wp.ImageList = value.ImageList; + wp.Icon = value.Icon; + wp.Selected = value.Selected; + wp.StartFocus = value.StartFocus; + + return Add(wp); + } + + public WizardPage Add(WizardPage value) + { + // Use base class to process actual collection operation + base.List.Add(value as object); + + return value; + } + + public void AddRange(WizardPage[] values) + { + // Use existing method to add each array entry + foreach (WizardPage page in values) + Add(page); + } + + public void Remove(WizardPage value) + { + // Use base class to process actual collection operation + base.List.Remove(value as object); + } + + public void Insert(int index, WizardPage value) + { + // Use base class to process actual collection operation + base.List.Insert(index, value as object); + } + + public bool Contains(WizardPage value) + { + // Use base class to process actual collection operation + return base.List.Contains(value as object); + } + + public WizardPage this[int index] + { + // Use base class to process actual collection operation + get { return (base.List[index] as WizardPage); } + } + + public WizardPage this[string title] + { + get + { + // Search for a Page with a matching title + foreach (WizardPage page in base.List) + if (page.Title == title) + return page; + + return null; + } + } + + public int IndexOf(WizardPage value) + { + // Find the 0 based index of the requested entry + return base.List.IndexOf(value); + } + } +} \ No newline at end of file diff --git a/Labyrinth3/Crownwood.Magic/Collections/ZoneCollection.cs b/Labyrinth3/Crownwood.Magic/Collections/ZoneCollection.cs new file mode 100644 index 0000000..2d32b2d --- /dev/null +++ b/Labyrinth3/Crownwood.Magic/Collections/ZoneCollection.cs @@ -0,0 +1,63 @@ +// ***************************************************************************** +// +// (c) Crownwood Consulting Limited 2002-2003 +// All rights reserved. The software and associated documentation +// supplied hereunder are the proprietary information of Crownwood Consulting +// Limited, Crownwood, Bracknell, Berkshire, England and are supplied subject +// to licence terms. +// +// Magic Version 1.7.4.0 www.dotnetmagic.com +// ***************************************************************************** + +using Crownwood.Magic.Docking; + +namespace Crownwood.Magic.Collections +{ + public class ZoneCollection : CollectionWithEvents + { + public Zone Add(Zone value) + { + // Use base class to process actual collection operation + base.List.Add(value as object); + + return value; + } + + public void AddRange(Zone[] values) + { + // Use existing method to add each array entry + foreach (Zone page in values) + Add(page); + } + + public void Remove(Zone value) + { + // Use base class to process actual collection operation + base.List.Remove(value as object); + } + + public void Insert(int index, Zone value) + { + // Use base class to process actual collection operation + base.List.Insert(index, value as object); + } + + public bool Contains(Zone value) + { + // Use base class to process actual collection operation + return base.List.Contains(value as object); + } + + public Zone this[int index] + { + // Use base class to process actual collection operation + get { return (base.List[index] as Zone); } + } + + public int IndexOf(Zone value) + { + // Find the 0 based index of the requested entry + return base.List.IndexOf(value); + } + } +} \ No newline at end of file diff --git a/Labyrinth3/Crownwood.Magic/Common/ColorHelper.cs b/Labyrinth3/Crownwood.Magic/Common/ColorHelper.cs new file mode 100644 index 0000000..614ba2c --- /dev/null +++ b/Labyrinth3/Crownwood.Magic/Common/ColorHelper.cs @@ -0,0 +1,80 @@ +// ***************************************************************************** +// +// (c) Crownwood Consulting Limited 2002-2003 +// All rights reserved. The software and associated documentation +// supplied hereunder are the proprietary information of Crownwood Consulting +// Limited, Crownwood, Bracknell, Berkshire, England and are supplied subject +// to licence terms. +// +// Magic Version 1.7.4.0 www.dotnetmagic.com +// ***************************************************************************** + +using System.Drawing; + +//using Crownwood.Magic.Win32; + +namespace Crownwood.Magic.Common +{ + public class ColorHelper + { + public static Color TabBackgroundFromBaseColor(Color backColor) + { + Color backIDE; + + // Check for the 'Classic' control color + if ((backColor.R == 212) && + (backColor.G == 208) && + (backColor.B == 200)) + { + // Use the exact background for this color + backIDE = Color.FromArgb(247, 243, 233); + } + else + { + // Check for the 'XP' control color + if ((backColor.R == 236) && + (backColor.G == 233) && + (backColor.B == 216)) + { + // Use the exact background for this color + backIDE = Color.FromArgb(255, 251, 233); + } + else + { + // Calculate the IDE background color as only half as dark as the control color + int red = 255 - ((255 - backColor.R) / 2); + int green = 255 - ((255 - backColor.G) / 2); + int blue = 255 - ((255 - backColor.B) / 2); + backIDE = Color.FromArgb(red, green, blue); + } + } + + return backIDE; + } + + public static Color CalculateColor(Color front, Color back, int alpha) + { + // Use alpha blending to brigthen the colors but don't use it + // directly. Instead derive an opaque color that we can use. + Color frontColor = Color.FromArgb(255, front); + Color backColor = Color.FromArgb(255, back); + + float frontRed = frontColor.R; + float frontGreen = frontColor.G; + float frontBlue = frontColor.B; + float backRed = backColor.R; + float backGreen = backColor.G; + float backBlue = backColor.B; + + float fRed = (frontRed * alpha / 255) + backRed * ((float)(255 - alpha) / 255); + float fGreen = (frontGreen * alpha / 255) + backGreen * ((float)(255 - alpha) / 255); + float fBlue = (frontBlue * alpha / 255) + backBlue * ((float)(255 - alpha) / 255); + + byte newRed = (byte)fRed; + byte newGreen = (byte)fGreen; + byte newBlue = (byte)fBlue; + + return Color.FromArgb(255, newRed, newGreen, newBlue); + } + } +} \ No newline at end of file diff --git a/Labyrinth3/Crownwood.Magic/Common/ControlHelper.cs b/Labyrinth3/Crownwood.Magic/Common/ControlHelper.cs new file mode 100644 index 0000000..c1e8a4c --- /dev/null +++ b/Labyrinth3/Crownwood.Magic/Common/ControlHelper.cs @@ -0,0 +1,124 @@ +// ***************************************************************************** +// +// (c) Crownwood Consulting Limited 2002-2003 +// All rights reserved. The software and associated documentation +// supplied hereunder are the proprietary information of Crownwood Consulting +// Limited, Crownwood, Bracknell, Berkshire, England and are supplied subject +// to licence terms. +// +// Magic Version 1.7.4.0 www.dotnetmagic.com +// ***************************************************************************** + +using System.Windows.Forms; + +namespace Crownwood.Magic.Common +{ + public class ControlHelper + { + public static void RemoveAll(Control control) + { + if ((control != null) && (control.Controls.Count > 0)) + { + Button tempButton = null; + Form parentForm = control.FindForm(); + + if (parentForm != null) + { + // Create a hidden, temporary button + tempButton = new Button(); + tempButton.Visible = false; + + // Add this temporary button to the parent form + parentForm.Controls.Add(tempButton); + + // Must ensure that temp button is the active one + parentForm.ActiveControl = tempButton; + } + + // Remove all entries from target + control.Controls.Clear(); + + if (parentForm != null) + { + // Remove the temporary button + tempButton.Dispose(); + parentForm.Controls.Remove(tempButton); + } + } + } + + public static void Remove(Control.ControlCollection coll, Control item) + { + if ((coll != null) && (item != null)) + { + Button tempButton = null; + Form parentForm = item.FindForm(); + + if (parentForm != null) + { + // Create a hidden, temporary button + tempButton = new Button(); + tempButton.Visible = false; + + // Add this temporary button to the parent form + parentForm.Controls.Add(tempButton); + + // Must ensure that temp button is the active one + parentForm.ActiveControl = tempButton; + } + + // Remove our target control + coll.Remove(item); + + if (parentForm != null) + { + // Remove the temporary button + tempButton.Dispose(); + parentForm.Controls.Remove(tempButton); + } + } + } + + public static void RemoveAt(Control.ControlCollection coll, int index) + { + if (coll != null) + { + if ((index >= 0) && (index < coll.Count)) + { + Remove(coll, coll[index]); + } + } + } + + public static void RemoveForm(Control source, Form form) + { + ContainerControl container = source.FindForm() as ContainerControl; + + if (container == null) + container = source as ContainerControl; + + Button tempButton = new Button(); + + if (container != null) + { + tempButton.Visible = false; + + // Add this temporary button to the parent form + container.Controls.Add(tempButton); + + // Must ensure that temp button is the active one + container.ActiveControl = tempButton; + } + + // Remove Form parent + form.Parent = null; + + if (container != null) + { + // Remove the temporary button + tempButton.Dispose(); + container.Controls.Remove(tempButton); + } + } + } +} \ No newline at end of file diff --git a/Labyrinth3/Crownwood.Magic/Common/ConversionHelper.cs b/Labyrinth3/Crownwood.Magic/Common/ConversionHelper.cs new file mode 100644 index 0000000..a42190a --- /dev/null +++ b/Labyrinth3/Crownwood.Magic/Common/ConversionHelper.cs @@ -0,0 +1,46 @@ +// ***************************************************************************** +// +// (c) Crownwood Consulting Limited 2002-2003 +// All rights reserved. The software and associated documentation +// supplied hereunder are the proprietary information of Crownwood Consulting +// Limited, Crownwood, Bracknell, Berkshire, England and are supplied subject +// to licence terms. +// +// Magic Version 1.7.4.0 www.dotnetmagic.com +// ***************************************************************************** + +using System; +using System.Drawing; + +namespace Crownwood.Magic.Common +{ + public class ConversionHelper + { + // Faster performance to cache the converters and type objects, rather + // than keep recreating them each time a conversion is required + protected static SizeConverter _sc = new SizeConverter(); + + protected static PointConverter _pc = new PointConverter(); + protected static Type _stringType = Type.GetType("System.String"); + + public static string SizeToString(Size size) + { + return (string)_sc.ConvertTo(size, _stringType); + } + + public static Size StringToSize(string str) + { + return (Size)_sc.ConvertFrom(str); + } + + public static string PointToString(Point point) + { + return (string)_pc.ConvertTo(point, _stringType); + } + + public static Point StringToPoint(string str) + { + return (Point)_pc.ConvertFrom(str); + } + } +} \ No newline at end of file diff --git a/Labyrinth3/Crownwood.Magic/Common/DebugHelper.cs b/Labyrinth3/Crownwood.Magic/Common/DebugHelper.cs new file mode 100644 index 0000000..cc16ba8 --- /dev/null +++ b/Labyrinth3/Crownwood.Magic/Common/DebugHelper.cs @@ -0,0 +1,53 @@ +// ***************************************************************************** +// +// (c) Crownwood Consulting Limited 2002-2003 +// All rights reserved. The software and associated documentation +// supplied hereunder are the proprietary information of Crownwood Consulting +// Limited, Crownwood, Bracknell, Berkshire, England and are supplied subject +// to licence terms. +// +// Magic Version 1.7.4.0 www.dotnetmagic.com +// ***************************************************************************** + +using System; +using System.Windows.Forms; + +namespace Crownwood.Magic.Common +{ + public class DebugHelper + { + public static void ListControls(Control.ControlCollection controls) + { + ListControls("Control Collection", controls, false); + } + + public static void ListControls(string title, Control.ControlCollection controls) + { + ListControls(title, controls, false); + } + + public static void ListControls(string title, Control.ControlCollection controls, bool fullName) + { + // Output title first + Console.WriteLine("\n{0}", title); + + // Find number of controls in the collection + int count = controls.Count; + + // Output details for each + for (int index = 0; index < count; index++) + { + Control c = controls[index]; + + string typeName; + + if (fullName) + typeName = c.GetType().FullName; + else + typeName = c.GetType().Name; + + Console.WriteLine("{0} V:{1} T:{2} N:{3}", index, c.Visible, typeName, c.Name); + } + } + } +} \ No newline at end of file diff --git a/Labyrinth3/Crownwood.Magic/Common/DrawHelper.cs b/Labyrinth3/Crownwood.Magic/Common/DrawHelper.cs new file mode 100644 index 0000000..477d221 --- /dev/null +++ b/Labyrinth3/Crownwood.Magic/Common/DrawHelper.cs @@ -0,0 +1,490 @@ +// ***************************************************************************** +// +// (c) Crownwood Consulting Limited 2002-2003 +// All rights reserved. The software and associated documentation +// supplied hereunder are the proprietary information of Crownwood Consulting +// Limited, Crownwood, Bracknell, Berkshire, England and are supplied subject +// to licence terms. +// +// Magic Version 1.7.4.0 www.dotnetmagic.com +// ***************************************************************************** + +using System; +using System.Drawing; +using System.Drawing.Drawing2D; +using System.Windows.Forms; + +//using Crownwood.Magic.Win32; + +namespace Crownwood.Magic.Common +{ + public class DrawHelper + { + public enum CommandState + { + Normal, + HotTrack, + Pushed + } + + protected static IntPtr _halfToneBrush = IntPtr.Zero; + + public static void DrawReverseString(Graphics g, + String drawText, + Font drawFont, + Rectangle drawRect, + Brush drawBrush, + StringFormat drawFormat) + { + GraphicsContainer container = g.BeginContainer(); + + // The text will be rotated around the origin (0,0) and so needs moving + // back into position by using a transform + g.TranslateTransform(drawRect.Left * 2 + drawRect.Width, + drawRect.Top * 2 + drawRect.Height); + + // Rotate the text by 180 degress to reverse the direction + g.RotateTransform(180); + + // Draw the string as normal and let then transforms do the work + g.DrawString(drawText, drawFont, drawBrush, drawRect, drawFormat); + + g.EndContainer(container); + } + + public static void DrawPlainRaised(Graphics g, + Rectangle boxRect, + Color baseColor) + { + using (Pen lighlight = new Pen(ControlPaint.LightLight(baseColor)), + dark = new Pen(ControlPaint.DarkDark(baseColor))) + { + g.DrawLine(lighlight, boxRect.Left, boxRect.Bottom, boxRect.Left, boxRect.Top); + g.DrawLine(lighlight, boxRect.Left, boxRect.Top, boxRect.Right, boxRect.Top); + g.DrawLine(dark, boxRect.Right, boxRect.Top, boxRect.Right, boxRect.Bottom); + g.DrawLine(dark, boxRect.Right, boxRect.Bottom, boxRect.Left, boxRect.Bottom); + } + } + + public static void DrawPlainSunken(Graphics g, + Rectangle boxRect, + Color baseColor) + { + using (Pen lighlight = new Pen(ControlPaint.LightLight(baseColor)), + dark = new Pen(ControlPaint.DarkDark(baseColor))) + { + g.DrawLine(dark, boxRect.Left, boxRect.Bottom, boxRect.Left, boxRect.Top); + g.DrawLine(dark, boxRect.Left, boxRect.Top, boxRect.Right, boxRect.Top); + g.DrawLine(lighlight, boxRect.Right, boxRect.Top, boxRect.Right, boxRect.Bottom); + g.DrawLine(lighlight, boxRect.Right, boxRect.Bottom, boxRect.Left, boxRect.Bottom); + } + } + + public static void DrawPlainRaisedBorder(Graphics g, + Rectangle rect, + Color lightLight, + Color baseColor, + Color dark, + Color darkDark) + { + if ((rect.Width > 2) && (rect.Height > 2)) + { + using (Pen ll = new Pen(lightLight), + b = new Pen(baseColor), + d = new Pen(dark), + dd = new Pen(darkDark)) + { + int left = rect.Left; + int top = rect.Top; + int right = rect.Right; + int bottom = rect.Bottom; + + // Draw the top border + g.DrawLine(b, right - 1, top, left, top); + g.DrawLine(ll, right - 2, top + 1, left + 1, top + 1); + g.DrawLine(b, right - 3, top + 2, left + 2, top + 2); + + // Draw the left border + g.DrawLine(b, left, top, left, bottom - 1); + g.DrawLine(ll, left + 1, top + 1, left + 1, bottom - 2); + g.DrawLine(b, left + 2, top + 2, left + 2, bottom - 3); + + // Draw the right + g.DrawLine(dd, right - 1, top + 1, right - 1, bottom - 1); + g.DrawLine(d, right - 2, top + 2, right - 2, bottom - 2); + g.DrawLine(b, right - 3, top + 3, right - 3, bottom - 3); + + // Draw the bottom + g.DrawLine(dd, right - 1, bottom - 1, left, bottom - 1); + g.DrawLine(d, right - 2, bottom - 2, left + 1, bottom - 2); + g.DrawLine(b, right - 3, bottom - 3, left + 2, bottom - 3); + } + } + } + + public static void DrawPlainRaisedBorderTopOrBottom(Graphics g, + Rectangle rect, + Color lightLight, + Color baseColor, + Color dark, + Color darkDark, + bool drawTop) + { + if ((rect.Width > 2) && (rect.Height > 2)) + { + using (Pen ll = new Pen(lightLight), + b = new Pen(baseColor), + d = new Pen(dark), + dd = new Pen(darkDark)) + { + int left = rect.Left; + int top = rect.Top; + int right = rect.Right; + int bottom = rect.Bottom; + + if (drawTop) + { + // Draw the top border + g.DrawLine(b, right - 1, top, left, top); + g.DrawLine(ll, right - 1, top + 1, left, top + 1); + g.DrawLine(b, right - 1, top + 2, left, top + 2); + } + else + { + // Draw the bottom + g.DrawLine(dd, right - 1, bottom - 1, left, bottom - 1); + g.DrawLine(d, right - 1, bottom - 2, left, bottom - 2); + g.DrawLine(b, right - 1, bottom - 3, left, bottom - 3); + } + } + } + } + + public static void DrawPlainSunkenBorder(Graphics g, + Rectangle rect, + Color lightLight, + Color baseColor, + Color dark, + Color darkDark) + { + if ((rect.Width > 2) && (rect.Height > 2)) + { + using (Pen ll = new Pen(lightLight), + b = new Pen(baseColor), + d = new Pen(dark), + dd = new Pen(darkDark)) + { + int left = rect.Left; + int top = rect.Top; + int right = rect.Right; + int bottom = rect.Bottom; + + // Draw the top border + g.DrawLine(d, right - 1, top, left, top); + g.DrawLine(dd, right - 2, top + 1, left + 1, top + 1); + g.DrawLine(b, right - 3, top + 2, left + 2, top + 2); + + // Draw the left border + g.DrawLine(d, left, top, left, bottom - 1); + g.DrawLine(dd, left + 1, top + 1, left + 1, bottom - 2); + g.DrawLine(b, left + 2, top + 2, left + 2, bottom - 3); + + // Draw the right + g.DrawLine(ll, right - 1, top + 1, right - 1, bottom - 1); + g.DrawLine(b, right - 2, top + 2, right - 2, bottom - 2); + g.DrawLine(b, right - 3, top + 3, right - 3, bottom - 3); + + // Draw the bottom + g.DrawLine(ll, right - 1, bottom - 1, left, bottom - 1); + g.DrawLine(b, right - 2, bottom - 2, left + 1, bottom - 2); + g.DrawLine(b, right - 3, bottom - 3, left + 2, bottom - 3); + } + } + } + + public static void DrawPlainSunkenBorderTopOrBottom(Graphics g, + Rectangle rect, + Color lightLight, + Color baseColor, + Color dark, + Color darkDark, + bool drawTop) + { + if ((rect.Width > 2) && (rect.Height > 2)) + { + using (Pen ll = new Pen(lightLight), + b = new Pen(baseColor), + d = new Pen(dark), + dd = new Pen(darkDark)) + { + int left = rect.Left; + int top = rect.Top; + int right = rect.Right; + int bottom = rect.Bottom; + + if (drawTop) + { + // Draw the top border + g.DrawLine(d, right - 1, top, left, top); + g.DrawLine(dd, right - 1, top + 1, left, top + 1); + g.DrawLine(b, right - 1, top + 2, left, top + 2); + } + else + { + // Draw the bottom + g.DrawLine(ll, right - 1, bottom - 1, left, bottom - 1); + g.DrawLine(b, right - 1, bottom - 2, left, bottom - 2); + g.DrawLine(b, right - 1, bottom - 3, left, bottom - 3); + } + } + } + } + + public static void DrawButtonCommand(Graphics g, + VisualStyle style, + Direction direction, + Rectangle drawRect, + CommandState state, + Color baseColor, + Color trackLight, + Color trackBorder) + { + Rectangle rect = new Rectangle(drawRect.Left, drawRect.Top, drawRect.Width - 1, drawRect.Height - 1); + + // Draw background according to style + switch (style) + { + case VisualStyle.Plain: + // Draw background with back color + using (SolidBrush backBrush = new SolidBrush(baseColor)) + g.FillRectangle(backBrush, rect); + + // Modify according to state + switch (state) + { + case CommandState.HotTrack: + DrawPlainRaised(g, rect, baseColor); + break; + + case CommandState.Pushed: + DrawPlainSunken(g, rect, baseColor); + break; + } + break; + + case VisualStyle.IDE: + // Draw according to state + switch (state) + { + case CommandState.Normal: + // Draw background with back color + using (SolidBrush backBrush = new SolidBrush(baseColor)) + g.FillRectangle(backBrush, rect); + break; + + case CommandState.HotTrack: + g.FillRectangle(Brushes.White, rect); + + using (SolidBrush trackBrush = new SolidBrush(trackLight)) + g.FillRectangle(trackBrush, rect); + + using (Pen trackPen = new Pen(trackBorder)) + g.DrawRectangle(trackPen, rect); + break; + + case CommandState.Pushed: + //TODO: draw in a darker background color + break; + } + break; + } + } + + public static void DrawSeparatorCommand(Graphics g, + VisualStyle style, + Direction direction, + Rectangle drawRect, + Color baseColor) + { + // Drawing depends on the visual style required + if (style == VisualStyle.IDE) + { + // Draw a single separating line + using (Pen dPen = new Pen(ControlPaint.Dark(baseColor))) + { + if (direction == Direction.Horizontal) + g.DrawLine(dPen, drawRect.Left, drawRect.Top, + drawRect.Left, drawRect.Bottom - 1); + else + g.DrawLine(dPen, drawRect.Left, drawRect.Top, + drawRect.Right - 1, drawRect.Top); + } + } + else + { + // Draw a dark/light combination of lines to give an indent + using (Pen lPen = new Pen(ControlPaint.Dark(baseColor)), + llPen = new Pen(ControlPaint.LightLight(baseColor))) + { + if (direction == Direction.Horizontal) + { + g.DrawLine(lPen, drawRect.Left, drawRect.Top, drawRect.Left, drawRect.Bottom - 1); + g.DrawLine(llPen, drawRect.Left + 1, drawRect.Top, drawRect.Left + 1, drawRect.Bottom - 1); + } + else + { + g.DrawLine(lPen, drawRect.Left, drawRect.Top, drawRect.Right - 1, drawRect.Top); + g.DrawLine(llPen, drawRect.Left, drawRect.Top + 1, drawRect.Right - 1, drawRect.Top + 1); + } + } + } + } + + public static void DrawDragRectangle(Rectangle newRect, int indent) + { + DrawDragRectangles(new Rectangle[] { newRect }, indent); + } + + public static void DrawDragRectangles(Rectangle[] newRects, int indent) + { + foreach (Rectangle r in newRects) + ControlPaint.DrawReversibleFrame(r, Color.Gray, FrameStyle.Thick); + + /* + if (newRects.Length > 0) + { + // Create the first region + IntPtr newRegion = CreateRectangleRegion(newRects[0], indent); + + for(int index=1; index= 1) + { + Size ourSize = this.Size; + + // Get the first child (there should not be any others) + Control child = this.Controls[0]; + + // Define new position + child.Location = new Point(_borderWidth, _borderWidth); + + // Define new size + child.Size = new Size(ourSize.Width - _borderWidth * 2, ourSize.Height - _borderWidth * 2); + } + } + } +} \ No newline at end of file diff --git a/Labyrinth3/Crownwood.Magic/Controls/BorderForControl/BorderForControl.resx b/Labyrinth3/Crownwood.Magic/Controls/BorderForControl/BorderForControl.resx new file mode 100644 index 0000000..7e32396 --- /dev/null +++ b/Labyrinth3/Crownwood.Magic/Controls/BorderForControl/BorderForControl.resx @@ -0,0 +1,42 @@ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + text/microsoft-resx + + + 1.0.0.0 + + + System.Resources.ResXResourceReader, System.Windows.Forms, Version=1.0.3102.0, Culture=neutral, PublicKeyToken=b77a5c561934e089 + + + System.Resources.ResXResourceWriter, System.Windows.Forms, Version=1.0.3102.0, Culture=neutral, PublicKeyToken=b77a5c561934e089 + + diff --git a/Labyrinth3/Crownwood.Magic/Controls/InertButton.bmp b/Labyrinth3/Crownwood.Magic/Controls/InertButton.bmp new file mode 100644 index 0000000..8097190 Binary files /dev/null and b/Labyrinth3/Crownwood.Magic/Controls/InertButton.bmp differ diff --git a/Labyrinth3/Crownwood.Magic/Controls/InertButton/InertButton.cs b/Labyrinth3/Crownwood.Magic/Controls/InertButton/InertButton.cs new file mode 100644 index 0000000..121c94d --- /dev/null +++ b/Labyrinth3/Crownwood.Magic/Controls/InertButton/InertButton.cs @@ -0,0 +1,375 @@ +// ***************************************************************************** +// +// (c) Crownwood Consulting Limited 2002-2003 +// All rights reserved. The software and associated documentation +// supplied hereunder are the proprietary information of Crownwood Consulting +// Limited, Crownwood, Bracknell, Berkshire, England and are supplied subject +// to licence terms. +// +// Magic Version 1.7.4.0 www.dotnetmagic.com +// ***************************************************************************** + +using System; +using System.ComponentModel; +using System.Drawing; +using System.Drawing.Imaging; +using System.Windows.Forms; + +namespace Crownwood.Magic.Controls +{ + [ToolboxBitmap(typeof(InertButton))] + [DefaultProperty("PopupStyle")] + public class InertButton : Control + { + // Instance fields + protected int _borderWidth; + + protected bool _mouseOver; + protected bool _mouseCapture; + protected bool _popupStyle; + protected int _imageIndexEnabled; + protected int _imageIndexDisabled; + protected ImageList _imageList; + protected ImageAttributes _imageAttr; + protected MouseButtons _mouseButton; + + public InertButton() + { + InternalConstruct(null, -1, -1, null); + } + + public InertButton(ImageList imageList, int imageIndexEnabled) + { + InternalConstruct(imageList, imageIndexEnabled, -1, null); + } + + public InertButton(ImageList imageList, int imageIndexEnabled, int imageIndexDisabled) + { + InternalConstruct(imageList, imageIndexEnabled, imageIndexDisabled, null); + } + + public InertButton(ImageList imageList, int imageIndexEnabled, int imageIndexDisabled, ImageAttributes imageAttr) + { + InternalConstruct(imageList, imageIndexEnabled, imageIndexDisabled, imageAttr); + } + + public void InternalConstruct(ImageList imageList, + int imageIndexEnabled, + int imageIndexDisabled, + ImageAttributes imageAttr) + { + // Remember parameters + _imageList = imageList; + _imageIndexEnabled = imageIndexEnabled; + _imageIndexDisabled = imageIndexDisabled; + _imageAttr = imageAttr; + + // Set initial state + _borderWidth = 2; + _mouseOver = false; + _mouseCapture = false; + _popupStyle = true; + _mouseButton = MouseButtons.None; + + // Prevent drawing flicker by blitting from memory in WM_PAINT + SetStyle(ControlStyles.DoubleBuffer | + ControlStyles.AllPaintingInWmPaint | + ControlStyles.UserPaint, true); + + // Prevent base class from trying to generate double click events and + // so testing clicks against the double click time and rectangle. Getting + // rid of this allows the user to press then button very quickly. + SetStyle(ControlStyles.StandardDoubleClick, false); + + // Should not be allowed to select this control + SetStyle(ControlStyles.Selectable, false); + } + + [Category("Appearance")] + [DefaultValue(null)] + public ImageList ImageList + { + get { return _imageList; } + + set + { + if (_imageList != value) + { + _imageList = value; + Invalidate(); + } + } + } + + [Category("Appearance")] + [DefaultValue(-1)] + public int ImageIndexEnabled + { + get { return _imageIndexEnabled; } + + set + { + if (_imageIndexEnabled != value) + { + _imageIndexEnabled = value; + Invalidate(); + } + } + } + + [Category("Appearance")] + [DefaultValue(-1)] + public int ImageIndexDisabled + { + get { return _imageIndexDisabled; } + + set + { + if (_imageIndexDisabled != value) + { + _imageIndexDisabled = value; + Invalidate(); + } + } + } + + [Category("Appearance")] + [DefaultValue(null)] + public ImageAttributes ImageAttributes + { + get { return _imageAttr; } + + set + { + if (_imageAttr != value) + { + _imageAttr = value; + Invalidate(); + } + } + } + + [Category("Appearance")] + [DefaultValue(2)] + public int BorderWidth + { + get { return _borderWidth; } + + set + { + if (_borderWidth != value) + { + _borderWidth = value; + Invalidate(); + } + } + } + + [Category("Appearance")] + [DefaultValue(true)] + public bool PopupStyle + { + get { return _popupStyle; } + + set + { + if (_popupStyle != value) + { + _popupStyle = value; + Invalidate(); + } + } + } + + protected override void OnMouseDown(MouseEventArgs e) + { + if (!_mouseCapture) + { + // Mouse is over the button and being pressed, so enter the button depressed + // state and also remember the original button that was pressed. As we only + // generate an event when the same button is released. + _mouseOver = true; + _mouseCapture = true; + _mouseButton = e.Button; + + // Redraw to show button state + Invalidate(); + } + + base.OnMouseDown(e); + } + + protected override void OnMouseUp(MouseEventArgs e) + { + // Are we waiting for this button to go up? + if (e.Button == _mouseButton) + { + // Set state back to become normal + _mouseOver = false; + _mouseCapture = false; + + // Redraw to show button state + Invalidate(); + } + else + { + // We don't want to lose capture of mouse + Capture = true; + } + + base.OnMouseUp(e); + } + + protected override void OnMouseMove(MouseEventArgs e) + { + // Is mouse point inside our client rectangle + bool over = this.ClientRectangle.Contains(new Point(e.X, e.Y)); + + // If entering the button area or leaving the button area... + if (over != _mouseOver) + { + // Update state + _mouseOver = over; + + // Redraw to show button state + Invalidate(); + } + + base.OnMouseMove(e); + } + + protected override void OnMouseEnter(EventArgs e) + { + // Update state to reflect mouse over the button area + _mouseOver = true; + + // Redraw to show button state + Invalidate(); + + base.OnMouseEnter(e); + } + + protected override void OnMouseLeave(EventArgs e) + { + // Update state to reflect mouse not over the button area + _mouseOver = false; + + // Redraw to show button state + Invalidate(); + + base.OnMouseLeave(e); + } + + protected override void OnPaint(PaintEventArgs e) + { + // Do we have an image list for use? + if (_imageList != null) + { + // Is the button disabled? + if (!this.Enabled) + { + // Do we have an image for showing when disabled? + if (_imageIndexDisabled != -1) + { + // Any caller supplied attributes to modify drawing? + if (null == _imageAttr) + { + // No, so use the simple DrawImage method + e.Graphics.DrawImage(_imageList.Images[_imageIndexDisabled], new Point(1, 1)); + } + else + { + // Yes, need to use the more complex DrawImage method instead + Image image = _imageList.Images[_imageIndexDisabled]; + + // Three points provided are upper-left, upper-right and + // lower-left of the destination parallelogram. + Point[] pts = new Point[3]; + pts[0].X = 1; + pts[0].Y = 1; + pts[1].X = pts[0].X + image.Width; + pts[1].Y = pts[0].Y; + pts[2].X = pts[0].X; + pts[2].Y = pts[1].Y + image.Height; + + e.Graphics.DrawImage(_imageList.Images[_imageIndexDisabled], + pts, + new Rectangle(0, 0, image.Width, image.Height), + GraphicsUnit.Pixel, _imageAttr); + } + } + else + { + // No disbled image, how about an enabled image we can draw grayed? + if (_imageIndexEnabled != -1) + { + // Yes, draw the enabled image but with color drained away + ControlPaint.DrawImageDisabled(e.Graphics, _imageList.Images[_imageIndexEnabled], 1, 1, this.BackColor); + } + else + { + // No images at all. Do nothing. + } + } + } + else + { + // Button is enabled, any caller supplied attributes to modify drawing? + if (null == _imageAttr) + { + // No, so use the simple DrawImage method + e.Graphics.DrawImage(_imageList.Images[_imageIndexEnabled], + (_mouseOver && _mouseCapture ? new Point(2, 2) : + new Point(1, 1))); + } + else + { + // Yes, need to use the more complex DrawImage method instead + Image image = _imageList.Images[_imageIndexEnabled]; + + // Three points provided are upper-left, upper-right and + // lower-left of the destination parallelogram. + Point[] pts = new Point[3]; + pts[0].X = (_mouseOver && _mouseCapture) ? 2 : 1; + pts[0].Y = (_mouseOver && _mouseCapture) ? 2 : 1; + pts[1].X = pts[0].X + image.Width; + pts[1].Y = pts[0].Y; + pts[2].X = pts[0].X; + pts[2].Y = pts[1].Y + image.Height; + + e.Graphics.DrawImage(_imageList.Images[_imageIndexEnabled], + pts, + new Rectangle(0, 0, image.Width, image.Height), + GraphicsUnit.Pixel, _imageAttr); + } + + ButtonBorderStyle bs; + + // Decide on the type of border to draw around image + if (_popupStyle) + { + if (_mouseOver && this.Enabled) + bs = (_mouseCapture ? ButtonBorderStyle.Inset : ButtonBorderStyle.Outset); + else + bs = ButtonBorderStyle.Solid; + } + else + { + if (this.Enabled) + bs = ((_mouseOver && _mouseCapture) ? ButtonBorderStyle.Inset : ButtonBorderStyle.Outset); + else + bs = ButtonBorderStyle.Solid; + } + + ControlPaint.DrawBorder(e.Graphics, this.ClientRectangle, + this.BackColor, _borderWidth, bs, + this.BackColor, _borderWidth, bs, + this.BackColor, _borderWidth, bs, + this.BackColor, _borderWidth, bs); + } + } + + base.OnPaint(e); + } + } +} \ No newline at end of file diff --git a/Labyrinth3/Crownwood.Magic/Controls/InertButton/InertButton.resx b/Labyrinth3/Crownwood.Magic/Controls/InertButton/InertButton.resx new file mode 100644 index 0000000..7e32396 --- /dev/null +++ b/Labyrinth3/Crownwood.Magic/Controls/InertButton/InertButton.resx @@ -0,0 +1,42 @@ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + text/microsoft-resx + + + 1.0.0.0 + + + System.Resources.ResXResourceReader, System.Windows.Forms, Version=1.0.3102.0, Culture=neutral, PublicKeyToken=b77a5c561934e089 + + + System.Resources.ResXResourceWriter, System.Windows.Forms, Version=1.0.3102.0, Culture=neutral, PublicKeyToken=b77a5c561934e089 + + diff --git a/Labyrinth3/Crownwood.Magic/Controls/ResizeBar/ResizeBar.cs b/Labyrinth3/Crownwood.Magic/Controls/ResizeBar/ResizeBar.cs new file mode 100644 index 0000000..38658ab --- /dev/null +++ b/Labyrinth3/Crownwood.Magic/Controls/ResizeBar/ResizeBar.cs @@ -0,0 +1,409 @@ +// ***************************************************************************** +// +// (c) Crownwood Consulting Limited 2002-2003 +// All rights reserved. The software and associated documentation +// supplied hereunder are the proprietary information of Crownwood Consulting +// Limited, Crownwood, Bracknell, Berkshire, England and are supplied subject +// to licence terms. +// +// Magic Version 1.7.4.0 www.dotnetmagic.com +// ***************************************************************************** + +using Crownwood.Magic.Common; +using Crownwood.Magic.Docking; +using System.ComponentModel; +using System.Drawing; +using System.Windows.Forms; + +namespace Crownwood.Magic.Controls +{ + public interface IResizeSource + { + bool CanResize(ResizeBar bar); + + bool StartResizeOperation(ResizeBar bar, ref Rectangle screenBoundary); + + void EndResizeOperation(ResizeBar bar, int delta); + + Color ResizeBarColor { get; } + int ResizeBarVector { get; } + VisualStyle Style { get; } + Color BackgroundColor { get; } + } + + [ToolboxItem(false)] + public class ResizeBar : Control + { + // Class constants + protected static int _ideLength = 4; + + protected static int _plainLength = 6; + + // Instance fields + protected VisualStyle _style; + + protected Direction _direction; + protected bool _resizing; + protected Point _pointStart; + protected Point _pointCurrent; + protected Rectangle _boundary; + protected IResizeSource _resizeSource; + + public ResizeBar(Direction direction, IResizeSource resizeSource) + { + // Define initial state + _direction = direction; + _resizing = false; + _resizeSource = resizeSource; + + // Always default to Control color + this.BackColor = _resizeSource.ResizeBarColor; + this.ForeColor = SystemColors.ControlText; + + UpdateStyle(_resizeSource.Style); + } + + public VisualStyle Style + { + get { return _style; } + + set + { + if (_style != value) + UpdateStyle(value); + } + } + + public Direction Direction + { + get { return _direction; } + + set + { + if (_direction != value) + { + _direction = value; + UpdateStyle(_style); + } + } + } + + public int Length + { + get + { + int vector = _resizeSource.ResizeBarVector; + + if (vector == -1) + { + if (_style == VisualStyle.IDE) + vector = _ideLength; + else + vector = _plainLength; + } + + return vector; + } + + set + { + // If a change in vector... + if (value != this.Length) + { + // Force update of the height/width + UpdateStyle(_resizeSource.Style); + } + } + } + + public virtual void PropogateNameValue(PropogateName name, object value) + { + if (name == PropogateName.ResizeBarVector) + this.Length = (int)value; + + if (name == PropogateName.ResizeBarColor) + { + this.BackColor = (Color)value; + Invalidate(); + } + } + + protected void UpdateStyle(VisualStyle newStyle) + { + _style = newStyle; + + int vector = this.Length; + + if (_direction == Direction.Vertical) + this.Height = vector; + else + this.Width = vector; + + Invalidate(); + } + + protected bool StartResizeOperation(MouseEventArgs e) + { + if (_resizeSource != null) + { + if (_resizeSource.CanResize(this)) + { + if (_resizeSource.StartResizeOperation(this, ref _boundary)) + { + // Record the starting screen position + _pointStart = PointToScreen(new Point(e.X, e.Y)); + + // Record the current position being drawn + _pointCurrent = _pointStart; + + // Draw the starting position + DrawResizeIndicator(_pointCurrent); + + return true; + } + } + } + + return false; + } + + protected void EndResizeOperation(MouseEventArgs e) + { + if (_resizeSource != null) + { + // Undraw the current position + DrawResizeIndicator(_pointCurrent); + + // Find new screen position + Point newCurrent = PointToScreen(new Point(e.X, e.Y)); + + // Limit the extend the bar can be moved + ApplyBoundaryToPoint(ref newCurrent); + + // Calculate delta from initial resize + Point delta = new Point(newCurrent.X - _pointStart.X, + newCurrent.Y - _pointStart.Y); + + // Inform the Zone of requested change + if (_direction == Direction.Horizontal) + _resizeSource.EndResizeOperation(this, delta.X); + else + _resizeSource.EndResizeOperation(this, delta.Y); + } + + _resizing = false; + } + + protected void UpdateResizePosition(MouseEventArgs e) + { + // Find new screen position + Point newCurrent = PointToScreen(new Point(e.X, e.Y)); + + // Limit the extend the bar can be moved + ApplyBoundaryToPoint(ref newCurrent); + + // Has change in position occured? + if (newCurrent != _pointCurrent) + { + // Undraw the old position + DrawResizeIndicator(_pointCurrent); + + // Record the new screen position + _pointCurrent = newCurrent; + + // Draw the new position + DrawResizeIndicator(_pointCurrent); + } + } + + protected void ApplyBoundaryToPoint(ref Point newCurrent) + { + // Calculate mouse position delta from mouse down + Point delta = new Point(newCurrent.X - _pointStart.X, + newCurrent.Y - _pointStart.Y); + + // Get our dimensions in screen coordinates + Rectangle client = RectangleToScreen(this.ClientRectangle); + + if (_direction == Direction.Horizontal) + { + client.Offset(delta.X, 0); + + // Test against left hand edge + if (client.X < _boundary.X) + newCurrent.X += _boundary.X - client.X; + + // Test against right hand edge + if (client.Right > _boundary.Right) + newCurrent.X -= client.Right - _boundary.Right; + } + else + { + client.Offset(0, delta.Y); + + // Test against top edge + if (client.Y < _boundary.Y) + newCurrent.Y += _boundary.Y - client.Y; + + // Test against bottom edge + if (client.Bottom > _boundary.Bottom) + newCurrent.Y -= client.Bottom - _boundary.Bottom; + } + } + + protected void DrawResizeIndicator(Point screenPosition) + { + // Calculate mouse position delta from mouse down + Point delta = new Point(screenPosition.X - _pointStart.X, + screenPosition.Y - _pointStart.Y); + + // Get our dimensions in screen coordinates + Rectangle client = RectangleToScreen(this.ClientRectangle); + + if (_direction == Direction.Horizontal) + client.Offset(delta.X, 0); + else + client.Offset(0, delta.Y); + + DrawHelper.DrawDragRectangle(client, 0); + } + + protected override void OnMouseDown(MouseEventArgs e) + { + // Currently in a resizing operation? + if (_resizing) + { + // Reset resizing state + EndResizeOperation(e); + } + else + { + // Mouse down occured inside control + _resizing = StartResizeOperation(e); + } + + base.OnMouseDown(e); + } + + protected override void OnMouseUp(MouseEventArgs e) + { + // Currently in a resizing operation? + if (_resizing) + { + // Reset resizing state + EndResizeOperation(e); + } + + base.OnMouseUp(e); + } + + protected override void OnMouseMove(MouseEventArgs e) + { + if ((_resizeSource != null) && (_resizeSource.CanResize(this))) + { + // Display the correct mouse shape + if (_direction == Direction.Vertical) + this.Cursor = Cursors.SizeNS; + else + this.Cursor = Cursors.SizeWE; + } + else + this.Cursor = Cursors.Arrow; + + // Currently in a resizing operation? + if (_resizing) + { + UpdateResizePosition(e); + } + + base.OnMouseMove(e); + } + + protected override void OnPaint(PaintEventArgs e) + { + // Plain style draws a 3D effect around edges + if (_style == VisualStyle.Plain) + { + // Drawing is relative to client area + Size ourSize = this.ClientSize; + + Point[] light = new Point[2]; + Point[] dark = new Point[2]; + Point[] black = new Point[2]; + + // Painting depends on orientation + if (_direction == Direction.Vertical) + { + // Draw as a horizontal bar + dark[0].Y = dark[1].Y = ourSize.Height - 2; + black[0].Y = black[1].Y = ourSize.Height - 1; + light[1].X = dark[1].X = black[1].X = ourSize.Width; + } + else + { + // Draw as a vertical bar + dark[0].X = dark[1].X = ourSize.Width - 2; + black[0].X = black[1].X = ourSize.Width - 1; + light[1].Y = dark[1].Y = black[1].Y = ourSize.Height; + } + + using (Pen penLightLight = new Pen(ControlPaint.LightLight(_resizeSource.BackgroundColor)), + penDark = new Pen(ControlPaint.Dark(_resizeSource.BackgroundColor)), + penBlack = new Pen(ControlPaint.DarkDark(_resizeSource.BackgroundColor))) + { + e.Graphics.DrawLine(penLightLight, light[0], light[1]); + e.Graphics.DrawLine(penDark, dark[0], dark[1]); + e.Graphics.DrawLine(penBlack, black[0], black[1]); + } + } + + // Let delegates fire through base + base.OnPaint(e); + } + } + + [ToolboxItem(false)] + public class ResizeAutoBar : ResizeBar + { + public ResizeAutoBar(Direction direction, IResizeSource resizeSource) + : base(direction, resizeSource) + { + } + + protected override void OnPaint(PaintEventArgs e) + { + Color backColor = this.BackColor; + + switch (this.Dock) + { + case DockStyle.Right: + using (Pen penD = new Pen(ControlPaint.Dark(backColor)), + penDD = new Pen(ControlPaint.DarkDark(backColor))) + { + e.Graphics.DrawLine(penD, this.Width - 2, 0, this.Width - 2, this.Height); + e.Graphics.DrawLine(penDD, this.Width - 1, 0, this.Width - 1, this.Height); + } + break; + + case DockStyle.Left: + using (Pen penLL = new Pen(ControlPaint.LightLight(backColor))) + e.Graphics.DrawLine(penLL, 1, 0, 1, this.Height); + break; + + case DockStyle.Bottom: + using (Pen penD = new Pen(ControlPaint.Dark(backColor)), + penDD = new Pen(ControlPaint.DarkDark(backColor))) + { + e.Graphics.DrawLine(penD, 0, this.Height - 2, this.Width, this.Height - 2); + e.Graphics.DrawLine(penDD, 0, this.Height - 1, this.Width, this.Height - 1); + } + break; + + case DockStyle.Top: + using (Pen penLL = new Pen(ControlPaint.LightLight(backColor))) + e.Graphics.DrawLine(penLL, 0, 1, this.Width, 1); + break; + } + } + } +} \ No newline at end of file diff --git a/Labyrinth3/Crownwood.Magic/Controls/ResizeBar/ResizeBar.resx b/Labyrinth3/Crownwood.Magic/Controls/ResizeBar/ResizeBar.resx new file mode 100644 index 0000000..7e32396 --- /dev/null +++ b/Labyrinth3/Crownwood.Magic/Controls/ResizeBar/ResizeBar.resx @@ -0,0 +1,42 @@ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + text/microsoft-resx + + + 1.0.0.0 + + + System.Resources.ResXResourceReader, System.Windows.Forms, Version=1.0.3102.0, Culture=neutral, PublicKeyToken=b77a5c561934e089 + + + System.Resources.ResXResourceWriter, System.Windows.Forms, Version=1.0.3102.0, Culture=neutral, PublicKeyToken=b77a5c561934e089 + + diff --git a/Labyrinth3/Crownwood.Magic/Controls/TabControl.bmp b/Labyrinth3/Crownwood.Magic/Controls/TabControl.bmp new file mode 100644 index 0000000..4c1349a Binary files /dev/null and b/Labyrinth3/Crownwood.Magic/Controls/TabControl.bmp differ diff --git a/Labyrinth3/Crownwood.Magic/Controls/TabControl/TabControl.cs b/Labyrinth3/Crownwood.Magic/Controls/TabControl/TabControl.cs new file mode 100644 index 0000000..fb92ab4 --- /dev/null +++ b/Labyrinth3/Crownwood.Magic/Controls/TabControl/TabControl.cs @@ -0,0 +1,4176 @@ +// ***************************************************************************** +// +// (c) Crownwood Consulting Limited 2002-2003 +// All rights reserved. The software and associated documentation +// supplied hereunder are the proprietary information of Crownwood Consulting +// Limited, Crownwood, Bracknell, Berkshire, England and are supplied subject +// to licence terms. +// +// Magic Version 1.7.4.0 www.dotnetmagic.com +// ***************************************************************************** + +using Crownwood.Magic.Collections; +using Crownwood.Magic.Common; + +//using Crownwood.Magic.Win32; +using Crownwood.Magic.Menus; +using Microsoft.Win32; +using System; +using System.Collections; +using System.ComponentModel; +using System.Drawing; +using System.Drawing.Imaging; +using System.Drawing.Text; +using System.Windows.Forms; + +namespace Crownwood.Magic.Controls +{ + [ToolboxBitmap(typeof(TabControl))] + [DefaultProperty("Appearance")] + [DefaultEvent("SelectionChanged")] + [Designer(typeof(Crownwood.Magic.Controls.TabControlDesigner))] + public class TabControl : Panel + { + // Enumeration of appearance styles + public enum VisualAppearance + { + MultiDocument = 0, + MultiForm = 1, + MultiBox = 2 + } + + // Enumeration of modes that control display of the tabs area + public enum HideTabsModes + { + ShowAlways, + HideAlways, + HideUsingLogic, + HideWithoutMouse + } + + // Indexes into the menu images strip + protected enum ImageStrip + { + LeftEnabled = 0, + LeftDisabled = 1, + RightEnabled = 2, + RightDisabled = 3, + Close = 4, + Error = 5 + } + + // Enumeration of Indexes into positioning constants array + protected enum PositionIndex + { + BorderTop = 0, + BorderLeft = 1, + BorderBottom = 2, + BorderRight = 3, + ImageGapTop = 4, + ImageGapLeft = 5, + ImageGapBottom = 6, + ImageGapRight = 7, + TextOffset = 8, + TextGapLeft = 9, + TabsBottomGap = 10, + ButtonOffset = 11, + } + + // Helper class for handling multiline calculations + protected class MultiRect + { + protected Rectangle _rect; + protected int _index; + + public MultiRect(Rectangle rect, int index) + { + _rect = rect; + _index = index; + } + + public int Index + { + get { return _index; } + } + + public Rectangle Rect + { + get { return _rect; } + set { _rect = value; } + } + + public int X + { + get { return _rect.X; } + set { _rect.X = value; } + } + + public int Y + { + get { return _rect.Y; } + set { _rect.Y = value; } + } + + public int Width + { + get { return _rect.Width; } + set { _rect.Width = value; } + } + + public int Height + { + get { return _rect.Height; } + set { _rect.Height = value; } + } + } + + // Class constants for sizing/positioning each style + protected static int[,] _position = { + {3, 1, 1, 1, 1, 2, 1, 1, 2, 1, 3, 2}, // IDE + {6, 2, 2, 3, 3, 1, 1, 0, 1, 1, 2, 0} // Plain + }; + + // Class constants + protected static int _plainBorder = 3; + + protected static int _plainBorderDouble = 6; + protected static int _tabsAreaStartInset = 5; + protected static int _tabsAreaEndInset = 5; + protected static float _alphaIDE = 1.5F; + protected static int _buttonGap = 3; + protected static int _buttonWidth = 14; + protected static int _buttonHeight = 14; + protected static int _imageButtonWidth = 12; + protected static int _imageButtonHeight = 12; + protected static int _multiBoxAdjust = 2; + protected readonly Rectangle _nullPosition = new Rectangle(-999, -999, 0, 0); + + // Class state + protected static ImageList _internalImages; + + // Instance fields - size/positioning + protected int _textHeight; + + protected int _imageWidth; + protected int _imageHeight; + protected int _imageGapTopExtra; + protected int _imageGapBottomExtra; + protected Rectangle _pageRect; + protected Rectangle _pageAreaRect; + protected Rectangle _tabsAreaRect; + + // Instance fields - state + protected int _ctrlTopOffset; // How far from top edge embedded controls should offset + + protected int _ctrlLeftOffset; // How far from left edge embedded controls should offset + protected int _ctrlRightOffset; // How far from right edgeembedded controls should offset + protected int _ctrlBottomOffset; // How far from bottom edge embedded controls should offset + protected int _styleIndex; // Index into position array + protected int _pageSelected; // index of currently selected page (-1 is none) + protected int _startPage; // index of first page to draw, used when scrolling pages + protected int _hotTrackPage; // which page is currently displayed as being tracked + protected int _topYPos; // Y position of first line in multiline mode + protected int _bottomYPos; // Y position of last line in multiline mode + protected int _leaveTimeout; // How long from leaving to timeout occuring + protected bool _dragFromControl; // Must drag away from whole control before drag events generated + protected bool _mouseOver; // Mouse currently over the control (or child pages) + protected bool _multiline; // should tabs that cannot fit on a line create new lines + protected bool _multilineFullWidth; // when in multiline mode, all lines are extended to end + protected bool _shrinkPagesToFit; // pages are shrunk so they all fit in control width + protected bool _changed; // Flag for use when updating contents of collection + protected bool _positionAtTop; // display tabs at top or bottom of the control + protected bool _showClose; // should the close button be displayed + protected bool _showArrows; // should then scroll arrow be displayed + protected bool _insetPlain; // Show the inset border for controls + protected bool _insetBorderPagesOnly; // Remove the border entirely for Plain mode + protected bool _selectedTextOnly; // Only draw text for selected tab + protected bool _rightScroll; // Should the right scroll button be enabled + protected bool _leftScroll; // Should the left scroll button be enabled + protected bool _dimUnselected; // should unselected pages be drawn slightly dimmed + protected bool _boldSelected; // should selected page use a bold font + protected bool _hotTrack; // should mouve moving over text hot track it + protected bool _hoverSelect; // select a page when he mouse hovers over it + protected bool _recalculate; // flag to indicate recalculation is needed before painting + protected bool _leftMouseDown; // Is the left mouse button down + protected bool _leftMouseDownDrag; // Has a drag operation begun + protected bool _ignoreDownDrag; // When pressed the left button cannot generate two drags + protected bool _defaultColor; // Is the background color the default one? + protected bool _defaultFont; // Is the Font the default one? + protected bool _recordFocus; // Record the control with focus when leaving a page + protected bool _idePixelArea; // Place a one pixel border at top/bottom of tabs area + protected bool _idePixelBorder; // Place a one pixel border around control + protected bool _dragOverSelect; // Should dragging over a tab cause selection? + protected PopupMenu _contextMenu; // Context menu to show on right mouse up + protected Point _leftMouseDownPos; // Initial mouse down position for left mouse button + protected Point _mouseDragOver; // Mouse position for drag over event + protected Color _hotTextColor; // color for use when drawing text as hot + protected Color _textColor; // color for use when text not hot + protected Color _textInactiveColor; // color for use when text not hot and not the active tab + protected Color _backIDE; // background drawing color when in IDE appearance + protected Color _buttonActiveColor; // color for drawing buttons images when active + protected Color _buttonInactiveColor; // color for drawing buttons images when inactive + protected Color _backLight; // light variation of the back color + protected Color _backLightLight; // lightlight variation of the back color + protected Color _backDark; // dark variation of the back color + protected Color _backDarkDark; // darkdark variation of the back color + protected VisualStyle _style; // which style of use + protected HideTabsModes _hideTabsMode; // Decide when to hide/show tabs area + protected Timer _overTimer; // Time when mouse has left control + protected Timer _dragTimer; // Time when mouse hovers in drag over + protected VisualAppearance _appearance; // which appearance style + protected ImageList _imageList; // collection of images for use is tabs + protected ArrayList _tabRects; // display rectangles for associated page + protected TabPageCollection _tabPages; // collection of pages + + // Instance fields - buttons + protected InertButton _closeButton; + + protected InertButton _leftArrow; + protected InertButton _rightArrow; + + public delegate void DoubleClickTabHandler(TabControl sender, TabPage page); + + // Exposed events + public event EventHandler ClosePressed; + + public event EventHandler SelectionChanging; + + public event EventHandler SelectionChanged; + + public event EventHandler PageGotFocus; + + public event EventHandler PageLostFocus; + + public event CancelEventHandler PopupMenuDisplay; + + public event MouseEventHandler PageDragStart; + + public event MouseEventHandler PageDragMove; + + public event MouseEventHandler PageDragEnd; + + public event MouseEventHandler PageDragQuit; + + public event DoubleClickTabHandler DoubleClickTab; + + static TabControl() + { + // Create a strip of images by loading an embedded bitmap resource + _internalImages = ResourceHelper.LoadBitmapStrip(Type.GetType("Crownwood.Magic.Controls.TabControl"), + "Crownwood.Magic.Resources.ImagesTabControl.bmp", + new Size(_imageButtonWidth, _imageButtonHeight), + new Point(0, 0)); + } + + public TabControl() + { + // Prevent flicker with double buffering and all painting inside WM_PAINT + SetStyle(ControlStyles.DoubleBuffer | + ControlStyles.AllPaintingInWmPaint | + ControlStyles.UserPaint, true); + + // Create collections + _tabRects = new ArrayList(); + _tabPages = new TabPageCollection(); + + // Hookup to collection events + _tabPages.Clearing += new CollectionClear(OnClearingPages); + _tabPages.Cleared += new CollectionClear(OnClearedPages); + _tabPages.Inserting += new CollectionChange(OnInsertingPage); + _tabPages.Inserted += new CollectionChange(OnInsertedPage); + _tabPages.Removing += new CollectionChange(OnRemovingPage); + _tabPages.Removed += new CollectionChange(OnRemovedPage); + + // Define the default state of the control + _startPage = -1; + _pageSelected = -1; + _hotTrackPage = -1; + _imageList = null; + _insetPlain = true; + _multiline = false; + _multilineFullWidth = false; + _dragFromControl = true; + _mouseOver = false; + _leftScroll = false; + _defaultFont = true; + _defaultColor = true; + _rightScroll = false; + _hoverSelect = false; + _leftMouseDown = false; + _ignoreDownDrag = true; + _selectedTextOnly = false; + _leftMouseDownDrag = false; + _insetBorderPagesOnly = false; + _dragOverSelect = true; + _hideTabsMode = HideTabsModes.ShowAlways; + _recordFocus = true; + _styleIndex = 1; + _leaveTimeout = 200; + _ctrlTopOffset = 0; + _ctrlLeftOffset = 0; + _ctrlRightOffset = 0; + _ctrlBottomOffset = 0; + _style = VisualStyle.IDE; + _buttonActiveColor = Color.FromArgb(128, this.ForeColor); + _buttonInactiveColor = _buttonActiveColor; + _textColor = TabControl.DefaultForeColor; + _textInactiveColor = Color.FromArgb(128, _textColor); + _hotTextColor = SystemColors.ActiveCaption; + + // Create hover buttons + _closeButton = new InertButton(_internalImages, (int)ImageStrip.Close); + _leftArrow = new InertButton(_internalImages, (int)ImageStrip.LeftEnabled, (int)ImageStrip.LeftDisabled); + _rightArrow = new InertButton(_internalImages, (int)ImageStrip.RightEnabled, (int)ImageStrip.RightDisabled); + + // We want our buttons to have very thin borders + _closeButton.BorderWidth = _leftArrow.BorderWidth = _rightArrow.BorderWidth = 1; + + // Hookup to the button events + _closeButton.Click += new EventHandler(OnCloseButton); + _leftArrow.Click += new EventHandler(OnLeftArrow); + _rightArrow.Click += new EventHandler(OnRightArrow); + + // Set their fixed sizes + _leftArrow.Size = _rightArrow.Size = _closeButton.Size = new Size(_buttonWidth, _buttonHeight); + + // Add child controls + Controls.AddRange(new Control[] { _closeButton, _leftArrow, _rightArrow }); + + // Grab some contant values + _imageWidth = 16; + _imageHeight = 16; + + // Default to having a MultiForm usage + SetAppearance(VisualAppearance.MultiForm); + + // Need a timer so that when the mouse leaves, a fractionaly delay occurs before + // noticing and hiding the tabs area when the appropriate style is set + _overTimer = new Timer(); + _overTimer.Interval = _leaveTimeout; + _overTimer.Tick += new EventHandler(OnMouseTick); + + // Need a timer so that when the mouse hovers in drag over mode the page then changes + _dragTimer = new Timer(); + _dragTimer.Interval = 200; + _dragTimer.Tick += new EventHandler(OnDragOverTick); + + // Need notification when the MenuFont is changed + Microsoft.Win32.SystemEvents.UserPreferenceChanged += + new UserPreferenceChangedEventHandler(OnPreferenceChanged); + + // Define the default Font, BackColor and Button images + DefineFont(SystemInformation.MenuFont); + DefineBackColor(SystemColors.Control); + DefineButtonImages(); + ResetAllowDrop(); + ResetDragOverSelect(); + + Recalculate(); + } + + protected override void Dispose(bool disposing) + { + if (disposing) + { + // Remove notifications + Microsoft.Win32.SystemEvents.UserPreferenceChanged -= + new UserPreferenceChangedEventHandler(OnPreferenceChanged); + } + base.Dispose(disposing); + } + + [DesignerSerializationVisibility(DesignerSerializationVisibility.Hidden)] + public new Control.ControlCollection Controls + { + get { return base.Controls; } + } + + [Category("Appearance")] + [DesignerSerializationVisibility(DesignerSerializationVisibility.Content)] + public virtual TabPageCollection TabPages + { + get { return _tabPages; } + } + + [Category("Appearance")] + public override Font Font + { + get { return base.Font; } + + set + { + if (value != null) + { + if (value != base.Font) + { + _defaultFont = (value == SystemInformation.MenuFont); + + DefineFont(value); + + _recalculate = true; + Invalidate(); + } + } + } + } + + private bool ShouldSerializeFont() + { + return !_defaultFont; + } + + [DefaultValue(true)] + public override bool AllowDrop + { + get { return base.AllowDrop; } + set { base.AllowDrop = value; } + } + + public void ResetAllowDrop() + { + AllowDrop = true; + } + + [Category("Appearance")] + public override Color ForeColor + { + get { return _textColor; } + + set + { + if (_textColor != value) + { + _textColor = value; + + _recalculate = true; + Invalidate(); + } + } + } + + private bool ShouldSerializeForeColor() + { + return _textColor != TabControl.DefaultForeColor; + } + + [Category("Appearance")] + public override Color BackColor + { + get { return base.BackColor; } + + set + { + if (this.BackColor != value) + { + _defaultColor = (value == SystemColors.Control); + + DefineBackColor(value); + + _recalculate = true; + Invalidate(); + } + } + } + + private bool ShouldSerializeBackColor() + { + return this.BackColor != SystemColors.Control; + } + + [Category("Appearance")] + public virtual Color ButtonActiveColor + { + get { return _buttonActiveColor; } + + set + { + if (_buttonActiveColor != value) + { + _buttonActiveColor = value; + DefineButtonImages(); + } + } + } + + private bool ShouldSerializeButtonActiveColor() + { + return _buttonActiveColor != Color.FromArgb(128, this.ForeColor); + } + + public void ResetButtonActiveColor() + { + ButtonActiveColor = Color.FromArgb(128, this.ForeColor); + } + + [Category("Appearance")] + public virtual Color ButtonInactiveColor + { + get { return _buttonInactiveColor; } + + set + { + if (_buttonInactiveColor != value) + { + _buttonInactiveColor = value; + DefineButtonImages(); + } + } + } + + private bool ShouldSerializeButtonInactiveColor() + { + return _buttonInactiveColor != Color.FromArgb(128, this.ForeColor); + } + + public void ResetButtonInactiveColor() + { + ButtonInactiveColor = Color.FromArgb(128, this.ForeColor); + } + + [Category("Appearance")] + [DefaultValue(typeof(VisualAppearance), "MultiForm")] + public virtual VisualAppearance Appearance + { + get { return _appearance; } + + set + { + if (_appearance != value) + { + SetAppearance(value); + + Recalculate(); + Invalidate(); + } + } + } + + public void ResetAppearance() + { + Appearance = VisualAppearance.MultiForm; + } + + [Category("Appearance")] + [DefaultValue(typeof(VisualStyle), "IDE")] + public virtual VisualStyle Style + { + get { return _style; } + + set + { + if (_style != value) + { + _style = value; + + // Define the correct style indexer + SetStyleIndex(); + + Recalculate(); + Invalidate(); + } + } + } + + public void ResetStyle() + { + Style = VisualStyle.IDE; + } + + [Category("Behavour")] + public virtual PopupMenu ContextPopupMenu + { + get { return _contextMenu; } + set { _contextMenu = value; } + } + + protected bool ShouldSerializeContextPopupMenu() + { + return _contextMenu != null; + } + + public void ResetContextPopupMenu() + { + ContextPopupMenu = null; + } + + [Category("Behavour")] + [DefaultValue(true)] + public virtual bool DragOverSelect + { + get { return _dragOverSelect; } + set { _dragOverSelect = value; } + } + + public void ResetDragOverSelect() + { + DragOverSelect = true; + } + + [Category("Appearance")] + [DefaultValue(false)] + public virtual bool HotTrack + { + get { return _hotTrack; } + + set + { + if (_hotTrack != value) + { + _hotTrack = value; + + if (!_hotTrack) + _hotTrackPage = -1; + + _recalculate = true; + Invalidate(); + } + } + } + + public void ResetHotTrack() + { + HotTrack = false; + } + + [Category("Appearance")] + public virtual Color HotTextColor + { + get { return _hotTextColor; } + + set + { + if (_hotTextColor != value) + { + _hotTextColor = value; + + _recalculate = true; + Invalidate(); + } + } + } + + private bool ShouldSerializeHotTextColor() + { + return _hotTextColor != SystemColors.ActiveCaption; + } + + public void ResetHotTextColor() + { + HotTextColor = SystemColors.ActiveCaption; + } + + [Category("Appearance")] + public virtual Color TextColor + { + get { return _textColor; } + + set + { + if (_textColor != value) + { + _textColor = value; + + _recalculate = true; + Invalidate(); + } + } + } + + private bool ShouldSerializeTextColor() + { + return _textColor != TabControl.DefaultForeColor; + } + + public void ResetTextColor() + { + TextColor = TabControl.DefaultForeColor; + } + + [Category("Appearance")] + public virtual Color TextInactiveColor + { + get { return _textInactiveColor; } + + set + { + if (_textInactiveColor != value) + { + _textInactiveColor = value; + + _recalculate = true; + Invalidate(); + } + } + } + + private bool ShouldSerializeTextInactiveColor() + { + return _textInactiveColor != Color.FromArgb(128, TabControl.DefaultForeColor); + } + + public void TextTextInactiveColor() + { + TextInactiveColor = Color.FromArgb(128, TabControl.DefaultForeColor); + } + + [Browsable(false)] + public virtual Rectangle TabsAreaRect + { + get { return _tabsAreaRect; } + } + + private bool ShouldSerializeTabsAreaRect() + { + return false; + } + + [Category("Appearance")] + public virtual ImageList ImageList + { + get { return _imageList; } + + set + { + if (_imageList != value) + { + _imageList = value; + + _recalculate = true; + Invalidate(); + } + } + } + + private bool ShouldSerializeImageList() + { + return _imageList != null; + } + + public void ResetImageList() + { + ImageList = null; + } + + [Category("Appearance")] + public virtual bool PositionTop + { + get { return _positionAtTop; } + + set + { + if (_positionAtTop != value) + { + _positionAtTop = value; + + _recalculate = true; + Invalidate(); + } + } + } + + protected bool ShouldSerializePositionTop() + { + switch (_appearance) + { + case VisualAppearance.MultiBox: + case VisualAppearance.MultiForm: + return _positionAtTop != false; + + case VisualAppearance.MultiDocument: + default: + return _positionAtTop != true; + } + } + + public void ResetPositionTop() + { + switch (_appearance) + { + case VisualAppearance.MultiBox: + case VisualAppearance.MultiForm: + PositionTop = false; + break; + + case VisualAppearance.MultiDocument: + default: + PositionTop = true; + break; + } + } + + [Category("Appearance")] + public virtual bool ShowClose + { + get { return _showClose; } + + set + { + if (_showClose != value) + { + _showClose = value; + + _recalculate = true; + Invalidate(); + } + } + } + + protected bool ShouldSerializeShowClose() + { + switch (_appearance) + { + case VisualAppearance.MultiBox: + case VisualAppearance.MultiForm: + return _showClose != false; + + case VisualAppearance.MultiDocument: + default: + return _showClose != true; + } + } + + public void ResetShowClose() + { + switch (_appearance) + { + case VisualAppearance.MultiBox: + case VisualAppearance.MultiForm: + ShowClose = false; + break; + + case VisualAppearance.MultiDocument: + default: + ShowClose = true; + break; + } + } + + [Category("Appearance")] + public virtual bool ShowArrows + { + get { return _showArrows; } + + set + { + if (_showArrows != value) + { + _showArrows = value; + + _recalculate = true; + Invalidate(); + } + } + } + + protected bool ShouldSerializeShowArrows() + { + switch (_appearance) + { + case VisualAppearance.MultiBox: + case VisualAppearance.MultiForm: + return _showArrows != false; + + case VisualAppearance.MultiDocument: + default: + return _showArrows != true; + } + } + + public void ResetShowArrows() + { + switch (_appearance) + { + case VisualAppearance.MultiBox: + case VisualAppearance.MultiForm: + ShowArrows = false; + break; + + case VisualAppearance.MultiDocument: + default: + ShowArrows = true; + break; + } + } + + [Category("Appearance")] + public virtual bool ShrinkPagesToFit + { + get { return _shrinkPagesToFit; } + + set + { + if (_shrinkPagesToFit != value) + { + _shrinkPagesToFit = value; + + _recalculate = true; + Invalidate(); + } + } + } + + protected bool ShouldSerializeShrinkPagesToFit() + { + switch (_appearance) + { + case VisualAppearance.MultiBox: + case VisualAppearance.MultiForm: + return _shrinkPagesToFit != true; + + case VisualAppearance.MultiDocument: + default: + return _shrinkPagesToFit != false; + } + } + + public void ResetShrinkPagesToFit() + { + switch (_appearance) + { + case VisualAppearance.MultiBox: + case VisualAppearance.MultiForm: + ShrinkPagesToFit = true; + break; + + case VisualAppearance.MultiDocument: + default: + ShrinkPagesToFit = false; + break; + } + } + + [Category("Appearance")] + public virtual bool BoldSelectedPage + { + get { return _boldSelected; } + + set + { + if (_boldSelected != value) + { + _boldSelected = value; + + _recalculate = true; + Invalidate(); + } + } + } + + protected bool ShouldSerializeBoldSelectedPage() + { + switch (_appearance) + { + case VisualAppearance.MultiBox: + case VisualAppearance.MultiForm: + return _boldSelected != false; + + case VisualAppearance.MultiDocument: + default: + return _boldSelected != true; + } + } + + public void ResetBoldSelectedPage() + { + switch (_appearance) + { + case VisualAppearance.MultiBox: + case VisualAppearance.MultiForm: + BoldSelectedPage = false; + break; + + case VisualAppearance.MultiDocument: + default: + BoldSelectedPage = true; + break; + } + } + + [Category("Appearance")] + [DefaultValue(false)] + public virtual bool MultilineFullWidth + { + get { return _multilineFullWidth; } + + set + { + if (_multilineFullWidth != value) + { + _multilineFullWidth = value; + + _recalculate = true; + Invalidate(); + } + } + } + + public void ResetMultilineFullWidth() + { + MultilineFullWidth = false; + } + + [Category("Appearance")] + [DefaultValue(false)] + public virtual bool Multiline + { + get { return _multiline; } + + set + { + if (_multiline != value) + { + _multiline = value; + + _recalculate = true; + Invalidate(); + } + } + } + + public void ResetMultiline() + { + Multiline = false; + } + + [Category("Appearance")] + [DefaultValue(0)] + public virtual int ControlLeftOffset + { + get { return _ctrlLeftOffset; } + + set + { + if (_ctrlLeftOffset != value) + { + _ctrlLeftOffset = value; + + Recalculate(); + Invalidate(); + } + } + } + + public void ResetControlLeftOffset() + { + ControlLeftOffset = 0; + } + + [Category("Appearance")] + [DefaultValue(0)] + public virtual int ControlTopOffset + { + get { return _ctrlTopOffset; } + + set + { + if (_ctrlTopOffset != value) + { + _ctrlTopOffset = value; + + Recalculate(); + Invalidate(); + } + } + } + + public void ResetControlTopOffset() + { + ControlTopOffset = 0; + } + + [Category("Appearance")] + [DefaultValue(0)] + public virtual int ControlRightOffset + { + get { return _ctrlRightOffset; } + + set + { + if (_ctrlRightOffset != value) + { + _ctrlRightOffset = value; + + Recalculate(); + Invalidate(); + } + } + } + + public void ResetControlRightOffset() + { + ControlRightOffset = 0; + } + + [Category("Appearance")] + [DefaultValue(0)] + public virtual int ControlBottomOffset + { + get { return _ctrlBottomOffset; } + + set + { + if (_ctrlBottomOffset != value) + { + _ctrlBottomOffset = value; + + Recalculate(); + Invalidate(); + } + } + } + + public void ResetControlBottomOffset() + { + ControlBottomOffset = 0; + } + + [Category("Appearance")] + [DefaultValue(true)] + public virtual bool InsetPlain + { + get { return _insetPlain; } + + set + { + if (_insetPlain != value) + { + _insetPlain = value; + + Recalculate(); + Invalidate(); + } + } + } + + public void ResetInsetPlain() + { + InsetPlain = true; + } + + [Category("Appearance")] + [DefaultValue(false)] + public virtual bool InsetBorderPagesOnly + { + get { return _insetBorderPagesOnly; } + + set + { + if (_insetBorderPagesOnly != value) + { + _insetBorderPagesOnly = value; + + Recalculate(); + Invalidate(); + } + } + } + + public void ResetInsetBorderPagesOnly() + { + InsetBorderPagesOnly = true; + } + + [Category("Appearance")] + public virtual bool IDEPixelBorder + { + get { return _idePixelBorder; } + + set + { + if (_idePixelBorder != value) + { + _idePixelBorder = value; + + Recalculate(); + Invalidate(); + } + } + } + + protected bool ShouldSerializeIDEPixelBorder() + { + switch (_appearance) + { + case VisualAppearance.MultiBox: + case VisualAppearance.MultiForm: + return _idePixelBorder != false; + + case VisualAppearance.MultiDocument: + default: + return _idePixelBorder != true; + } + } + + public void ResetIDEPixelBorder() + { + switch (_appearance) + { + case VisualAppearance.MultiBox: + case VisualAppearance.MultiForm: + IDEPixelBorder = false; + break; + + case VisualAppearance.MultiDocument: + default: + IDEPixelBorder = true; + break; + } + } + + [Category("Appearance")] + public virtual bool IDEPixelArea + { + get { return _idePixelArea; } + + set + { + if (_idePixelArea != value) + { + _idePixelArea = value; + + Recalculate(); + Invalidate(); + } + } + } + + public void ResetIDEPixelArea() + { + IDEPixelArea = true; + } + + [Category("Appearance")] + [DefaultValue(false)] + public virtual bool SelectedTextOnly + { + get { return _selectedTextOnly; } + + set + { + if (_selectedTextOnly != value) + { + _selectedTextOnly = value; + + _recalculate = true; + Invalidate(); + } + } + } + + public void ResetSelectedTextOnly() + { + SelectedTextOnly = false; + } + + [Category("Behavour")] + [DefaultValue(200)] + public int MouseLeaveTimeout + { + get { return _leaveTimeout; } + + set + { + if (_leaveTimeout != value) + { + _leaveTimeout = value; + _overTimer.Interval = value; + } + } + } + + public void ResetMouseLeaveTimeout() + { + _leaveTimeout = 200; + } + + [Category("Behavour")] + [DefaultValue(true)] + public bool DragFromControl + { + get { return _dragFromControl; } + set { _dragFromControl = value; } + } + + public void ResetDragFromControl() + { + DragFromControl = true; + } + + [Category("Appearance")] + [DefaultValue(typeof(HideTabsModes), "ShowAlways")] + public virtual HideTabsModes HideTabsMode + { + get { return _hideTabsMode; } + + set + { + if (_hideTabsMode != value) + { + _hideTabsMode = value; + + Recalculate(); + Invalidate(); + } + } + } + + protected bool ShouldSerializeHideTabsMode() + { + return HideTabsMode != HideTabsModes.ShowAlways; + } + + public void ResetHideTabsMode() + { + HideTabsMode = HideTabsModes.ShowAlways; + } + + [Category("Appearance")] + [DefaultValue(false)] + public virtual bool HoverSelect + { + get { return _hoverSelect; } + + set + { + if (_hoverSelect != value) + { + _hoverSelect = value; + + _recalculate = true; + Invalidate(); + } + } + } + + public void ResetHoverSelect() + { + HoverSelect = false; + } + + [Category("Behavour")] + [DefaultValue(true)] + public virtual bool RecordFocus + { + get { return _recordFocus; } + + set + { + if (_recordFocus != value) + _recordFocus = value; + } + } + + public void ResetRecordFocus() + { + RecordFocus = true; + } + + [Browsable(false)] + [DefaultValue(-1)] + public virtual int SelectedIndex + { + get { return _pageSelected; } + + set + { + if ((value >= 0) && (value < _tabPages.Count)) + { + if (_pageSelected != value) + { + // Raise selection changing event + OnSelectionChanging(EventArgs.Empty); + + // Any page currently selected? + if (_pageSelected != -1) + DeselectPage(_tabPages[_pageSelected]); + + _pageSelected = value; + + if (_pageSelected != -1) + { + SelectPage(_tabPages[_pageSelected]); + + // If newly selected page is scrolled off the left hand side + if (_pageSelected < _startPage) + _startPage = _pageSelected; // then bring it into view + } + + // Change in selection causes tab pages sizes to change + if (_boldSelected) + { + Recalculate(); + Invalidate(); + } + + // Raise selection change event + OnSelectionChanged(EventArgs.Empty); + + Invalidate(); + } + } + } + } + + [Browsable(false)] + [DefaultValue(null)] + public virtual TabPage SelectedTab + { + get + { + // If nothing is selected we return null + if (_pageSelected == -1) + return null; + else + return _tabPages[_pageSelected]; + } + + set + { + // Cannot change selection to be none of the tabs + if (value != null) + { + // Get the requested page from the collection + int index = _tabPages.IndexOf(value); + + // If a valid known page then using existing property to perform switch + if (index != -1) + this.SelectedIndex = index; + } + } + } + + public TabPage TabPageFromPoint(Point mousePos) + { + // Clicked on a tab page? + for (int i = 0; i < _tabPages.Count; i++) + { + Rectangle rect = (Rectangle)_tabRects[i]; + + // Does tab page rectangle contain mouse? + if (rect.Contains(mousePos)) + { + // Is left scroll button showing? + if (_leftArrow.Visible) + { + // Ignore mouse down over then buttons area + if (mousePos.X >= _leftArrow.Left) + return null; + } + else + { + // No, is the close button showing? + if (_closeButton.Visible) + { + // Ignore mouse down over then close button area + if (mousePos.X >= _closeButton.Left) + return null; + } + } + + return _tabPages[i]; + } + } + + // No matching tab header found + return null; + } + + public virtual void MakePageVisible(TabPage page) + { + MakePageVisible(_tabPages.IndexOf(page)); + } + + public virtual void MakePageVisible(int index) + { + // Only relevant if we do not shrink all pages to fit and not in multiline + if (!_shrinkPagesToFit && !_multiline) + { + // Range check the request page + if ((index >= 0) && (index < _tabPages.Count)) + { + // Is requested page before those shown? + if (index < _startPage) + { + // Define it as the new start page + _startPage = index; + + _recalculate = true; + Invalidate(); + } + else + { + // Find the last visible position + int xMax = GetMaximumDrawPos(); + + Rectangle rect = (Rectangle)_tabRects[index]; + + // Is the page drawn off over the maximum position? + if (rect.Right >= xMax) + { + // Need to find the new start page to bring this one into view + int newStart = index; + + // Space left over for other tabs to be drawn inside + int spaceLeft = xMax - rect.Width - _tabsAreaRect.Left - _tabsAreaStartInset; + + do + { + // Is there a previous tab to check? + if (newStart == 0) + break; + + Rectangle rectStart = (Rectangle)_tabRects[newStart - 1]; + + // Is there enough space to draw it? + if (rectStart.Width > spaceLeft) + break; + + // Move to new tab and reduce available space left + newStart--; + spaceLeft -= rectStart.Width; + } while (true); + + // Define the new starting page + _startPage = newStart; + + _recalculate = true; + Invalidate(); + } + } + } + } + } + + protected override bool ProcessMnemonic(char key) + { + int total = _tabPages.Count; + int index = this.SelectedIndex + 1; + + for (int count = 0; count < total; count++, index++) + { + // Range check the index + if (index >= total) + index = 0; + + TabPage page = _tabPages[index]; + + // Find position of first mnemonic character + int position = page.Title.IndexOf('&'); + + // Did we find a mnemonic indicator? + if (IsMnemonic(key, page.Title)) + { + // Select this page + this.SelectedTab = page; + + return true; + } + } + + return false; + } + + protected override void OnResize(EventArgs e) + { + Recalculate(); + Invalidate(); + + base.OnResize(e); + } + + protected override void OnSizeChanged(EventArgs e) + { + Recalculate(); + Invalidate(); + + base.OnSizeChanged(e); + } + + public virtual void OnPopupMenuDisplay(CancelEventArgs e) + { + // Has anyone registered for the event? + if (PopupMenuDisplay != null) + PopupMenuDisplay(this, e); + } + + public virtual void OnSelectionChanging(EventArgs e) + { + // Has anyone registered for the event? + if (SelectionChanging != null) + SelectionChanging(this, e); + } + + public virtual void OnSelectionChanged(EventArgs e) + { + // Has anyone registered for the event? + if (SelectionChanged != null) + SelectionChanged(this, e); + } + + public virtual void OnClosePressed(EventArgs e) + { + // Has anyone registered for the event? + if (ClosePressed != null) + ClosePressed(this, e); + } + + public virtual void OnPageGotFocus(EventArgs e) + { + // Has anyone registered for the event? + if (PageGotFocus != null) + PageGotFocus(this, e); + } + + public virtual void OnPageLostFocus(EventArgs e) + { + // Has anyone registered for the event? + if (PageLostFocus != null) + PageLostFocus(this, e); + } + + public virtual void OnPageDragStart(MouseEventArgs e) + { + // Has anyone registered for the event? + if (PageDragStart != null) + PageDragStart(this, e); + } + + public virtual void OnPageDragMove(MouseEventArgs e) + { + // Has anyone registered for the event? + if (PageDragMove != null) + PageDragMove(this, e); + } + + public virtual void OnPageDragEnd(MouseEventArgs e) + { + // Has anyone registered for the event? + if (PageDragEnd != null) + PageDragEnd(this, e); + } + + public virtual void OnPageDragQuit(MouseEventArgs e) + { + // Has anyone registered for the event? + if (PageDragQuit != null) + PageDragQuit(this, e); + } + + public virtual void OnDoubleClickTab(TabPage page) + { + // Has anyone registered for the event? + if (DoubleClickTab != null) + DoubleClickTab(this, page); + } + + protected virtual void OnCloseButton(object sender, EventArgs e) + { + OnClosePressed(EventArgs.Empty); + } + + protected virtual void OnLeftArrow(object sender, EventArgs e) + { + // Set starting page back one + _startPage--; + + _recalculate = true; + Invalidate(); + } + + protected virtual void OnRightArrow(object sender, EventArgs e) + { + // Set starting page forward one + _startPage++; + + _recalculate = true; + Invalidate(); + } + + protected virtual void DefineFont(Font newFont) + { + // Use base class for storage of value + base.Font = newFont; + + // Update internal height value using Font + _textHeight = newFont.Height; + + // Is the font height bigger than the image height? + if (_imageHeight >= _textHeight) + { + // No, do not need extra spacing around the image to fit in text + _imageGapTopExtra = 0; + _imageGapBottomExtra = 0; + } + else + { + // Yes, need to make the image area bigger so that its height calculation + // matchs that height of the text + int extraHeight = _textHeight - _imageHeight; + + // Split the extra height between the top and bottom of image + _imageGapTopExtra = extraHeight / 2; + _imageGapBottomExtra = extraHeight - _imageGapTopExtra; + } + } + + protected virtual void DefineBackColor(Color newColor) + { + base.BackColor = newColor; + + // Calculate the modified colors from this base + _backLight = ControlPaint.Light(newColor); + _backLightLight = ControlPaint.LightLight(newColor); + _backDark = ControlPaint.Dark(newColor); + _backDarkDark = ControlPaint.DarkDark(newColor); + + _backIDE = ColorHelper.TabBackgroundFromBaseColor(newColor); + } + + protected virtual void DefineButtonImages() + { + ImageAttributes ia = new ImageAttributes(); + + ColorMap activeMap = new ColorMap(); + ColorMap inactiveMap = new ColorMap(); + + // Define the color transformations needed + activeMap.OldColor = Color.Black; + activeMap.NewColor = _buttonActiveColor; + inactiveMap.OldColor = Color.White; + inactiveMap.NewColor = _buttonInactiveColor; + + // Create remap attributes for use by button + ia.SetRemapTable(new ColorMap[] { activeMap, inactiveMap }, ColorAdjustType.Bitmap); + + // Pass attributes to the buttons + _leftArrow.ImageAttributes = ia; + _rightArrow.ImageAttributes = ia; + _closeButton.ImageAttributes = ia; + } + + protected virtual void SetAppearance(VisualAppearance appearance) + { + switch (appearance) + { + case VisualAppearance.MultiForm: + case VisualAppearance.MultiBox: + _shrinkPagesToFit = true; // shrink tabs to fit width + _positionAtTop = false; // draw tabs at bottom of control + _showClose = false; // do not show the close button + _showArrows = false; // do not show the scroll arrow buttons + _boldSelected = false; // do not show selected pages in bold + _idePixelArea = true; // show a one pixel border at top or bottom + _idePixelBorder = false; // do not show a one pixel border round control + break; + + case VisualAppearance.MultiDocument: + _shrinkPagesToFit = false; // shrink tabs to fit width + _positionAtTop = true; // draw tabs at bottom of control + _showClose = true; // do not show the close button + _showArrows = true; // do not show the scroll arrow buttons + _boldSelected = true; // do not show selected pages in bold + _idePixelArea = true; // show a one pixel border at top or bottom + _idePixelBorder = false; // do not show a one pixel border round control + break; + } + + // These properties are the same whichever style is selected + _hotTrack = false; // do not hot track paes + _dimUnselected = true; // draw dimmed non selected pages + + // Define then starting page for drawing + if (_tabPages.Count > 0) + _startPage = 0; + else + _startPage = -1; + + _appearance = appearance; + + // Define the correct style indexer + SetStyleIndex(); + } + + protected virtual void SetStyleIndex() + { + switch (_appearance) + { + case VisualAppearance.MultiBox: + // Always pretend we are plain style + _styleIndex = 1; + break; + + case VisualAppearance.MultiForm: + case VisualAppearance.MultiDocument: + _styleIndex = (int)_style; + break; + } + } + + protected virtual bool HideTabsCalculation() + { + bool hideTabs = false; + + switch (_hideTabsMode) + { + case HideTabsModes.ShowAlways: + hideTabs = false; + break; + + case HideTabsModes.HideAlways: + hideTabs = true; + break; + + case HideTabsModes.HideUsingLogic: + hideTabs = (_tabPages.Count <= 1); + break; + + case HideTabsModes.HideWithoutMouse: + hideTabs = !_mouseOver; + break; + } + + return hideTabs; + } + + protected virtual void Recalculate() + { + // Reset the need for a recalculation + _recalculate = false; + + // The height of a tab button is... + int tabButtonHeight = _position[_styleIndex, (int)PositionIndex.ImageGapTop] + + _imageGapTopExtra + + _imageHeight + + _imageGapBottomExtra + + _position[_styleIndex, (int)PositionIndex.ImageGapBottom] + + _position[_styleIndex, (int)PositionIndex.BorderBottom]; + + // The height of the tabs area is... + int tabsAreaHeight = _position[_styleIndex, (int)PositionIndex.BorderTop] + + tabButtonHeight + _position[_styleIndex, (int)PositionIndex.TabsBottomGap]; + + bool hideTabsArea = HideTabsCalculation(); + + // Should the tabs area be hidden? + if (hideTabsArea) + { + // ... then do not show the tabs or button controls + _pageAreaRect = new Rectangle(0, 0, this.Width, this.Height); + _tabsAreaRect = new Rectangle(0, 0, 0, 0); + } + else + { + if (_positionAtTop) + { + // Create rectangle that represents the entire tabs area + _pageAreaRect = new Rectangle(0, tabsAreaHeight, this.Width, this.Height - tabsAreaHeight); + + // Create rectangle that represents the entire area for pages + _tabsAreaRect = new Rectangle(0, 0, this.Width, tabsAreaHeight); + } + else + { + // Create rectangle that represents the entire tabs area + _tabsAreaRect = new Rectangle(0, this.Height - tabsAreaHeight, this.Width, tabsAreaHeight); + + // Create rectangle that represents the entire area for pages + _pageAreaRect = new Rectangle(0, 0, this.Width, this.Height - tabsAreaHeight); + } + } + + int xEndPos = 0; + + if (!hideTabsArea && _tabPages.Count > 0) + { + // The minimum size of a button includes its left and right borders for width, + // and then fixed height which is based on the size of the image and font + Rectangle tabPosition; + + if (_positionAtTop) + tabPosition = new Rectangle(0, + _tabsAreaRect.Bottom - tabButtonHeight - + _position[_styleIndex, (int)PositionIndex.BorderTop], + _position[_styleIndex, (int)PositionIndex.BorderLeft] + + _position[_styleIndex, (int)PositionIndex.BorderRight], + tabButtonHeight); + else + tabPosition = new Rectangle(0, + _tabsAreaRect.Top + + _position[_styleIndex, (int)PositionIndex.BorderTop], + _position[_styleIndex, (int)PositionIndex.BorderLeft] + + _position[_styleIndex, (int)PositionIndex.BorderRight], + tabButtonHeight); + + // Find starting and ending positons for drawing tabs + int xStartPos = _tabsAreaRect.Left + _tabsAreaStartInset; + xEndPos = GetMaximumDrawPos(); + + // Available width for tabs is size between start and end positions + int xWidth = xEndPos - xStartPos; + + if (_multiline) + RecalculateMultilineTabs(xStartPos, xEndPos, tabPosition, tabButtonHeight); + else + RecalculateSinglelineTabs(xWidth, xStartPos, tabPosition); + } + + // Position of Controls defaults to the entire page area + _pageRect = _pageAreaRect; + + // Adjust child controls positions depending on style + if ((_style == VisualStyle.Plain) && (_appearance != VisualAppearance.MultiBox)) + { + _pageRect = _pageAreaRect; + + // Shrink by having a border on left,top and right borders + _pageRect.X += _plainBorderDouble; + _pageRect.Width -= (_plainBorderDouble * 2) - 1; + + if (!_positionAtTop) + _pageRect.Y += _plainBorderDouble; + + _pageRect.Height -= _plainBorderDouble - 1; + + // If hiding the tabs then need to adjust the controls positioning + if (hideTabsArea) + { + _pageRect.Height -= _plainBorderDouble; + + if (_positionAtTop) + _pageRect.Y += _plainBorderDouble; + } + } + + // Calcualte positioning of the child controls/forms + int leftOffset = _ctrlLeftOffset; + int rightOffset = _ctrlRightOffset; + int topOffset = _ctrlTopOffset; + int bottomOffset = _ctrlBottomOffset; + + if (_idePixelBorder && (_style == VisualStyle.IDE)) + { + leftOffset += 2; + rightOffset += 2; + + if (_positionAtTop || hideTabsArea) + bottomOffset += 2; + + if (!_positionAtTop || hideTabsArea) + topOffset += 2; + } + + Point pageLoc = new Point(_pageRect.Left + leftOffset, + _pageRect.Top + topOffset); + + Size pageSize = new Size(_pageRect.Width - leftOffset - rightOffset, + _pageRect.Height - topOffset - bottomOffset); + + // If in Plain style and requested to only show top or bottom border + if ((_style == VisualStyle.Plain) && _insetBorderPagesOnly) + { + // Then need to increase width to occupy where borders would have been + pageLoc.X -= _plainBorderDouble; + pageSize.Width += _plainBorderDouble * 2; + + if (hideTabsArea || _positionAtTop) + { + // Draw into the bottom border area + pageSize.Height += _plainBorderDouble; + } + + if (hideTabsArea || !_positionAtTop) + { + // Draw into the top border area + pageLoc.Y -= _plainBorderDouble; + pageSize.Height += _plainBorderDouble; + } + } + + // Position each page control correctly + foreach (TabPage page in _tabPages) + { + if (page.Control != null) + { + page.Control.Size = pageSize; + page.Control.Location = pageLoc; + } + else + { + page.Size = pageSize; + page.Location = pageLoc; + } + } + + // If we have any tabs at all + if (_tabPages.Count > 0) + { + Rectangle rect = (Rectangle)_tabRects[_tabPages.Count - 1]; + + // Determine is the right scrolling button should be enabled + _rightScroll = (rect.Right > xEndPos); + } + else + { + // No pages means there can be no right scrolling + _rightScroll = false; + } + + // Determine if left scrolling is possible + _leftScroll = (_startPage > 0); + + // Handle then display and positioning of buttons + RecalculateButtons(); + } + + protected virtual void RecalculateMultilineTabs(int xStartPos, int xEndPos, + Rectangle tabPosition, int tabButtonHeight) + { + using (Graphics g = this.CreateGraphics()) + { + // MultiBox style needs a pixel extra drawing room on right + if (_appearance == VisualAppearance.MultiBox) + xEndPos -= 2; + + // How many tabs on this line + int lineCount = 0; + + // Remember which line is the first displayed + _topYPos = tabPosition.Y; + + // Next tab starting position + int xPos = xStartPos; + int yPos = tabPosition.Y; + + // How many full lines were there + int fullLines = 0; + + // Line increment value + int lineIncrement = tabButtonHeight + 1; + + // Track which line has the selection on it + int selectedLine = 0; + + // Vertical adjustment + int yAdjust = 0; + + // Create array for holding lines of tabs + ArrayList lineList = new ArrayList(); + + // Add the initial line + lineList.Add(new ArrayList()); + + // Process each tag page in turn + for (int i = 0; i < _tabPages.Count; i++) + { + // Get the tab instance for this position + TabPage page = _tabPages[i]; + + // Find out the tabs total width + int tabWidth = GetTabPageSpace(g, page); + + // If not the first on the line, then check if newline should be started + if (lineCount > 0) + { + // Does this tab extend pass end of the lines + if ((xPos + tabWidth) > xEndPos) + { + // Next tab position is down a line and back to the start + xPos = xStartPos; + yPos += lineIncrement; + + // Remember which line is the last displayed + _bottomYPos = tabPosition.Y; + + // Increase height of the tabs area + _tabsAreaRect.Height += lineIncrement; + + // Decrease height of the control area + _pageAreaRect.Height -= lineIncrement; + + // Moving areas depends on drawing at top or bottom + if (_positionAtTop) + _pageAreaRect.Y += lineIncrement; + else + { + yAdjust -= lineIncrement; + _tabsAreaRect.Y -= lineIncrement; + } + + // Start a new line + lineList.Add(new ArrayList()); + + // Make sure the entries are aligned to fill entire line + fullLines++; + } + } + + // Limit the width of a tab to the whole line + if (tabWidth > (xEndPos - xStartPos)) + tabWidth = xEndPos - xStartPos; + + // Construct rectangle for representing this tab + Rectangle tabRect = new Rectangle(xPos, yPos, tabWidth, tabButtonHeight); + + // Add this tab to the current line array + ArrayList thisLine = lineList[lineList.Count - 1] as ArrayList; + + // Create entry to represent the sizing of the given page index + MultiRect tabEntry = new MultiRect(tabRect, i); + + thisLine.Add(tabEntry); + + // Track which line has the selection on it + if (i == _pageSelected) + selectedLine = fullLines; + + // Move position of next tab along + xPos += tabWidth + 1; + + // Increment number of tabs on this line + lineCount++; + } + + int line = 0; + + // Do we need all lines to extend full width + if (_multilineFullWidth) + fullLines++; + + // Make each full line stretch the whole line width + foreach (ArrayList lineArray in lineList) + { + // Only right fill the full lines + if (line < fullLines) + { + // Number of items on this line + int numLines = lineArray.Count; + + // Find ending position of last entry + MultiRect itemEntry = (MultiRect)lineArray[numLines - 1]; + + // Is there spare room between last entry and end of line? + if (itemEntry.Rect.Right < (xEndPos - 1)) + { + // Work out how much extra to give each one + int extra = (int)((xEndPos - itemEntry.Rect.Right - 1) / numLines); + + // Keep track of how much items need moving across + int totalMove = 0; + + // Add into each entry + for (int i = 0; i < numLines; i++) + { + // Get the entry class instance + MultiRect expandEntry = (MultiRect)lineArray[i]; + + // Move across requried amount + expandEntry.X += totalMove; + + // Add extra width + expandEntry.Width += (int)extra; + + // All items after this needing moving + totalMove += extra; + } + + // Extend the last position, in case rounding errors means its short + itemEntry.Width += (xEndPos - itemEntry.Rect.Right - 1); + } + } + + line++; + } + + if (_positionAtTop) + { + // If the selected line is not the bottom line + if (selectedLine != (lineList.Count - 1)) + { + ArrayList lastLine = (ArrayList)(lineList[lineList.Count - 1]); + + // Find y offset of last line + int lastOffset = ((MultiRect)lastLine[0]).Rect.Y; + + // Move all lines below it up one + for (int lineIndex = selectedLine + 1; lineIndex < lineList.Count; lineIndex++) + { + ArrayList al = (ArrayList)lineList[lineIndex]; + + for (int item = 0; item < al.Count; item++) + { + MultiRect itemEntry = (MultiRect)al[item]; + itemEntry.Y -= lineIncrement; + } + } + + // Move selected line to the bottom + ArrayList sl = (ArrayList)lineList[selectedLine]; + + for (int item = 0; item < sl.Count; item++) + { + MultiRect itemEntry = (MultiRect)sl[item]; + itemEntry.Y = lastOffset; + } + } + } + else + { + // If the selected line is not the top line + if (selectedLine != 0) + { + ArrayList topLine = (ArrayList)(lineList[0]); + + // Find y offset of top line + int topOffset = ((MultiRect)topLine[0]).Rect.Y; + + // Move all lines above it down one + for (int lineIndex = 0; lineIndex < selectedLine; lineIndex++) + { + ArrayList al = (ArrayList)lineList[lineIndex]; + + for (int item = 0; item < al.Count; item++) + { + MultiRect itemEntry = (MultiRect)al[item]; + itemEntry.Y += lineIncrement; + } + } + + // Move selected line to the top + ArrayList sl = (ArrayList)lineList[selectedLine]; + + for (int item = 0; item < sl.Count; item++) + { + MultiRect itemEntry = (MultiRect)sl[item]; + itemEntry.Y = topOffset; + } + } + } + + // Now assignt each lines rectangle to the corresponding structure + foreach (ArrayList al in lineList) + { + foreach (MultiRect multiEntry in al) + { + Rectangle newRect = multiEntry.Rect; + + // Make the vertical adjustment + newRect.Y += yAdjust; + + _tabRects[multiEntry.Index] = newRect; + } + } + } + } + + protected virtual void RecalculateSinglelineTabs(int xWidth, int xStartPos, Rectangle tabPosition) + { + using (Graphics g = this.CreateGraphics()) + { + // Remember which lines are then first and last displayed + _topYPos = tabPosition.Y; + _bottomYPos = _topYPos; + + // Set the minimum size for each tab page + for (int i = 0; i < _tabPages.Count; i++) + { + // Is this page before those displayed? + if (i < _startPage) + _tabRects[i] = (object)_nullPosition; // Yes, position off screen + else + _tabRects[i] = (object)tabPosition; // No, create minimum size + } + + // Subtract the minimum tab sizes already allocated + xWidth -= _tabPages.Count * (tabPosition.Width + 1); + + // Is there any more space left to allocate + if (xWidth > 0) + { + ArrayList listNew = new ArrayList(); + ArrayList listOld = new ArrayList(); + + // Add all pages to those that need space allocating + for (int i = _startPage; i < _tabPages.Count; i++) + listNew.Add(_tabPages[i]); + + // Each tab can have an allowance + int xAllowance; + + do + { + // The list generated in the last iteration becomes + // the to be processed in this iteration + listOld = listNew; + + // List of pages that still need more space allocating + listNew = new ArrayList(); + + if (_shrinkPagesToFit) + { + // Each page is allowed a maximum allowance of space + // during this iteration. + xAllowance = xWidth / _tabPages.Count; + } + else + { + // Allow each page as much space as it wants + xAllowance = 999; + } + + // Assign space to each page that is requesting space + foreach (TabPage page in listOld) + { + int index = _tabPages.IndexOf(page); + + Rectangle rectPos = (Rectangle)_tabRects[index]; + + // Find out how much extra space this page is requesting + int xSpace = GetTabPageSpace(g, page) - rectPos.Width; + + // Does it want more space than its currently allowed to have? + if (xSpace > xAllowance) + { + // Restrict allowed space + xSpace = xAllowance; + + // Add page to ensure it gets processed next time around + listNew.Add(page); + } + + // Give space to tab + rectPos.Width += xSpace; + + _tabRects[index] = (object)rectPos; + + // Reduce extra left for remaining tabs + xWidth -= xSpace; + } + } while ((listNew.Count > 0) && (xAllowance > 0) && (xWidth > 0)); + } + + // Assign the final positions to each tab now we known their sizes + for (int i = _startPage; i < _tabPages.Count; i++) + { + Rectangle rectPos = (Rectangle)_tabRects[i]; + + // Define position of tab page + rectPos.X = xStartPos; + + _tabRects[i] = (object)rectPos; + + // Next button must be the width of this one across + xStartPos += rectPos.Width + 1; + } + } + } + + protected virtual void RecalculateButtons() + { + int buttonTopGap = 0; + + if (_multiline) + { + // The height of a tab row is + int tabButtonHeight = _position[_styleIndex, (int)PositionIndex.ImageGapTop] + + _imageGapTopExtra + + _imageHeight + + _imageGapBottomExtra + + _position[_styleIndex, (int)PositionIndex.ImageGapBottom] + + _position[_styleIndex, (int)PositionIndex.BorderBottom]; + + // The height of the tabs area is... + int tabsAreaHeight = _position[_styleIndex, (int)PositionIndex.BorderTop] + + tabButtonHeight + _position[_styleIndex, (int)PositionIndex.TabsBottomGap]; + + // Find offset to place button halfway down the tabs area rectangle + buttonTopGap = _position[_styleIndex, (int)PositionIndex.ButtonOffset] + + (tabsAreaHeight - _buttonHeight) / 2; + + // Invert gap position when at bottom + if (!_positionAtTop) + buttonTopGap = _tabsAreaRect.Height - buttonTopGap - _buttonHeight; + } + else + { + // Find offset to place button halfway down the tabs area rectangle + buttonTopGap = _position[_styleIndex, (int)PositionIndex.ButtonOffset] + + (_tabsAreaRect.Height - _buttonHeight) / 2; + } + + // Position to place next button + int xStart = _tabsAreaRect.Right - _buttonWidth - _buttonGap; + + // Close button should be shown? + if (_showClose) + { + // Define the location + _closeButton.Location = new Point(xStart, _tabsAreaRect.Top + buttonTopGap); + + if (xStart < 1) + _closeButton.Hide(); + else + _closeButton.Show(); + + xStart -= _buttonWidth; + } + else + _closeButton.Hide(); + + // Arrows should be shown? + if (_showArrows) + { + // Position the right arrow first as its more the right hand side + _rightArrow.Location = new Point(xStart, _tabsAreaRect.Top + buttonTopGap); + + if (xStart < 1) + _rightArrow.Hide(); + else + _rightArrow.Show(); + + xStart -= _buttonWidth; + + _leftArrow.Location = new Point(xStart, _tabsAreaRect.Top + buttonTopGap); + + if (xStart < 1) + _leftArrow.Hide(); + else + _leftArrow.Show(); + + xStart -= _buttonWidth; + + // Define then enabled state of buttons + _leftArrow.Enabled = _leftScroll; + _rightArrow.Enabled = _rightScroll; + } + else + { + _leftArrow.Hide(); + _rightArrow.Hide(); + } + + if ((_appearance == VisualAppearance.MultiBox) || (_style == VisualStyle.Plain)) + _closeButton.BackColor = _leftArrow.BackColor = _rightArrow.BackColor = this.BackColor; + else + _closeButton.BackColor = _leftArrow.BackColor = _rightArrow.BackColor = _backIDE; + } + + protected virtual int GetMaximumDrawPos() + { + int xEndPos = _tabsAreaRect.Right - _tabsAreaEndInset; + + // Showing the close button reduces available space + if (_showClose) + xEndPos -= _buttonWidth + _buttonGap; + + // If showing arrows then reduce space for both + if (_showArrows) + xEndPos -= _buttonWidth * 2; + + return xEndPos; + } + + protected virtual int GetTabPageSpace(Graphics g, TabPage page) + { + // Find the fixed elements of required space + int width = _position[_styleIndex, (int)PositionIndex.BorderLeft] + + _position[_styleIndex, (int)PositionIndex.BorderRight]; + + // Any icon or image provided? + if ((page.Icon != null) || (((_imageList != null) || (page.ImageList != null)) && (page.ImageIndex != -1))) + { + width += _position[_styleIndex, (int)PositionIndex.ImageGapLeft] + + _imageWidth + + _position[_styleIndex, (int)PositionIndex.ImageGapRight]; + } + + // Any text provided? + if ((page.Title != null) && (page.Title.Length > 0)) + { + if (!_selectedTextOnly || (_selectedTextOnly && (_pageSelected == _tabPages.IndexOf(page)))) + { + Font drawFont = base.Font; + + if (_boldSelected && page.Selected) + drawFont = new Font(drawFont, FontStyle.Bold); + + // Find width of the requested text + SizeF dimension = g.MeasureString(page.Title, drawFont); + + // Convert to integral + width += _position[_styleIndex, (int)PositionIndex.TextGapLeft] + + (int)dimension.Width + 1; + } + } + + return width; + } + + protected override void OnPaintBackground(PaintEventArgs e) + { + } + + protected override void OnPaint(PaintEventArgs e) + { + // Does the state need recalculating before paint can occur? + if (_recalculate) + Recalculate(); + + using (SolidBrush pageAreaBrush = new SolidBrush(this.BackColor)) + { + // Fill backgrounds of the page and tabs areas + e.Graphics.FillRectangle(pageAreaBrush, _pageAreaRect); + + if ((_style == VisualStyle.Plain) || (_appearance == VisualAppearance.MultiBox)) + { + e.Graphics.FillRectangle(pageAreaBrush, _tabsAreaRect); + } + else + { + using (SolidBrush tabsAreaBrush = new SolidBrush(_backIDE)) + e.Graphics.FillRectangle(tabsAreaBrush, _tabsAreaRect); + } + } + + // MultiBox appearance does not have any borders + if (_appearance != VisualAppearance.MultiBox) + { + bool hiddenPages = HideTabsCalculation(); + + // Draw the borders + switch (_style) + { + case VisualStyle.Plain: + // Height for drawing the border is size of the page area extended + // down to draw the bottom border inside the tabs area + int pageHeight = _pageAreaRect.Height + _plainBorderDouble; + + int xDraw = _pageAreaRect.Top; + + // Should the tabs area be hidden? + if (hiddenPages) + { + // Then need to readjust pageHeight + pageHeight -= _plainBorderDouble; + } + else + { + // If drawing at top then overdraw upwards and not down + if (_positionAtTop) + xDraw -= _plainBorderDouble; + } + + if (_insetBorderPagesOnly) + { + if (!hiddenPages) + { + // Draw the outer border around the page area + DrawHelper.DrawPlainRaisedBorderTopOrBottom(e.Graphics, new Rectangle(0, xDraw, this.Width, pageHeight), + _backLightLight, base.BackColor, _backDark, _backDarkDark, _positionAtTop); + } + } + else + { + // Draw the outer border around the page area + DrawHelper.DrawPlainRaisedBorder(e.Graphics, new Rectangle(_pageAreaRect.Left, xDraw, _pageAreaRect.Width, pageHeight), + _backLightLight, base.BackColor, _backDark, _backDarkDark); + } + + // Do we have any tabs? + if ((_tabPages.Count > 0) && _insetPlain) + { + // Draw the inner border around the page area + Rectangle inner = new Rectangle(_pageAreaRect.Left + _plainBorder, + xDraw + _plainBorder, + _pageAreaRect.Width - _plainBorderDouble, + pageHeight - _plainBorderDouble); + + if (_insetBorderPagesOnly) + { + if (!hiddenPages) + { + DrawHelper.DrawPlainSunkenBorderTopOrBottom(e.Graphics, new Rectangle(0, inner.Top, this.Width, inner.Height), + _backLightLight, base.BackColor, _backDark, _backDarkDark, _positionAtTop); + } + } + else + { + DrawHelper.DrawPlainSunkenBorder(e.Graphics, new Rectangle(inner.Left, inner.Top, inner.Width, inner.Height), + _backLightLight, base.BackColor, _backDark, _backDarkDark); + } + } + break; + + case VisualStyle.IDE: + // Draw the top and bottom borders to the tabs area + using (Pen darkdark = new Pen(_backDarkDark), + dark = new Pen(_backDark), + lightlight = new Pen(_backLightLight), + backColor = new Pen(base.BackColor)) + { + int borderGap = _position[_styleIndex, (int)PositionIndex.BorderTop]; + + if (_positionAtTop) + { + // Fill the border between the tabs and the embedded controls + using (SolidBrush backBrush = new SolidBrush(base.BackColor)) + e.Graphics.FillRectangle(backBrush, 0, _tabsAreaRect.Bottom - borderGap, _tabsAreaRect.Width, borderGap); + + int indent = 0; + + // Is a single pixel border required around whole area? + if (_idePixelBorder) + { + using (Pen llFore = new Pen(ControlPaint.LightLight(this.ForeColor))) + e.Graphics.DrawRectangle(dark, 0, 0, this.Width - 1, this.Height - 1); + + indent++; + } + else + { + if (_idePixelArea) + { + // Draw top border + e.Graphics.DrawLine(dark, 0, _tabsAreaRect.Top, _tabsAreaRect.Width, _tabsAreaRect.Top); + } + } + + // Draw bottom border + if (!hiddenPages) + e.Graphics.DrawLine(lightlight, indent, + _tabsAreaRect.Bottom - borderGap, + _tabsAreaRect.Width - (indent * 2), + _tabsAreaRect.Bottom - borderGap); + } + else + { + // Fill the border between the tabs and the embedded controls + using (SolidBrush backBrush = new SolidBrush(base.BackColor)) + e.Graphics.FillRectangle(backBrush, 0, _tabsAreaRect.Top, _tabsAreaRect.Width, borderGap); + + int indent = 0; + + // Is a single pixel border required around whole area? + if (_idePixelBorder) + { + using (Pen llFore = new Pen(ControlPaint.LightLight(this.ForeColor))) + e.Graphics.DrawRectangle(dark, 0, 0, this.Width - 1, this.Height - 1); + + indent++; + } + else + { + if (_idePixelArea) + { + // Draw bottom border + e.Graphics.DrawLine(backColor, 0, _tabsAreaRect.Bottom - 1, _tabsAreaRect.Width, _tabsAreaRect.Bottom - 1); + } + } + + // Draw top border + if (!hiddenPages) + e.Graphics.DrawLine(darkdark, indent, + _tabsAreaRect.Top + 2, + _tabsAreaRect.Width - (indent * 2), + _tabsAreaRect.Top + 2); + } + } + break; + } + } + + // Clip the drawing to prevent drawing in unwanted areas + ClipDrawingTabs(e.Graphics); + + // Paint each tab page + foreach (TabPage page in _tabPages) + DrawTab(page, e.Graphics, false); + } + + protected virtual Rectangle ClippingRectangle() + { + // Calculate how much to reduce width by for clipping rectangle + int xReduce = _tabsAreaRect.Width - GetMaximumDrawPos(); + + // Create clipping rect + return new Rectangle(_tabsAreaRect.Left, + _tabsAreaRect.Top, + _tabsAreaRect.Width - xReduce, + _tabsAreaRect.Height); + } + + protected virtual void ClipDrawingTabs(Graphics g) + { + Rectangle clipRect = ClippingRectangle(); + + // Restrict drawing to this clipping rectangle + g.Clip = new Region(clipRect); + } + + protected virtual void DrawTab(TabPage page, Graphics g, bool highlightText) + { + Rectangle rectTab = (Rectangle)_tabRects[_tabPages.IndexOf(page)]; + + DrawTabBorder(ref rectTab, page, g); + + int xDraw = rectTab.Left + _position[_styleIndex, (int)PositionIndex.BorderLeft]; + int xMax = rectTab.Right - _position[_styleIndex, (int)PositionIndex.BorderRight]; + + DrawTabImage(rectTab, page, g, xMax, ref xDraw); + DrawTabText(rectTab, page, g, highlightText, xMax, xDraw); + } + + protected virtual void DrawTabImage(Rectangle rectTab, + TabPage page, + Graphics g, + int xMax, + ref int xDraw) + { + // Default to using the Icon from the page + Icon drawIcon = page.Icon; + Image drawImage = null; + + // If there is no valid Icon and the page is requested an image list index... + if ((drawIcon == null) && (page.ImageIndex != -1)) + { + try + { + // Default to using an image from the TabPage + ImageList imageList = page.ImageList; + + // If page does not have an ImageList... + if (imageList == null) + imageList = _imageList; // ...then use the TabControl one + + // Do we have an ImageList to select from? + if (imageList != null) + { + // Grab the requested image + drawImage = imageList.Images[page.ImageIndex]; + } + } + catch (Exception) + { + // User supplied ImageList/ImageIndex are invalid, use an error image instead + drawImage = _internalImages.Images[(int)ImageStrip.Error]; + } + } + + // Draw any image required + if ((drawImage != null) || (drawIcon != null)) + { + // Enough room to draw any of the image? + if ((xDraw + _position[_styleIndex, (int)PositionIndex.ImageGapLeft]) <= xMax) + { + // Move past the left image gap + xDraw += _position[_styleIndex, (int)PositionIndex.ImageGapLeft]; + + // Find down position for drawing the image + int yDraw = rectTab.Top + + _position[_styleIndex, (int)PositionIndex.ImageGapTop] + + _imageGapTopExtra; + + // If there is enough room for all of the image? + if ((xDraw + _imageWidth) <= xMax) + { + if (drawImage != null) + g.DrawImage(drawImage, new Rectangle(xDraw, yDraw, _imageWidth, _imageHeight)); + else + g.DrawIcon(drawIcon, new Rectangle(xDraw, yDraw, _imageWidth, _imageHeight)); + + // Move past the image and the image gap to the right + xDraw += _imageWidth + _position[_styleIndex, (int)PositionIndex.ImageGapRight]; + } + else + { + // Calculate how much room there is + int xSpace = xMax - xDraw; + + // Any room at all? + if (xSpace > 0) + { + if (drawImage != null) + { + // Draw only part of the image + g.DrawImage(drawImage, + new Point[]{new Point(xDraw, yDraw), + new Point(xDraw + xSpace, yDraw), + new Point(xDraw, yDraw + _imageHeight)}, + new Rectangle(0, 0, xSpace, + _imageHeight), + GraphicsUnit.Pixel); + } + + // All space has been used up, nothing left for text + xDraw = xMax; + } + } + } + } + } + + protected virtual void DrawTabText(Rectangle rectTab, + TabPage page, + Graphics g, + bool highlightText, + int xMax, + int xDraw) + { + if (!_selectedTextOnly || (_selectedTextOnly && page.Selected)) + { + // Any space for drawing text? + if (xDraw < xMax) + { + Color drawColor; + SolidBrush drawBrush; + Font drawFont = base.Font; + + // Decide which base color to use + if (highlightText) + drawColor = _hotTextColor; + else + { + // Do we modify base color depending on selection? + if (_dimUnselected && !page.Selected) + { + // Reduce the intensity of the color + drawColor = _textInactiveColor; + } + else + drawColor = _textColor; + } + + // Should selected items be drawn in bold? + if (_boldSelected && page.Selected) + drawFont = new Font(drawFont, FontStyle.Bold); + + // Now the color is determined, create solid brush + drawBrush = new SolidBrush(drawColor); + + // Ensure only a single line is draw from then left hand side of the + // rectangle and if to large for line to shows ellipsis for us + StringFormat drawFormat = new StringFormat(); + drawFormat.FormatFlags = StringFormatFlags.NoClip | StringFormatFlags.NoWrap; + drawFormat.Trimming = StringTrimming.EllipsisCharacter; + drawFormat.Alignment = StringAlignment.Center; + drawFormat.HotkeyPrefix = HotkeyPrefix.Show; + + // Find the vertical drawing limits for text + int yStart = rectTab.Top + _position[_styleIndex, (int)PositionIndex.ImageGapTop]; + + int yEnd = rectTab.Bottom - + _position[_styleIndex, (int)PositionIndex.ImageGapBottom] - + _position[_styleIndex, (int)PositionIndex.BorderBottom]; + + // Use text offset to adjust position of text + yStart += _position[_styleIndex, (int)PositionIndex.TextOffset]; + + // Across the text left gap + xDraw += _position[_styleIndex, (int)PositionIndex.TextGapLeft]; + + // Need at least 1 pixel width before trying to draw + if (xDraw < xMax) + { + // Find drawing rectangle + Rectangle drawRect = new Rectangle(xDraw, yStart, xMax - xDraw, yEnd - yStart); + + // Finally....draw the string! + g.DrawString(page.Title, drawFont, drawBrush, drawRect, drawFormat); + } + + // Cleanup resources! + drawBrush.Dispose(); + } + } + } + + protected virtual void DrawTabBorder(ref Rectangle rectTab, TabPage page, Graphics g) + { + if (_appearance == VisualAppearance.MultiBox) + { + // Adjust the drawing upwards two pixels to 'look pretty' + rectTab.Y -= _multiBoxAdjust; + + // Draw the same regardless of style + DrawMultiBoxBorder(page, g, rectTab); + } + else + { + // Drawing the border is style specific + switch (_style) + { + case VisualStyle.Plain: + DrawPlainTabBorder(page, g, rectTab); + break; + + case VisualStyle.IDE: + DrawIDETabBorder(page, g, rectTab); + break; + } + } + } + + protected virtual void DrawMultiBoxBorder(TabPage page, Graphics g, Rectangle rectPage) + { + if (page.Selected) + { + using (SolidBrush lightlight = new SolidBrush(_backLightLight)) + g.FillRectangle(lightlight, rectPage); + + using (Pen darkdark = new Pen(_backDarkDark)) + g.DrawRectangle(darkdark, rectPage); + } + else + { + using (SolidBrush backBrush = new SolidBrush(this.BackColor)) + g.FillRectangle(backBrush, rectPage.X + 1, rectPage.Y, rectPage.Width - 1, rectPage.Height); + + // Find the index into TabPage collection for this page + int index = _tabPages.IndexOf(page); + + // Decide if the separator should be drawn + bool drawSeparator = (index == _tabPages.Count - 1) || + (index < (_tabPages.Count - 1)) && + (_tabPages[index + 1].Selected != true); + + // MultiLine mode is slighty more complex + if (_multiline && !drawSeparator) + { + // By default always draw separator + drawSeparator = true; + + // If we are not the last item + if (index < (_tabPages.Count - 1)) + { + // If the next item is selected + if (_tabPages[index + 1].Selected == true) + { + Rectangle thisRect = (Rectangle)_tabRects[index]; + Rectangle nextRect = (Rectangle)_tabRects[index + 1]; + + // If we are on the same drawing line then do not draw separator + if (thisRect.Y == nextRect.Y) + drawSeparator = false; + } + } + } + + // Draw tab separator unless the next page after us is selected + if (drawSeparator) + { + using (Pen lightlight = new Pen(_backLightLight), + dark = new Pen(_backDark)) + { + g.DrawLine(dark, rectPage.Right, rectPage.Top + 2, rectPage.Right, + rectPage.Bottom - _position[_styleIndex, (int)PositionIndex.TabsBottomGap] - 1); + g.DrawLine(lightlight, rectPage.Right + 1, rectPage.Top + 2, rectPage.Right + 1, + rectPage.Bottom - _position[_styleIndex, (int)PositionIndex.TabsBottomGap] - 1); + } + } + } + } + + protected virtual void DrawPlainTabBorder(TabPage page, Graphics g, Rectangle rectPage) + { + using (Pen light = new Pen(_backLightLight), + dark = new Pen(_backDark), + darkdark = new Pen(_backDarkDark)) + { + int yLeftOffset = 0; + int yRightOffset = 0; + + using (SolidBrush backBrush = new SolidBrush(base.BackColor)) + { + if (page.Selected) + { + // Calculate the rectangle that covers half the top border area + int yBorder; + + if (_positionAtTop) + yBorder = rectPage.Top + (_position[_styleIndex, (int)PositionIndex.BorderTop] / 2); + else + yBorder = rectPage.Top - (_position[_styleIndex, (int)PositionIndex.BorderTop] / 2); + + // Construct rectangle that covers the outer part of the border + Rectangle rectBorder = new Rectangle(rectPage.Left, yBorder, rectPage.Width - 1, rectPage.Height); + + // Blank out area + g.FillRectangle(backBrush, rectBorder); + + // Make the left and right border lines extend higher up + yLeftOffset = -2; + yRightOffset = -1; + } + } + + if (_positionAtTop) + { + // Draw the left border + g.DrawLine(light, rectPage.Left, rectPage.Bottom, rectPage.Left, rectPage.Top + 2); + g.DrawLine(light, rectPage.Left + 1, rectPage.Top + 1, rectPage.Left + 1, rectPage.Top + 2); + + // Draw the top border + g.DrawLine(light, rectPage.Left + 2, rectPage.Top + 1, rectPage.Right - 2, rectPage.Top + 1); + + // Draw the right border + g.DrawLine(darkdark, rectPage.Right, rectPage.Bottom - yRightOffset, rectPage.Right, rectPage.Top + 2); + g.DrawLine(dark, rectPage.Right - 1, rectPage.Bottom - yRightOffset, rectPage.Right - 1, rectPage.Top + 2); + g.DrawLine(dark, rectPage.Right - 2, rectPage.Top + 1, rectPage.Right - 2, rectPage.Top + 2); + g.DrawLine(darkdark, rectPage.Right - 2, rectPage.Top, rectPage.Right, rectPage.Top + 2); + } + else + { + // Draw the left border + g.DrawLine(light, rectPage.Left, rectPage.Top + yLeftOffset, rectPage.Left, rectPage.Bottom - 2); + g.DrawLine(dark, rectPage.Left + 1, rectPage.Bottom - 1, rectPage.Left + 1, rectPage.Bottom - 2); + + // Draw the bottom border + g.DrawLine(dark, rectPage.Left + 2, rectPage.Bottom - 1, rectPage.Right - 2, rectPage.Bottom - 1); + g.DrawLine(darkdark, rectPage.Left + 2, rectPage.Bottom, rectPage.Right - 2, rectPage.Bottom); + + // Draw the right border + g.DrawLine(darkdark, rectPage.Right, rectPage.Top, rectPage.Right, rectPage.Bottom - 2); + g.DrawLine(dark, rectPage.Right - 1, rectPage.Top + yRightOffset, rectPage.Right - 1, rectPage.Bottom - 2); + g.DrawLine(dark, rectPage.Right - 2, rectPage.Bottom - 1, rectPage.Right - 2, rectPage.Bottom - 2); + g.DrawLine(darkdark, rectPage.Right - 2, rectPage.Bottom, rectPage.Right, rectPage.Bottom - 2); + } + } + } + + protected virtual void DrawIDETabBorder(TabPage page, Graphics g, Rectangle rectPage) + { + using (Pen lightlight = new Pen(_backLightLight), + backColor = new Pen(base.BackColor), + dark = new Pen(_backDark), + darkdark = new Pen(_backDarkDark)) + { + if (page.Selected) + { + // Draw background in selected color + using (SolidBrush pageAreaBrush = new SolidBrush(this.BackColor)) + g.FillRectangle(pageAreaBrush, rectPage); + + if (_positionAtTop) + { + // Overdraw the bottom border + g.DrawLine(backColor, rectPage.Left, rectPage.Bottom, rectPage.Right - 1, rectPage.Bottom); + + // Draw the right border + g.DrawLine(darkdark, rectPage.Right, rectPage.Top, rectPage.Right, rectPage.Bottom); + } + else + { + // Draw the left border + g.DrawLine(lightlight, rectPage.Left, rectPage.Top - 1, rectPage.Left, rectPage.Bottom); + + // Draw the bottom border + g.DrawLine(darkdark, rectPage.Left + 1, rectPage.Bottom, rectPage.Right, rectPage.Bottom); + + // Draw the right border + g.DrawLine(darkdark, rectPage.Right, rectPage.Top - 1, rectPage.Right, rectPage.Bottom); + + // Overdraw the top border + g.DrawLine(backColor, rectPage.Left + 1, rectPage.Top - 1, rectPage.Right - 1, rectPage.Top - 1); + } + } + else + { + // Draw background in unselected color + using (SolidBrush tabsAreaBrush = new SolidBrush(_backIDE)) + g.FillRectangle(tabsAreaBrush, rectPage); + + // Find the index into TabPage collection for this page + int index = _tabPages.IndexOf(page); + + // Decide if the separator should be drawn + bool drawSeparator = (index == _tabPages.Count - 1) || + (index < (_tabPages.Count - 1)) && + (_tabPages[index + 1].Selected != true); + + // MultiLine mode is slighty more complex + if (_multiline && !drawSeparator) + { + // By default always draw separator + drawSeparator = true; + + // If we are not the last item + if (index < (_tabPages.Count - 1)) + { + // If the next item is selected + if (_tabPages[index + 1].Selected == true) + { + Rectangle thisRect = (Rectangle)_tabRects[index]; + Rectangle nextRect = (Rectangle)_tabRects[index + 1]; + + // If we are on the same drawing line then do not draw separator + if (thisRect.Y == nextRect.Y) + drawSeparator = false; + } + } + } + + // Draw tab separator unless the next page after us is selected + if (drawSeparator) + { + // Reduce the intensity of the color + using (Pen linePen = new Pen(_textInactiveColor)) + g.DrawLine(linePen, rectPage.Right, rectPage.Top + 2, rectPage.Right, + rectPage.Bottom - _position[_styleIndex, (int)PositionIndex.TabsBottomGap] - 1); + } + } + } + } + + protected virtual void OnClearingPages() + { + // Is a page currently selected? + if (_pageSelected != -1) + { + // Deselect the page + DeselectPage(_tabPages[_pageSelected]); + + // Remember that nothing is selected + _pageSelected = -1; + _startPage = -1; + } + + // Remove all the user controls + foreach (TabPage page in _tabPages) + RemoveTabPage(page); + + // Remove all rectangles associated with TabPage's + _tabRects.Clear(); + } + + protected virtual void OnClearedPages() + { + // Must recalculate after the pages have been removed and + // not before as that would calculate based on pages still + // being present in the list + Recalculate(); + + // Raise selection changing event + OnSelectionChanging(EventArgs.Empty); + + // Must notify a change in selection + OnSelectionChanged(EventArgs.Empty); + + Invalidate(); + } + + protected virtual void OnInsertingPage(int index, object value) + { + // If a page currently selected? + if (_pageSelected != -1) + { + // Is the selected page going to be after this new one in the list + if (_pageSelected >= index) + _pageSelected++; // then need to update selection index to reflect this + } + } + + protected virtual void OnInsertedPage(int index, object value) + { + bool selectPage = false; + + TabPage page = value as TabPage; + + // Hookup to receive TabPage property changes + page.PropertyChanged += new TabPage.PropChangeHandler(OnPagePropertyChanged); + + // Add the appropriate Control/Form/TabPage to the control + AddTabPage(page); + + // Do we want to select this page? + if ((_pageSelected == -1) || (page.Selected)) + { + // Raise selection changing event + OnSelectionChanging(EventArgs.Empty); + + // Any page currently selected + if (_pageSelected != -1) + DeselectPage(_tabPages[_pageSelected]); + + // This becomes the newly selected page + _pageSelected = _tabPages.IndexOf(page); + + // If no page is currently defined as the start page + if (_startPage == -1) + _startPage = 0; // then must be added then first page + + // Request the page be selected + selectPage = true; + } + + // Add new rectangle to match new number of pages, this must be done before + // the 'SelectPage' or 'OnSelectionChanged' to ensure the number of _tabRects + // entries matches the number of _tabPages entries. + _tabRects.Add((object)new Rectangle()); + + // Cause the new page to be the selected one + if (selectPage) + { + // Must recalculate to ensure the new _tabRects entry above it correctly + // filled in before the new page is selected, as a change in page selection + // may cause the _tabRects values ot be interrogated. + Recalculate(); + + SelectPage(page); + + // Raise selection change event + OnSelectionChanged(EventArgs.Empty); + } + + Recalculate(); + Invalidate(); + } + + protected virtual void OnRemovingPage(int index, object value) + { + TabPage page = value as TabPage; + + page.PropertyChanged -= new TabPage.PropChangeHandler(OnPagePropertyChanged); + + // Remove the appropriate Control/Form/TabPage to the control + RemoveTabPage(page); + + // Notice a change in selected page + _changed = false; + + // Is this the currently selected page + if (_pageSelected == index) + { + // Raise selection changing event + OnSelectionChanging(EventArgs.Empty); + + _changed = true; + DeselectPage(page); + } + } + + protected virtual void OnRemovedPage(int index, object value) + { + // Is first displayed page then one being removed? + if (_startPage >= index) + { + // Decrement to use start displaying previous page + _startPage--; + + // Have we tried to select off the left hand side? + if (_startPage == -1) + { + // Are there still some pages left? + if (_tabPages.Count > 0) + _startPage = 0; + } + } + + // Is the selected page equal to or after this new one in the list + if (_pageSelected >= index) + { + // Decrement index to reflect this change + _pageSelected--; + + // Have we tried to select off the left hand side? + if (_pageSelected == -1) + { + // Are there still some pages left? + if (_tabPages.Count > 0) + _pageSelected = 0; + } + + // Is the new selection valid? + if (_pageSelected != -1) + SelectPage(_tabPages[_pageSelected]); // Select it + } + + // Change in selection causes event generation + if (_changed) + { + // Reset changed flag + _changed = false; + + // Raise selection change event + OnSelectionChanged(EventArgs.Empty); + } + + // Remove a rectangle to match number of pages + _tabRects.RemoveAt(0); + + Recalculate(); + Invalidate(); + } + + protected virtual void AddTabPage(TabPage page) + { + // Has not been shown for the first time yet + page.Shown = false; + + // Add user supplied control + if (page.Control != null) + { + Form controlIsForm = page.Control as Form; + + page.Control.Hide(); + + // Adding a Form takes extra effort + if (controlIsForm == null) + { + // Monitor focus changes on the Control + page.Control.GotFocus += new EventHandler(OnPageEnter); + page.Control.LostFocus += new EventHandler(OnPageLeave); + page.Control.MouseEnter += new EventHandler(OnPageMouseEnter); + page.Control.MouseLeave += new EventHandler(OnPageMouseLeave); + + Controls.Add(page.Control); + } + else + { + // Monitor activation changes on the TabPage + controlIsForm.Activated += new EventHandler(OnPageEnter); + controlIsForm.Deactivate += new EventHandler(OnPageLeave); + controlIsForm.MouseEnter += new EventHandler(OnPageMouseEnter); + controlIsForm.MouseLeave += new EventHandler(OnPageMouseLeave); + + // Have to ensure the Form is not a top level form + controlIsForm.TopLevel = false; + + // We are the new parent of this form + controlIsForm.Parent = this; + + // To prevent user resizing the form manually and prevent + // the caption bar appearing, we use the 'None' border style. + controlIsForm.FormBorderStyle = FormBorderStyle.None; + } + + // Need to monitor when the Form/Panel is clicked + if ((page.Control is Form) || (page.Control is Panel)) + page.Control.MouseDown += new MouseEventHandler(OnPageMouseDown); + + RecursiveMonitor(page.Control, true); + } + else + { + page.Hide(); + + // Monitor focus changes on the TabPage + page.GotFocus += new EventHandler(OnPageEnter); + page.LostFocus += new EventHandler(OnPageLeave); + page.MouseEnter += new EventHandler(OnPageMouseEnter); + page.MouseLeave += new EventHandler(OnPageMouseLeave); + + // Must fill the entire hosting panel it is on + page.Dock = DockStyle.None; + + // Need to monitor when the Panel is clicked + page.MouseDown += new MouseEventHandler(OnPageMouseDown); + + RecursiveMonitor(page, true); + + // Add the TabPage itself instead + Controls.Add(page); + } + } + + protected virtual void RemoveTabPage(TabPage page) + { + // Remove user supplied control + if (page.Control != null) + RemoveTabPageControl(page.Control); + else + RemoveTabPagePanel(page); + } + + protected virtual void RemoveTabPageControl(Control c) + { + RecursiveMonitor(c, false); + + Form controlIsForm = c as Form; + + // Need to unhook hooked up event + if ((c is Form) || (c is Panel)) + c.MouseDown -= new MouseEventHandler(OnPageMouseDown); + + if (controlIsForm == null) + { + // Unhook event monitoring + c.GotFocus -= new EventHandler(OnPageEnter); + c.LostFocus -= new EventHandler(OnPageLeave); + c.MouseEnter -= new EventHandler(OnPageMouseEnter); + c.MouseLeave -= new EventHandler(OnPageMouseLeave); + + // Use helper method to circumvent form Close bug + ControlHelper.Remove(this.Controls, c); + } + else + { + // Unhook activation monitoring + controlIsForm.Activated -= new EventHandler(OnPageEnter); + controlIsForm.Deactivate -= new EventHandler(OnPageLeave); + controlIsForm.MouseEnter -= new EventHandler(OnPageMouseEnter); + controlIsForm.MouseLeave -= new EventHandler(OnPageMouseLeave); + + // Remove Form but prevent the Form close bug + ControlHelper.RemoveForm(this, controlIsForm); + } + } + + protected virtual void RemoveTabPagePanel(TabPage page) + { + RecursiveMonitor(page, false); + + // Need to unhook hooked up event + page.MouseDown -= new MouseEventHandler(OnPageMouseDown); + + // Unhook event monitoring + page.GotFocus -= new EventHandler(OnPageEnter); + page.LostFocus -= new EventHandler(OnPageLeave); + page.MouseEnter -= new EventHandler(OnPageMouseEnter); + page.MouseLeave -= new EventHandler(OnPageMouseLeave); + + // Use helper method to circumvent form Close bug + ControlHelper.Remove(this.Controls, page); + } + + protected virtual void OnPageMouseDown(object sender, MouseEventArgs e) + { + Control c = sender as Control; + + // If the mouse has been clicked and it does not have + // focus then it should receive the focus immediately. + if (!c.ContainsFocus) + c.Focus(); + } + + protected virtual void RecursiveMonitor(Control top, bool monitor) + { + foreach (Control c in top.Controls) + { + if (monitor) + { + // Monitor focus changes on the Control + c.GotFocus += new EventHandler(OnPageEnter); + c.LostFocus += new EventHandler(OnPageLeave); + c.MouseEnter += new EventHandler(OnPageMouseEnter); + c.MouseLeave += new EventHandler(OnPageMouseLeave); + } + else + { + // Unmonitor focus changes on the Control + c.GotFocus -= new EventHandler(OnPageEnter); + c.LostFocus -= new EventHandler(OnPageLeave); + c.MouseEnter -= new EventHandler(OnPageMouseEnter); + c.MouseLeave -= new EventHandler(OnPageMouseLeave); + } + + RecursiveMonitor(c, monitor); + } + } + + protected virtual void OnPageEnter(object sender, EventArgs e) + { + OnPageGotFocus(e); + } + + protected virtual void OnPageLeave(object sender, EventArgs e) + { + OnPageLostFocus(e); + } + + protected virtual void OnPageMouseEnter(object sender, EventArgs e) + { + try + { + _mouseOver = true; + _overTimer.Stop(); + + if (_hideTabsMode == HideTabsModes.HideWithoutMouse) + { + Recalculate(); + Invalidate(); + } + } + catch (Exception) + { + } + } + + protected virtual void OnPageMouseLeave(object sender, EventArgs e) + { + try + { + _overTimer.Start(); + } + catch (Exception) + { + } + } + + protected virtual void OnMouseTick(object sender, EventArgs e) + { + try + { + _mouseOver = false; + _overTimer.Stop(); + + if (_hideTabsMode == HideTabsModes.HideWithoutMouse) + { + Recalculate(); + Invalidate(); + } + } + catch (Exception) + { + } + } + + protected virtual void OnDragOverTick(object sender, EventArgs e) + { + try + { + _dragTimer.Stop(); + + // Allow to select pages on drag over? + if (_dragOverSelect) + { + // Find any tab header the mouse is over + TabPage mouseTab = TabPageFromPoint(_mouseDragOver); + + // Was a tab found? + if (mouseTab != null) + { + // Switch to this tab + if (!mouseTab.Selected) + mouseTab.Selected = true; + } + } + } + catch (Exception) + { + } + } + + protected virtual void OnPagePropertyChanged(TabPage page, TabPage.Property prop, object oldValue) + { + switch (prop) + { + case TabPage.Property.Control: + Control pageControl = oldValue as Control; + + // Remove the page or the page control as appropriate + if (pageControl != null) + RemoveTabPageControl(pageControl); + else + RemoveTabPagePanel(page); + + // Add the appropriate Control/Form/TabPage to the control + AddTabPage(page); + + // Is a page currently selected? + if (_pageSelected != -1) + { + // Is the change in Control for this page? + if (page == _tabPages[_pageSelected]) + SelectPage(page); // make Control visible + } + + Recalculate(); + Invalidate(); + break; + + case TabPage.Property.Title: + case TabPage.Property.ImageIndex: + case TabPage.Property.ImageList: + case TabPage.Property.Icon: + _recalculate = true; + Invalidate(); + break; + + case TabPage.Property.Selected: + // Becoming selected? + if (page.Selected) + { + // Move selection to the new page and update page properties + MovePageSelection(page); + MakePageVisible(page); + } + break; + } + } + + protected virtual Control FindFocus(Control root) + { + // Does the root control has focus? + if (root.Focused) + return root; + + // Check for focus at each child control + foreach (Control c in root.Controls) + { + Control child = FindFocus(c); + + if (child != null) + return child; + } + + return null; + } + + protected virtual void DeselectPage(TabPage page) + { + page.Selected = false; + + // Hide any associated control + if (page.Control != null) + { + // Should we remember which control had focus when leaving? + if (_recordFocus) + { + // Record current focus location on Control + if (page.Control.ContainsFocus) + page.StartFocus = FindFocus(page.Control); + else + page.StartFocus = null; + } + + page.Control.Hide(); + } + else + { + // Should we remember which control had focus when leaving? + if (_recordFocus) + { + // Record current focus location on Control + if (page.ContainsFocus) + page.StartFocus = FindFocus(page); + else + page.StartFocus = null; + } + + page.Hide(); + } + } + + protected virtual void SelectPage(TabPage page) + { + page.Selected = true; + + // Bring the control for this page to the front + if (page.Control != null) + HandleShowingTabPage(page, page.Control); + else + HandleShowingTabPage(page, page); + } + + protected virtual void HandleShowingTabPage(TabPage page, Control c) + { + // First time this page has been displayed? + if (!page.Shown) + { + // Special testing needed for Forms + Form f = c as Form; + + // AutoScaling can cause the Control/Form to be + if ((f != null) && (f.AutoScaleMode != AutoScaleMode.None)) + { + // Workaround the problem where a form has a defined 'AutoScaleBaseSize' value. The + // first time it is shown it calculates the size of each contained control and scales + // as needed. But if the contained control is Dock=DockStyle.Fill it scales up/down so + // its not actually filling the space! Get around by hiding and showing to force correct + // calculation. + c.Show(); + c.Hide(); + } + + // Only need extra logic first time around + page.Shown = true; + } + + // Finally, show it! + c.Show(); + + // Restore focus to last know control to have it + if (page.StartFocus != null) + page.StartFocus.Focus(); + else + c.Focus(); + } + + protected virtual void MovePageSelection(TabPage page) + { + int pageIndex = _tabPages.IndexOf(page); + + if (pageIndex != _pageSelected) + { + // Raise selection changing event + OnSelectionChanging(EventArgs.Empty); + + // Any page currently selected? + if (_pageSelected != -1) + DeselectPage(_tabPages[_pageSelected]); + + _pageSelected = pageIndex; + + if (_pageSelected != -1) + SelectPage(_tabPages[_pageSelected]); + + // Change in selection causes tab pages sizes to change + if (_boldSelected || _selectedTextOnly || !_shrinkPagesToFit || _multiline) + { + Recalculate(); + Invalidate(); + } + + // Raise selection change event + OnSelectionChanged(EventArgs.Empty); + + Invalidate(); + } + } + + // Used by the TabControlDesigner + internal bool WantDoubleClick(IntPtr hWnd, Point mousePos) + { + return ControlWantDoubleClick(hWnd, mousePos, _leftArrow) || + ControlWantDoubleClick(hWnd, mousePos, _rightArrow) || + ControlWantDoubleClick(hWnd, mousePos, _closeButton); + } + + // Used by the TabControlDesigner + internal void ExternalMouseTest(IntPtr hWnd, Point mousePos) + { + if (!(ControlMouseTest(hWnd, mousePos, _leftArrow) || + ControlMouseTest(hWnd, mousePos, _rightArrow) || + ControlMouseTest(hWnd, mousePos, _closeButton))) + InternalMouseDown(mousePos); + } + + protected virtual bool ControlWantDoubleClick(IntPtr hWnd, Point mousePos, Control check) + { + // Cannot have double click if control not visible + if (check.Visible) + { + // Is double click for this control? + if (check.Enabled && (hWnd == check.Handle)) + { + if (check == _leftArrow) + OnLeftArrow(null, EventArgs.Empty); + + if (check == _rightArrow) + OnRightArrow(null, EventArgs.Empty); + + return true; + } + else + { + // Create rectangle for control position + Rectangle checkRect = new Rectangle(check.Location.X, + check.Location.Y, + check.Width, + check.Height); + + // Was double click over a disabled button? + if (checkRect.Contains(mousePos)) + return true; + } + } + + return false; + } + + protected virtual bool ControlMouseTest(IntPtr hWnd, Point mousePos, Control check) + { + // Is the mouse down for the left arrow window and is it valid to click? + if ((hWnd == check.Handle) && check.Visible && check.Enabled) + { + // Check if the mouse click is over the left arrow + if (check.ClientRectangle.Contains(mousePos)) + { + if (check == _leftArrow) + OnLeftArrow(null, EventArgs.Empty); + + if (check == _rightArrow) + OnRightArrow(null, EventArgs.Empty); + + return true; + } + } + + return false; + } + + protected override void OnDoubleClick(EventArgs e) + { + Point pos = TabControl.MousePosition; + + int count = _tabRects.Count; + + for (int index = 0; index < count; index++) + { + // Get tab drawing rectangle + Rectangle local = (Rectangle)_tabRects[index]; + + // If drawing on the control + if (local != _nullPosition) + { + // Convert from Control to screen coordinates + Rectangle screen = this.RectangleToScreen(local); + + if (screen.Contains(pos)) + { + // Generate appropriate event + OnDoubleClickTab(_tabPages[index]); + break; + } + } + } + + base.OnDoubleClick(e); + } + + protected override void OnMouseUp(MouseEventArgs e) + { + if (_leftMouseDownDrag) + { + // Generate event for interested parties + if (e.Button == MouseButtons.Left) + OnPageDragEnd(e); + else + OnPageDragQuit(e); + + _leftMouseDownDrag = false; + _ignoreDownDrag = true; + } + + if (e.Button == MouseButtons.Left) + { + // Exit any page dragging attempt + _leftMouseDown = false; + } + else + { + // Is it the button that causes context menu to show? + if (e.Button == MouseButtons.Right) + { + Point mousePos = new Point(e.X, e.Y); + + // Is the mouse in the tab area + if (_tabsAreaRect.Contains(mousePos)) + { + CancelEventArgs ce = new CancelEventArgs(); + + // Generate event giving handlers cancel to update/cancel menu + OnPopupMenuDisplay(ce); + + // Still want the popup? + if (!ce.Cancel) + { + // Is there any attached menu to show + if (_contextMenu != null) + _contextMenu.TrackPopup(this.PointToScreen(new Point(e.X, e.Y))); + } + } + } + } + + base.OnMouseUp(e); + } + + protected override void OnMouseDown(MouseEventArgs e) + { + // Any mouse press when dragging should quit it + if (_leftMouseDownDrag) + { + OnPageDragQuit(e); + + _leftMouseDownDrag = false; + _ignoreDownDrag = true; + } + else + { + // Only select a button or page when using left mouse button + InternalMouseDown(new Point(e.X, e.Y)); + } + + base.OnMouseDown(e); + } + + protected virtual void InternalMouseDown(Point mousePos) + { + int process = 0; + + // Clicked on a tab page? + for (int i = 0; i < _tabPages.Count; i++) + { + Rectangle rect = (Rectangle)_tabRects[i]; + + if (rect.Contains(mousePos)) + { + // Are the scroll buttons being shown? + if (_leftArrow.Visible) + { + // Ignore mouse down over then buttons area + if (mousePos.X >= _leftArrow.Left) + return; + } + else + { + // No, is the close button visible? + if (_closeButton.Visible) + { + // Ignore mouse down over then close button area + if (mousePos.X >= _closeButton.Left) + return; + } + } + + process = i; + break; + } + else + { + // Remember the last tab to the left of mouse + if (rect.Right < mousePos.X) + process = i; + } + } + + // Is there any page to select? + if (process < _tabPages.Count) + { + // Remember where the left mouse was initially pressed + if (Control.MouseButtons == MouseButtons.Left) + { + _leftMouseDown = true; + _ignoreDownDrag = false; + _leftMouseDownDrag = false; + _leftMouseDownPos = mousePos; + } + + MovePageSelection(_tabPages[process]); + MakePageVisible(_tabPages[process]); + + // Set focus into the selected page contents + if (_tabPages[process].Control != null) + _tabPages[process].Control.Focus(); + else + _tabPages[process].Focus(); + } + } + + protected override void OnMouseMove(MouseEventArgs e) + { + if (_leftMouseDown) + { + if (!_leftMouseDownDrag) + { + Point thisPosition = new Point(e.X, e.Y); + + bool startDrag = false; + + if (_dragFromControl) + startDrag = !this.ClientRectangle.Contains(thisPosition); + else + { + // Create starting mouse down position + Rectangle dragRect = new Rectangle(_leftMouseDownPos, new Size(0, 0)); + + // Expand by size of the double click area + dragRect.Inflate(SystemInformation.DoubleClickSize); + + // Drag when mouse moves outside the double click area + startDrag = !dragRect.Contains(thisPosition); + } + + if (startDrag && !_ignoreDownDrag) + { + // Generate event for interested parties + OnPageDragStart(e); + + // Enter dragging mode + _leftMouseDownDrag = true; + } + } + else + { + // Generate event for interested parties + OnPageDragMove(e); + } + } + else + { + if (_hotTrack || _hoverSelect) + { + int mousePage = -1; + bool pageChanged = false; + + // Create a point representing current mouse position + Point mousePos = new Point(e.X, e.Y); + + // Find the page this mouse point is inside + for (int pos = 0; pos < _tabPages.Count; pos++) + { + Rectangle rect = (Rectangle)_tabRects[pos]; + + if (rect.Contains(mousePos)) + { + mousePage = pos; + break; + } + } + + // Should moving over a tab cause selection changes? + if (_hoverSelect && !_multiline && (mousePage != -1)) + { + // Has the selected page changed? + if (mousePage != _pageSelected) + { + // Move selection to new page + MovePageSelection(_tabPages[mousePage]); + + pageChanged = true; + } + } + + if (_hotTrack && !pageChanged && (mousePage != _hotTrackPage)) + { + Graphics g = this.CreateGraphics(); + + // Clip the drawing to prevent drawing in unwanted areas + ClipDrawingTabs(g); + + // Remove highlight of old page + if (_hotTrackPage != -1) + DrawTab(_tabPages[_hotTrackPage], g, false); + + _hotTrackPage = mousePage; + + // Add highlight to new page + if (_hotTrackPage != -1) + DrawTab(_tabPages[_hotTrackPage], g, true); + + // Must correctly release resource + g.Dispose(); + } + } + } + + base.OnMouseMove(e); + } + + protected override void OnMouseEnter(EventArgs e) + { + try + { + _mouseOver = true; + _overTimer.Stop(); + + base.OnMouseEnter(e); + } + catch (Exception) + { + } + } + + protected override void OnMouseLeave(EventArgs e) + { + if (_hotTrack) + { + int newTrackPage = -1; + + if (newTrackPage != _hotTrackPage) + { + Graphics g = this.CreateGraphics(); + + // Clip the drawing to prevent drawing in unwanted areas + ClipDrawingTabs(g); + + // Remove highlight of old page + if (_hotTrackPage != -1) + DrawTab(_tabPages[_hotTrackPage], g, false); + + _hotTrackPage = newTrackPage; + + // Must correctly release resource + g.Dispose(); + } + } + + try + { + _overTimer.Start(); + } + catch (Exception) + { + } + + base.OnMouseLeave(e); + } + + protected override void OnDragEnter(DragEventArgs e) + { + // Default to an impossible position + _mouseDragOver = new Point(-1, -1); + + base.OnDragEnter(e); + } + + protected override void OnDragOver(DragEventArgs e) + { + // Allow to select pages on drag over? + if (_dragOverSelect) + { + // Remember mouse position for when timer expires + Point mouseDragOver = PointToClient(new Point(e.X, e.Y)); + + // If a new position has been found then restart timer + if (mouseDragOver != _mouseDragOver) + { + // Use the new position + _mouseDragOver = mouseDragOver; + + // Stop if already running + _dragTimer.Stop(); + + // Start running from beginning + _dragTimer.Start(); + } + } + + base.OnDragOver(e); + } + + protected override void OnDragLeave(EventArgs e) + { + // Stop if already running + _dragTimer.Stop(); + + base.OnDragLeave(e); + } + + protected virtual void OnPreferenceChanged(object sender, UserPreferenceChangedEventArgs e) + { + // Are we using the default menu or a user defined value? + if (_defaultFont) + { + DefineFont(SystemInformation.MenuFont); + + Recalculate(); + Invalidate(); + } + } + + protected override void OnSystemColorsChanged(EventArgs e) + { + // If still using the Default color when we were created + if (_defaultColor) + { + DefineBackColor(TabControl.DefaultBackColor); + + Recalculate(); + Invalidate(); + } + + base.OnSystemColorsChanged(e); + } + } +} \ No newline at end of file diff --git a/Labyrinth3/Crownwood.Magic/Controls/TabControl/TabControl.resx b/Labyrinth3/Crownwood.Magic/Controls/TabControl/TabControl.resx new file mode 100644 index 0000000..7e32396 --- /dev/null +++ b/Labyrinth3/Crownwood.Magic/Controls/TabControl/TabControl.resx @@ -0,0 +1,42 @@ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + text/microsoft-resx + + + 1.0.0.0 + + + System.Resources.ResXResourceReader, System.Windows.Forms, Version=1.0.3102.0, Culture=neutral, PublicKeyToken=b77a5c561934e089 + + + System.Resources.ResXResourceWriter, System.Windows.Forms, Version=1.0.3102.0, Culture=neutral, PublicKeyToken=b77a5c561934e089 + + diff --git a/Labyrinth3/Crownwood.Magic/Controls/TabControl/TabControlDesigner.cs b/Labyrinth3/Crownwood.Magic/Controls/TabControl/TabControlDesigner.cs new file mode 100644 index 0000000..ce934ac --- /dev/null +++ b/Labyrinth3/Crownwood.Magic/Controls/TabControl/TabControlDesigner.cs @@ -0,0 +1,101 @@ +// ***************************************************************************** +// +// (c) Crownwood Consulting Limited 2002-2003 +// All rights reserved. The software and associated documentation +// supplied hereunder are the proprietary information of Crownwood Consulting +// Limited, Crownwood, Bracknell, Berkshire, England and are supplied subject +// to licence terms. +// +// Magic Version 1.7.4.0 www.dotnetmagic.com +// ***************************************************************************** + +using System.Collections; +using System.ComponentModel.Design; +using System.Drawing; +using System.Windows.Forms; + +//using Crownwood.Magic.Win32; + +namespace Crownwood.Magic.Controls +{ + public class TabControlDesigner : System.Windows.Forms.Design.ParentControlDesigner + { + private ISelectionService _selectionService = null; + + public override ICollection AssociatedComponents + { + get + { + if (base.Control is Crownwood.Magic.Controls.TabControl) + return ((Crownwood.Magic.Controls.TabControl)base.Control).TabPages; + else + return base.AssociatedComponents; + } + } + + public ISelectionService SelectionService + { + get + { + // Is this the first time the accessor has been called? + if (_selectionService == null) + { + // Then grab and cache the required interface + _selectionService = (ISelectionService)GetService(typeof(ISelectionService)); + } + + return _selectionService; + } + } + + protected override bool DrawGrid + { + get { return false; } + } + + protected override void WndProc(ref Message msg) + { + // Test for the left mouse down windows message + if (msg.Msg == (int)Win32.Msgs.WM_LBUTTONDOWN) + { + // Get access to the TabControl we are the designer for + Crownwood.Magic.Controls.TabControl tabControl = this.SelectionService.PrimarySelection as Crownwood.Magic.Controls.TabControl; + + // Check we have a valid object reference + if (tabControl != null) + { + // Extract the mouse position + int xPos = (short)((uint)msg.LParam & 0x0000FFFFU); + int yPos = (short)(((uint)msg.LParam & 0xFFFF0000U) >> 16); + + // Ask the TabControl to change tabs according to mouse message + tabControl.ExternalMouseTest(msg.HWnd, new Point(xPos, yPos)); + } + } + else + { + if (msg.Msg == (int)Win32.Msgs.WM_LBUTTONDBLCLK) + { + // Get access to the TabControl we are the designer for + Crownwood.Magic.Controls.TabControl tabControl = this.SelectionService.PrimarySelection as Crownwood.Magic.Controls.TabControl; + + // Check we have a valid object reference + if (tabControl != null) + { + // Extract the mouse position + int xPos = (short)((uint)msg.LParam & 0x0000FFFFU); + int yPos = (short)(((uint)msg.LParam & 0xFFFF0000U) >> 16); + + // Ask the TabControl to process a double click over an arrow as a simple + // click of the arrow button. In which case we return immediately to prevent + // the base class from using the double to generate the default event + if (tabControl.WantDoubleClick(msg.HWnd, new Point(xPos, yPos))) + return; + } + } + } + + base.WndProc(ref msg); + } + } +} \ No newline at end of file diff --git a/Labyrinth3/Crownwood.Magic/Controls/TabControl/TabPage.cs b/Labyrinth3/Crownwood.Magic/Controls/TabControl/TabPage.cs new file mode 100644 index 0000000..30e8a35 --- /dev/null +++ b/Labyrinth3/Crownwood.Magic/Controls/TabControl/TabPage.cs @@ -0,0 +1,222 @@ +// ***************************************************************************** +// +// (c) Crownwood Consulting Limited 2002-2003 +// All rights reserved. The software and associated documentation +// supplied hereunder are the proprietary information of Crownwood Consulting +// Limited, Crownwood, Bracknell, Berkshire, England and are supplied subject +// to licence terms. +// +// Magic Version 1.7.4.0 www.dotnetmagic.com +// ***************************************************************************** + +using System.ComponentModel; +using System.Drawing; +using System.Windows.Forms; + +namespace Crownwood.Magic.Controls +{ + [ToolboxItem(false)] + [DefaultProperty("Title")] + [DefaultEvent("PropertyChanged")] + public class TabPage : Panel + { + // Enumeration of property change events + public enum Property + { + Title, + Control, + ImageIndex, + ImageList, + Icon, + Selected, + } + + // Declare the property change event signature + public delegate void PropChangeHandler(TabPage page, Property prop, object oldValue); + + // Public events + public event PropChangeHandler PropertyChanged; + + // Instance fields + protected string _title; + + protected Control _control; + protected int _imageIndex; + protected ImageList _imageList; + protected Icon _icon; + protected bool _selected; + protected Control _startFocus; + protected bool _shown; + + public TabPage() + { + InternalConstruct("Page", null, null, -1, null); + } + + public TabPage(string title) + { + InternalConstruct(title, null, null, -1, null); + } + + public TabPage(string title, Control control) + { + InternalConstruct(title, control, null, -1, null); + } + + public TabPage(string title, Control control, int imageIndex) + { + InternalConstruct(title, control, null, imageIndex, null); + } + + public TabPage(string title, Control control, ImageList imageList, int imageIndex) + { + InternalConstruct(title, control, imageList, imageIndex, null); + } + + public TabPage(string title, Control control, Icon icon) + { + InternalConstruct(title, control, null, -1, icon); + } + + protected void InternalConstruct(string title, + Control control, + ImageList imageList, + int imageIndex, + Icon icon) + { + // Assign parameters to internal fields + _title = title; + _control = control; + _imageIndex = imageIndex; + _imageList = imageList; + _icon = icon; + + // Appropriate defaults + _selected = false; + _startFocus = null; + } + + [DefaultValue("Page")] + [Localizable(true)] + public string Title + { + get { return _title; } + + set + { + if (_title != value) + { + string oldValue = _title; + _title = value; + + OnPropertyChanged(Property.Title, oldValue); + } + } + } + + [DefaultValue(null)] + public Control Control + { + get { return _control; } + + set + { + if (_control != value) + { + Control oldValue = _control; + _control = value; + + OnPropertyChanged(Property.Control, oldValue); + } + } + } + + [DefaultValue(-1)] + public int ImageIndex + { + get { return _imageIndex; } + + set + { + if (_imageIndex != value) + { + int oldValue = _imageIndex; + _imageIndex = value; + + OnPropertyChanged(Property.ImageIndex, oldValue); + } + } + } + + [DefaultValue(null)] + public ImageList ImageList + { + get { return _imageList; } + + set + { + if (_imageList != value) + { + ImageList oldValue = _imageList; + _imageList = value; + + OnPropertyChanged(Property.ImageList, oldValue); + } + } + } + + [DefaultValue(null)] + public Icon Icon + { + get { return _icon; } + + set + { + if (_icon != value) + { + Icon oldValue = _icon; + _icon = value; + + OnPropertyChanged(Property.Icon, oldValue); + } + } + } + + [DefaultValue(true)] + public bool Selected + { + get { return _selected; } + + set + { + if (_selected != value) + { + bool oldValue = _selected; + _selected = value; + + OnPropertyChanged(Property.Selected, oldValue); + } + } + } + + [DefaultValue(null)] + public Control StartFocus + { + get { return _startFocus; } + set { _startFocus = value; } + } + + public virtual void OnPropertyChanged(Property prop, object oldValue) + { + // Any attached event handlers? + if (PropertyChanged != null) + PropertyChanged(this, prop, oldValue); + } + + internal bool Shown + { + get { return _shown; } + set { _shown = value; } + } + } +} \ No newline at end of file diff --git a/Labyrinth3/Crownwood.Magic/Controls/TabControl/TabPage.resx b/Labyrinth3/Crownwood.Magic/Controls/TabControl/TabPage.resx new file mode 100644 index 0000000..7e32396 --- /dev/null +++ b/Labyrinth3/Crownwood.Magic/Controls/TabControl/TabPage.resx @@ -0,0 +1,42 @@ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + text/microsoft-resx + + + 1.0.0.0 + + + System.Resources.ResXResourceReader, System.Windows.Forms, Version=1.0.3102.0, Culture=neutral, PublicKeyToken=b77a5c561934e089 + + + System.Resources.ResXResourceWriter, System.Windows.Forms, Version=1.0.3102.0, Culture=neutral, PublicKeyToken=b77a5c561934e089 + + diff --git a/Labyrinth3/Crownwood.Magic/Controls/TabbedGroups.bmp b/Labyrinth3/Crownwood.Magic/Controls/TabbedGroups.bmp new file mode 100644 index 0000000..d5609c2 Binary files /dev/null and b/Labyrinth3/Crownwood.Magic/Controls/TabbedGroups.bmp differ diff --git a/Labyrinth3/Crownwood.Magic/Controls/TabbedGroups/TabGroupBase.cs b/Labyrinth3/Crownwood.Magic/Controls/TabbedGroups/TabGroupBase.cs new file mode 100644 index 0000000..44e70ab --- /dev/null +++ b/Labyrinth3/Crownwood.Magic/Controls/TabbedGroups/TabGroupBase.cs @@ -0,0 +1,179 @@ +// ***************************************************************************** +// +// (c) Crownwood Consulting Limited 2002-2003 +// All rights reserved. The software and associated documentation +// supplied hereunder are the proprietary information of Crownwood Consulting +// Limited, Crownwood, Bracknell, Berkshire, England and are supplied subject +// to licence terms. +// +// Magic Version 1.7.4.0 www.dotnetmagic.com +// ***************************************************************************** + +using System; +using System.Drawing; +using System.Windows.Forms; +using System.Xml; + +namespace Crownwood.Magic.Controls +{ + public abstract class TabGroupBase : IDisposable + { + public enum NotifyCode + { + StyleChanged, + ProminentChanged, + MinimumSizeChanged, + ResizeBarVectorChanged, + ResizeBarColorChanged, + DisplayTabMode, + ImageListChanging, + ImageListChanged + } + + // Class fields + protected static int _count = 0; + + // Instance fields + protected int _unique; + + protected object _tag; + protected Size _minSize; + protected Decimal _space; + protected TabGroupBase _parent; + protected TabbedGroups _tabbedGroups; + + public TabGroupBase(TabbedGroups tabbedGroups) + { + InternalConstruct(tabbedGroups, null); + } + + public TabGroupBase(TabbedGroups tabbedGroups, TabGroupBase parent) + { + InternalConstruct(tabbedGroups, parent); + } + + 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); + } + + public abstract void Dispose(); + + public Decimal Space + { + get + { + TabGroupLeaf prominent = _tabbedGroups.ProminentLeaf; + + // Are we in prominent mode? + if (prominent != null) + { + // If we are a child of the root sequence + if (_parent.Parent == null) + { + // Then our space is determined by the containment of the prominent leaf + if (this.ContainsProminent(true)) + return 100m; + else + return 0m; + } + else + { + // Else, if we are inside a sequence that contains prominent leaf + if (_parent.ContainsProminent(true)) + { + // Then we need to decide on all or nothing allocation + if (this.ContainsProminent(true)) + return 100m; + else + return 0m; + } + else + { + // Otherwise, we will already be shrunk + return _space; + } + } + } + else + return _space; + } + + set { _space = value; } + } + + internal Decimal RealSpace + { + get { return _space; } + set { _space = value; } + } + + public Size MinimumSize + { + get { return _minSize; } + + set + { + if (!_minSize.Equals(value)) + { + _minSize = value; + + // Inform parent it might need to resize its children + if (_parent != null) + _parent.Notify(NotifyCode.MinimumSizeChanged); + } + } + } + + public TabGroupBase Parent + { + get { return _parent; } + } + + internal void SetParent(TabGroupBase tgb) + { + _parent = tgb; + } + + public TabbedGroups TabbedGroups + { + get { return _tabbedGroups; } + } + + public object Tag + { + get { return _tag; } + set { _tag = value; } + } + + public int Unique + { + get { return _unique; } + } + + // Common Properties not implemented + public abstract int Count { get; } + + public abstract bool IsLeaf { get; } + public abstract bool IsSequence { get; } + public abstract Control GroupControl { get; } + + // Common methods not implemented + public abstract void Notify(NotifyCode code); + + public abstract bool ContainsProminent(bool recurse); + + public abstract void SaveToXml(XmlTextWriter xmlOut); + + public abstract void LoadFromXml(XmlTextReader xmlIn); + } +} \ No newline at end of file diff --git a/Labyrinth3/Crownwood.Magic/Controls/TabbedGroups/TabGroupLeaf.cs b/Labyrinth3/Crownwood.Magic/Controls/TabbedGroups/TabGroupLeaf.cs new file mode 100644 index 0000000..569bf51 --- /dev/null +++ b/Labyrinth3/Crownwood.Magic/Controls/TabbedGroups/TabGroupLeaf.cs @@ -0,0 +1,836 @@ +// ***************************************************************************** +// +// (c) Crownwood Consulting Limited 2002-2003 +// All rights reserved. The software and associated documentation +// supplied hereunder are the proprietary information of Crownwood Consulting +// Limited, Crownwood, Bracknell, Berkshire, England and are supplied subject +// to licence terms. +// +// Magic Version 1.7.4.0 www.dotnetmagic.com +// ***************************************************************************** + +using Crownwood.Magic.Collections; +using Crownwood.Magic.Common; +using Crownwood.Magic.Menus; +using System; +using System.ComponentModel; +using System.Drawing; +using System.Reflection; +using System.Windows.Forms; +using System.Xml; + +namespace Crownwood.Magic.Controls +{ + public class TabGroupLeaf : TabGroupBase + { + // Class constants + protected const int _imageWidth = 16; + + protected const int _imageHeight = 16; + protected const int _imageHorzSplit = 0; + protected const int _imageVertSplit = 1; + + // Class state + protected static ImageList _internalImages; + + // Instance fields + protected MenuCommand _mcClose; + + protected MenuCommand _mcSep1; + protected MenuCommand _mcProm; + protected MenuCommand _mcReba; + protected MenuCommand _mcSep2; + protected MenuCommand _mcPrev; + protected MenuCommand _mcNext; + protected MenuCommand _mcVert; + protected MenuCommand _mcHorz; + protected Cursor _savedCursor; + protected bool _dragEntered; + protected TargetManager _targetManager; + protected Controls.TabControl _tabControl; + + static TabGroupLeaf() + { + // Create a strip of images by loading an embedded bitmap resource + _internalImages = ResourceHelper.LoadBitmapStrip(Type.GetType("Crownwood.Magic.Controls.TabbedGroups"), + "Crownwood.Magic.Resources.ImagesTabbedGroups.bmp", + new Size(_imageWidth, _imageHeight), + new Point(0, 0)); + } + + 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); + } + + public override void Dispose() + { + // Must unhook from the menu related events + _mcClose.Click -= new EventHandler(OnClose); + _mcProm.Click -= new EventHandler(OnToggleProminent); + _mcReba.Click -= new EventHandler(OnRebalance); + _mcHorz.Click -= new EventHandler(OnNewVertical); + _mcVert.Click -= new EventHandler(OnNewHorizontal); + _mcNext.Click -= new EventHandler(OnMoveNext); + _mcPrev.Click -= new EventHandler(OnMovePrevious); + + // If the tab control was created + if (_tabControl != null) + { + // Unhook drag related events + _tabControl.DragDrop -= new DragEventHandler(OnControlDragDrop); + _tabControl.DragEnter -= new DragEventHandler(OnControlDragEnter); + _tabControl.DragLeave -= new EventHandler(OnControlDragLeave); + + // Unhook custom drag related events + _tabControl.PageDragStart -= new MouseEventHandler(OnPageDragStart); + _tabControl.PageDragMove -= new MouseEventHandler(OnPageDragMove); + _tabControl.PageDragEnd -= new MouseEventHandler(OnPageDragEnd); + _tabControl.PageDragQuit -= new MouseEventHandler(OnPageDragQuit); + + // Unhook tab page collection events + _tabControl.TabPages.Cleared -= new CollectionClear(OnTabPagesCleared); + _tabControl.TabPages.Inserted -= new CollectionChange(OnTabPagesInserted); + _tabControl.TabPages.Removed -= new CollectionChange(OnTabPagesRemoved); + + // Unhook tab page level events + _tabControl.GotFocus -= new EventHandler(OnGainedFocus); + _tabControl.PageGotFocus -= new EventHandler(OnGainedFocus); + _tabControl.ClosePressed -= new EventHandler(OnClose); + _tabControl.PopupMenuDisplay -= new CancelEventHandler(OnPopupMenuDisplay); + + // Remove it without hitting close form bug + ControlHelper.RemoveAll(_tabControl); + + // Dispose of the tab control + _tabControl.Dispose(); + _tabControl = null; + } + } + + protected void DefinePopupMenuForControl(Controls.TabControl tabControl) + { + PopupMenu pm = new PopupMenu(); + + // Add all the standard menus we manage + _mcClose = new MenuCommand("", new EventHandler(OnClose)); + _mcSep1 = new MenuCommand("-"); + _mcProm = new MenuCommand("", new EventHandler(OnToggleProminent)); + _mcReba = new MenuCommand("", new EventHandler(OnRebalance)); + _mcSep2 = new MenuCommand("-"); + _mcHorz = new MenuCommand("", _internalImages, _imageHorzSplit, new EventHandler(OnNewVertical)); + _mcVert = new MenuCommand("", _internalImages, _imageVertSplit, new EventHandler(OnNewHorizontal)); + _mcNext = new MenuCommand("", new EventHandler(OnMoveNext)); + _mcPrev = new MenuCommand("", new EventHandler(OnMovePrevious)); + + // Prominent is a radio checked item + _mcProm.RadioCheck = true; + + // Use the provided context menu + tabControl.ContextPopupMenu = pm; + + // Update command states when shown + tabControl.PopupMenuDisplay += new CancelEventHandler(OnPopupMenuDisplay); + } + + public TabPageCollection TabPages + { + get { return _tabControl.TabPages; } + } + + public override void Notify(NotifyCode code) + { + switch (code) + { + case NotifyCode.ImageListChanging: + // Are we using the group level imagelist? + if (_tabbedGroups.ImageList == _tabControl.ImageList) + { + // Then remove its use + _tabControl.ImageList = null; + } + break; + + case NotifyCode.ImageListChanged: + // If no imagelist defined + if (_tabControl.ImageList == null) + { + // Then use the group level one + _tabControl.ImageList = _tabbedGroups.ImageList; + } + break; + + case NotifyCode.StyleChanged: + // Update tab control with new style + _tabControl.Style = _tabbedGroups.Style; + break; + + case NotifyCode.DisplayTabMode: + // Apply the latest mode + switch (_tabbedGroups.DisplayTabMode) + { + case Crownwood.Magic.Controls.TabbedGroups.DisplayTabModes.ShowAll: + _tabControl.HideTabsMode = Magic.Controls.TabControl.HideTabsModes.ShowAlways; + break; + + case Crownwood.Magic.Controls.TabbedGroups.DisplayTabModes.HideAll: + _tabControl.HideTabsMode = Magic.Controls.TabControl.HideTabsModes.HideAlways; + break; + + case Crownwood.Magic.Controls.TabbedGroups.DisplayTabModes.ShowActiveLeaf: + _tabControl.HideTabsMode = (_tabbedGroups.ActiveLeaf == this ? Magic.Controls.TabControl.HideTabsModes.ShowAlways : + Magic.Controls.TabControl.HideTabsModes.HideAlways); + break; + + case Crownwood.Magic.Controls.TabbedGroups.DisplayTabModes.ShowMouseOver: + _tabControl.HideTabsMode = Magic.Controls.TabControl.HideTabsModes.HideWithoutMouse; + break; + + case Crownwood.Magic.Controls.TabbedGroups.DisplayTabModes.ShowActiveAndMouseOver: + _tabControl.HideTabsMode = (_tabbedGroups.ActiveLeaf == this ? Magic.Controls.TabControl.HideTabsModes.ShowAlways : + Magic.Controls.TabControl.HideTabsModes.HideWithoutMouse); + break; + } + break; + } + } + + public override int Count { get { return _tabControl.TabPages.Count; } } + public override bool IsLeaf { get { return true; } } + public override bool IsSequence { get { return false; } } + public override Control GroupControl { get { return _tabControl; } } + + public override bool ContainsProminent(bool recurse) + { + // Cache the currently selected prominent group + TabGroupLeaf prominent = _tabbedGroups.ProminentLeaf; + + // Valid value to test against? + if (prominent != null) + return (this == prominent); + else + return false; + } + + public override void SaveToXml(XmlTextWriter xmlOut) + { + // Output standard values appropriate for all Sequence instances + xmlOut.WriteStartElement("Leaf"); + xmlOut.WriteAttributeString("Count", Count.ToString()); + xmlOut.WriteAttributeString("Unique", _unique.ToString()); + xmlOut.WriteAttributeString("Space", _space.ToString()); + + // Output each tab page + foreach (Controls.TabPage tp in _tabControl.TabPages) + { + string controlType = "null"; + + if (_tabbedGroups.SaveControls && tp.Control != null) + controlType = tp.Control.GetType().AssemblyQualifiedName; + + xmlOut.WriteStartElement("Page"); + xmlOut.WriteAttributeString("Title", tp.Title); + xmlOut.WriteAttributeString("ImageList", (tp.ImageList != null).ToString()); + xmlOut.WriteAttributeString("ImageIndex", tp.ImageIndex.ToString()); + xmlOut.WriteAttributeString("Selected", tp.Selected.ToString()); + xmlOut.WriteAttributeString("Control", controlType); + + // Give handlers chance to reconstruct the page + xmlOut.WriteStartElement("CustomPageData"); + _tabbedGroups.OnPageSaving(new TGPageSavingEventArgs(tp, xmlOut)); + xmlOut.WriteEndElement(); + + xmlOut.WriteEndElement(); + } + + xmlOut.WriteEndElement(); + } + + 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); + + // Convert to correct types + int count = Convert.ToInt32(rawCount); + int unique = Convert.ToInt32(rawUnique); + Decimal space = Convert.ToDecimal(rawSpace); + + // Update myself with new values + _unique = unique; + _space = space; + + // Load each of the children + for (int i = 0; i < count; i++) + { + // Read to the first page element or + if (!xmlIn.Read()) + throw new ArgumentException("An element was expected but could not be read in"); + + // Must always be a page instance + if (xmlIn.Name == "Page") + { + Controls.TabPage tp = new Controls.TabPage(); + + // Grab the expected attributes + string title = xmlIn.GetAttribute(0); + string rawImageList = xmlIn.GetAttribute(1); + string rawImageIndex = xmlIn.GetAttribute(2); + string rawSelected = xmlIn.GetAttribute(3); + string controlType = xmlIn.GetAttribute(4); + + // Convert to correct types + bool imageList = Convert.ToBoolean(rawImageList); + int imageIndex = Convert.ToInt32(rawImageIndex); + bool selected = Convert.ToBoolean(rawSelected); + + // Setup new page instance + tp.Title = title; + tp.ImageIndex = imageIndex; + tp.Selected = selected; + + if (imageList) + tp.ImageList = _tabbedGroups.ImageList; + + // Is there a type description of required control? + if (controlType != "null") + { + try + { + // Get type description, if possible + Type t = Type.GetType(controlType); + + // Was a valid, known type? + if (t != null) + { + // Get the assembly this type is defined inside + Assembly a = t.Assembly; + + if (a != null) + { + // Create a new instance form the assemnly + object newObj = a.CreateInstance(t.FullName); + + Control newControl = newObj as Control; + + // Must derive from Control to be of use to us + if (newControl != null) + tp.Control = newControl; + } + } + } + catch + { + // We ignore failure to recreate given control type + } + } + + // Read to the custom data element + if (!xmlIn.Read()) + throw new ArgumentException("An element was expected but could not be read in"); + + if (xmlIn.Name != "CustomPageData") + throw new ArgumentException("Expected 'CustomPageData' element was not found"); + + bool finished = xmlIn.IsEmptyElement; + + TGPageLoadingEventArgs e = new TGPageLoadingEventArgs(tp, xmlIn); + + // Give handlers chance to reconstruct per-page information + _tabbedGroups.OnPageLoading(e); + + // Add into the control unless handler cancelled add operation + if (!e.Cancel) + _tabControl.TabPages.Add(tp); + + // 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 == "CustomPageData"); + + if (!finished) + { + if (!xmlIn.Read()) + throw new ArgumentException("An element was expected but could not be read in"); + } + } + + // Read past the end of page element + if (!xmlIn.Read()) + throw new ArgumentException("An element was expected but could not be read in"); + + // Check it has the expected name + if (xmlIn.NodeType != XmlNodeType.EndElement) + throw new ArgumentException("End of 'page' element expected but missing"); + } + else + throw new ArgumentException("Unknown element was encountered"); + } + } + + protected void OnGainedFocus(object sender, EventArgs e) + { + // This tab control has the focus, make it the active leaf + _tabbedGroups.ActiveLeaf = this; + } + + protected void OnTabPagesCleared() + { + // All pages removed, do we need to compact? + if (_tabbedGroups.AutoCompact) + _tabbedGroups.Compact(); + + // Mark layout as dirty + if (_tabbedGroups.AutoCalculateDirty) + _tabbedGroups.Dirty = true; + } + + protected void OnTabPagesInserted(int index, object value) + { + // If there is no currently active leaf then make it us + if (_tabbedGroups.ActiveLeaf == null) + _tabbedGroups.ActiveLeaf = this; + + // Mark layout as dirty + if (_tabbedGroups.AutoCalculateDirty) + _tabbedGroups.Dirty = true; + } + + protected void OnTabPagesRemoved(int index, object value) + { + if (_tabControl.TabPages.Count == 0) + { + // All pages removed, do we need to compact? + if (_tabbedGroups.AutoCompact) + _tabbedGroups.Compact(); + } + + // Mark layout as dirty + if (_tabbedGroups.AutoCalculateDirty) + _tabbedGroups.Dirty = true; + } + + 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)); + } + + internal void OnClose(object sender, EventArgs e) + { + // If there anything to close? (or the control has been set to generate event always) + if ((_tabControl.TabPages.Count > 0) || _tabbedGroups.PageCloseWhenEmpty) + { + TGCloseRequestEventArgs tge = new TGCloseRequestEventArgs(this, _tabControl, _tabControl.SelectedTab); + + // Generate event so handlers can perform appropriate action + _tabbedGroups.OnPageCloseRequested(tge); + + // Still want to close the page? (and there is something to close) + if (!tge.Cancel && (_tabControl.TabPages.Count > 0)) + _tabControl.TabPages.Remove(_tabControl.SelectedTab); + } + } + + internal void OnToggleProminent(object sender, EventArgs e) + { + // Toggel the prominent mode + if (_tabbedGroups.ProminentLeaf == this) + _tabbedGroups.ProminentLeaf = null; + else + _tabbedGroups.ProminentLeaf = this; + } + + internal void OnRebalance(object sender, EventArgs e) + { + _tabbedGroups.Rebalance(); + } + + internal void OnMovePrevious(object sender, EventArgs e) + { + // Find the previous leaf node + TabGroupLeaf prev = _tabbedGroups.PreviousLeaf(this); + + // Must always be valid! + if (prev != null) + MovePageToLeaf(prev); + } + + internal void OnMoveNext(object sender, EventArgs e) + { + // Find the previous leaf node + TabGroupLeaf next = _tabbedGroups.NextLeaf(this); + + // Must always be valid! + if (next != null) + MovePageToLeaf(next); + } + + internal void OnNewVertical(object sender, EventArgs e) + { + NewVerticalGroup(this, false); + } + + protected void OnNewHorizontal(object sender, EventArgs e) + { + NewHorizontalGroup(this, false); + } + + internal void NewVerticalGroup(TabGroupLeaf sourceLeaf, bool before) + { + TabGroupSequence tgs = this.Parent as TabGroupSequence; + + // We must have a parent sequence! + if (tgs != null) + { + tgs.Direction = Direction.Vertical; + AddGroupToSequence(tgs, sourceLeaf, before); + } + } + + 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); + } + } + + internal void MovePageToLeaf(TabGroupLeaf leaf) + { + // Remember original auto compact mode + bool autoCompact = _tabbedGroups.AutoCompact; + + // Turn mode off as it interferes with reorganisation + _tabbedGroups.AutoCompact = false; + + // Get the requested tab page to be moved to new leaf + TabPage tp = _tabControl.SelectedTab; + + // Remove page from ourself + _tabControl.TabPages.Remove(tp); + + // Add into the new leaf + leaf.TabPages.Add(tp); + + // Make new leaf the active one + _tabbedGroups.ActiveLeaf = leaf; + + TabControl tc = leaf.GroupControl as Controls.TabControl; + + // Select the newly added page + tc.SelectedTab = 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 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(); + } + + protected void OnPageDragStart(object sender, MouseEventArgs e) + { + // Cannot drag tab pages when the layout is locked + if (!_tabbedGroups.LayoutLock) + { + // Save the current cursor value + _savedCursor = _tabControl.Cursor; + + // Manager will create hot zones and draw dragging rectangle + _targetManager = new TargetManager(_tabbedGroups, this, _tabControl); + } + } + + protected void OnPageDragMove(object sender, MouseEventArgs e) + { + // Cannot drag tab pages when the layout is locked + if (!_tabbedGroups.LayoutLock) + { + // Convert from Control coordinates to screen coordinates + Point mousePos = _tabControl.PointToScreen(new Point(e.X, e.Y)); + + // Let manager decide on drawing rectangles and setting cursor + _targetManager.MouseMove(mousePos); + } + } + + protected void OnPageDragEnd(object sender, MouseEventArgs e) + { + // Cannot drag tab pages when the layout is locked + if (!_tabbedGroups.LayoutLock) + { + // Give manager chance to action request and cleanup + _targetManager.Exit(); + + // No longer need the manager + _targetManager = null; + + if (_tabControl != null) + { + // Restore the original cursor + _tabControl.Cursor = _savedCursor; + } + } + } + + protected void OnPageDragQuit(object sender, MouseEventArgs e) + { + // Cannot drag tab pages when the layout is locked + if (!_tabbedGroups.LayoutLock) + { + // Give manager chance to cleanup + _targetManager.Quit(); + + // No longer need the manager + _targetManager = null; + + // Restore the original cursor + _tabControl.Cursor = _savedCursor; + } + } + + protected void OnControlDragEnter(object sender, DragEventArgs drgevent) + { + // Cannot drag into control when the layout is locked + if (!_tabbedGroups.LayoutLock) + { + _dragEntered = ValidFormat(drgevent); + + // Do we allow the drag to occur? + if (_dragEntered) + { + // Must draw a drag indicator + DrawDragIndicator(); + + // Update the allowed effects + drgevent.Effect = DragDropEffects.Copy; + } + } + else + { + // No drop allowed + drgevent.Effect = DragDropEffects.None; + } + } + + protected void OnControlDragDrop(object sender, DragEventArgs drgevent) + { + // Do we allow the drop to occur? + if (_dragEntered) + { + // Must remove the drag indicator + DrawDragIndicator(); + + // Generate an event so caller can perform required action + _tabbedGroups.OnExternalDrop(this, _tabControl, GetDragProvider(drgevent)); + } + + _dragEntered = false; + } + + protected void OnControlDragLeave(object sender, EventArgs e) + { + // Do we need to remove the drag indicator? + if (_dragEntered) + DrawDragIndicator(); + + _dragEntered = false; + } + + protected bool ValidFormat(DragEventArgs e) + { + return e.Data.GetDataPresent(typeof(TabbedGroups.DragProvider)); + } + + protected TabbedGroups.DragProvider GetDragProvider(DragEventArgs e) + { + return (TabbedGroups.DragProvider)e.Data.GetData(typeof(TabbedGroups.DragProvider)); + } + + protected void DrawDragIndicator() + { + // Create client rectangle + Rectangle clientRect = new Rectangle(new Point(0, 0), _tabControl.ClientSize); + + // Draw drag indicator around whole control + TargetManager.DrawDragRectangle(_tabControl.RectangleToScreen(clientRect)); + } + } +} \ No newline at end of file diff --git a/Labyrinth3/Crownwood.Magic/Controls/TabbedGroups/TabGroupSequence.cs b/Labyrinth3/Crownwood.Magic/Controls/TabbedGroups/TabGroupSequence.cs new file mode 100644 index 0000000..2e8b0d6 --- /dev/null +++ b/Labyrinth3/Crownwood.Magic/Controls/TabbedGroups/TabGroupSequence.cs @@ -0,0 +1,1371 @@ +// ***************************************************************************** +// +// (c) Crownwood Consulting Limited 2002-2003 +// All rights reserved. The software and associated documentation +// supplied hereunder are the proprietary information of Crownwood Consulting +// Limited, Crownwood, Bracknell, Berkshire, England and are supplied subject +// to licence terms. +// +// Magic Version 1.7.4.0 www.dotnetmagic.com +// ***************************************************************************** + +using Crownwood.Magic.Collections; +using Crownwood.Magic.Common; +using System; +using System.Drawing; +using System.Windows.Forms; +using System.Xml; + +namespace Crownwood.Magic.Controls +{ + public class TabGroupSequence : TabGroupBase, IResizeSource + { + // Class fields + protected const int SPACE_PRECISION = 3; + + // Instance fields + protected Control _control; + + protected Direction _direction; + protected TabGroupBaseCollection _children; + + public TabGroupSequence(TabbedGroups tabbedGroups) + : base(tabbedGroups) + { + // Root instance always defaults to being horizontal + InternalConstruct(tabbedGroups, Direction.Horizontal); + } + + public TabGroupSequence(TabbedGroups tabbedGroups, TabGroupBase parent) + : base(tabbedGroups, parent) + { + InternalConstruct(null, Direction.Horizontal); + } + + public TabGroupSequence(TabbedGroups tabbedGroups, TabGroupBase parent, Direction direction) + : base(tabbedGroups, parent) + { + InternalConstruct(null, direction); + } + + protected void InternalConstruct(Control control, Direction direction) + { + // Do we need to create our own window? + if (control == null) + { + // Yes, use a simple panel for organizing children onto + _control = new Panel(); + } + else + { + // No, use the constructor provided one + _control = control; + } + + // Hook into control events + _control.Resize += new EventHandler(OnControlResize); + + // Assign initial values + _direction = direction; + + // Create collection to remember our child objects + _children = new TabGroupBaseCollection(); + } + + public override void Dispose() + { + // Did we manage to create a control? + if (_control != null) + { + // Must unhook to remove references + _control.Resize -= new EventHandler(OnControlResize); + } + } + + public override int Count + { + get { return _children.Count; } + } + + public override bool IsLeaf + { + get { return false; } + } + + public override bool IsSequence + { + get { return true; } + } + + public override Control GroupControl + { + get { return _control; } + } + + public Direction Direction + { + get { return _direction; } + + set + { + if (_direction != value) + { + _direction = value; + RepositionChildren(); + } + } + } + + public VisualStyle Style { get { return _tabbedGroups.Style; } } + public int ResizeBarVector { get { return _tabbedGroups.ResizeBarVector; } } + public Color ResizeBarColor { get { return _tabbedGroups.ResizeBarColor; } } + public Color BackgroundColor { get { return _tabbedGroups.BackColor; } } + + public TabGroupLeaf AddNewLeaf() + { + // Create a new leaf instance with correct back references + TabGroupLeaf tgl = new TabGroupLeaf(_tabbedGroups, this); + + // Add into the collection + Add(tgl); + + // Return its position in collection + return tgl; + } + + public TabGroupLeaf InsertNewLeaf(int index) + { + // 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"); + + // Create a new leaf instance with correct back references + TabGroupLeaf tgl = new TabGroupLeaf(_tabbedGroups, this); + + // Insert into correct collection position + Insert(index, tgl); + + // Return its position in collection + return tgl; + } + + public void Remove(TabGroupBase group) + { + // Convert from reference to index to use existing RemoveAt implementation + RemoveAt(_children.IndexOf(group)); + } + + public void RemoveAt(int index) + { + // Range check index + if (index < 0) + throw new ArgumentOutOfRangeException("index", index, "RemoveAt index must be at least 0"); + + if (index >= _children.Count) + throw new ArgumentOutOfRangeException("index", index, "Cannot remove entry after end of list"); + + // Is the removed item the active leaf? + if (_children[index] == _tabbedGroups.ActiveLeaf) + { + // Then request movement of the active leaf + _tabbedGroups.MoveActiveToNearestFromLeaf(_children[index]); + } + + TabGroupBase childRemoved = _children[index]; + + // Inform control that a group is removed, so it can track number of leafs + _tabbedGroups.GroupRemoved(_children[index]); + + // 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 (index != 0) + pos = index * 2 - 1; + + // Remove Window and bar + + // Use helper method to circumvent form Close bug + ControlHelper.RemoveAt(_control.Controls, pos); + ControlHelper.RemoveAt(_control.Controls, pos); + } + + // How much space is removed entry taking up? + Decimal space = _children[index].Space; + + // Remove child from collection + _children.RemoveAt(index); + + // Redistribute space to other groups + RemoveWindowSpace(space); + + // Update child layout to reflect new proportional spacing values + RepositionChildren(); + + // Last page removed? + if (_children.Count == 0) + { + // All pages removed, do we need to compact? + if (_tabbedGroups.AutoCompact) + _tabbedGroups.Compact(); + } + + // Give control chance to enfore leaf policy + _tabbedGroups.EnforceAtLeastOneLeaf(); + + // Mark layout as dirty + if (_tabbedGroups.AutoCalculateDirty) + _tabbedGroups.Dirty = true; + + // Finally, get rid of resources + childRemoved.Dispose(); + } + + public int IndexOf(TabGroupBase group) + { + return _children.IndexOf(group); + } + + public void Clear() + { + // Do we contain the active leaf? + if (_children.IndexOf(_tabbedGroups.ActiveLeaf) != 0) + { + // Then request movement of the active leaf to different group + _tabbedGroups.MoveActiveToNearestFromSequence(this); + } + + TabGroupBaseCollection copyChildren = new TabGroupBaseCollection(); + + // Inform control about all removed children for leaf counting + foreach (TabGroupBase tgb in _children) + { + // Make temporary copy of the child + copyChildren.Add(tgb); + + // Remove processing + _tabbedGroups.GroupRemoved(tgb); + } + + // Remove all child controls + ControlHelper.RemoveAll(_control); + + // Remove children from collection + _children.Clear(); + + // Must repaint to reflect changes + _control.Invalidate(); + + // All pages removed, do we need to compact? + if (_tabbedGroups.AutoCompact) + _tabbedGroups.Compact(); + + // Give control chance to enfore leaf policy + _tabbedGroups.EnforceAtLeastOneLeaf(); + + // Mark layout as dirty + if (_tabbedGroups.AutoCalculateDirty) + _tabbedGroups.Dirty = true; + + // Inform control about all removed children for leaf counting + foreach (TabGroupBase tgb in copyChildren) + tgb.Dispose(); + } + + public TabGroupBase this[int index] + { + get { return _children[index]; } + } + + public override void Notify(NotifyCode code) + { + // Handle codes of interest + switch (code) + { + case NotifyCode.ProminentChanged: + case NotifyCode.MinimumSizeChanged: + // Must reposition to take account of change + RepositionChildren(); + break; + + case NotifyCode.StyleChanged: + // Inform each resize bar of change in style + foreach (Control c in _control.Controls) + if (c is ResizeBar) + (c as ResizeBar).Style = _tabbedGroups.Style; + + // Reposition the children based on new resize bar size + RepositionChildren(); + break; + + case NotifyCode.ResizeBarVectorChanged: + // Recalculate layout of childreen + RepositionChildren(); + break; + + case NotifyCode.ResizeBarColorChanged: + // If we are showing at least one resize bar + if (_children.Count > 1) + { + // Then must repaint in new color + _control.Invalidate(); + } + break; + } + + // Pass notification to children + foreach (TabGroupBase child in _children) + child.Notify(code); + } + + public void Rebalance(bool recurse) + { + if (_children.Count > 0) + { + // Calculate how much space to give each child + Decimal newSpace = Decimal.Round(100m / _children.Count, SPACE_PRECISION); + + // Assign equal space to all entries + foreach (TabGroupBase group in _children) + group.Space = newSpace; + + Decimal remainderSpace = 100m - (newSpace * _children.Count); + + // Allocate rounding errors to last child + if (remainderSpace != 0) + _children[_children.Count - 1].Space += remainderSpace; + + // Propogate effect into child sequences? + if (recurse) + { + foreach (TabGroupBase group in _children) + if (group.IsSequence) + (group as TabGroupSequence).Rebalance(recurse); + } + } + + // Update child layout to reflect new proportional spacing values + RepositionChildren(); + } + + public override bool ContainsProminent(bool recurse) + { + // Cache the currently selected prominent group + TabGroupLeaf prominent = _tabbedGroups.ProminentLeaf; + + // If not defined then we cannot contain it! + if (prominent == null) + return false; + + // Check our own leaf nodes first + foreach (TabGroupBase group in _children) + if (group.IsLeaf) + if (group == prominent) + return true; + + // Need to check sub-sequences? + if (recurse) + { + // Check our child sequences + foreach (TabGroupBase group in _children) + if (group.IsSequence) + if (group.ContainsProminent(recurse)) + return true; + } + + // Not found + return false; + } + + public override void SaveToXml(XmlTextWriter xmlOut) + { + // Output standard values appropriate for all Sequence instances + xmlOut.WriteStartElement("Sequence"); + xmlOut.WriteAttributeString("Count", _children.Count.ToString()); + xmlOut.WriteAttributeString("Unique", _unique.ToString()); + xmlOut.WriteAttributeString("Space", _space.ToString()); + xmlOut.WriteAttributeString("Direction", _direction.ToString()); + + // Output each sub element + foreach (TabGroupBase tgb in _children) + tgb.SaveToXml(xmlOut); + + xmlOut.WriteEndElement(); + } + + 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); + Direction direction = (rawDirection == "Horizontal" ? Direction.Horizontal : + 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"); + } + } + } + + public void Compact() + { + Compact(_tabbedGroups.CompactOptions); + } + + public void Compact(TabbedGroups.CompactFlags flags) + { + // Compact each child sequence + foreach (TabGroupBase tgb in _children) + if (tgb.IsSequence) + (tgb as TabGroupSequence).Compact(flags); + + // Remove dangling entries + CompactRemoveEmptyTabLeafs(flags); + CompactRemoveEmptyTabSequences(flags); + + // Integrate single entries + CompactReduceSingleEntries(flags); + + // Integrate sub-sequences which run in same direction + CompactReduceSameDirection(flags); + } + + public void Reposition() + { + // Update child layout to reflect new proportional spacing values + RepositionChildren(); + } + + protected void CompactRemoveEmptyTabLeafs(TabbedGroups.CompactFlags flags) + { + // Should we check for empty leaf nodes? + if ((flags & Controls.TabbedGroups.CompactFlags.RemoveEmptyTabLeaf) != 0) + { + int count = _children.Count; + + for (int index = 0; index < count; index++) + { + // Only interested in leaf entries + if (_children[index].IsLeaf) + { + TabGroupLeaf tgl = (TabGroupLeaf)_children[index]; + + // Is this an empty leaf node? + if (tgl.Count == 0) + { + // Update active leaf setting + if (_tabbedGroups.ActiveLeaf == tgl) + { + TabGroupLeaf newLeaf = _tabbedGroups.NextLeaf(tgl); + + if (newLeaf == null) + newLeaf = _tabbedGroups.PreviousLeaf(tgl); + + _tabbedGroups.ActiveLeaf = newLeaf; + } + + // 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 CompactRemoveEmptyTabSequences(TabbedGroups.CompactFlags flags) + { + // Should we check for empty sequence nodes? + if ((flags & Controls.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 CompactReduceSingleEntries(TabbedGroups.CompactFlags flags) + { + bool changed = false; + + // Should we check for single instance nodes? + if ((flags & Controls.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(); + } + + protected void CompactReduceSameDirection(TabbedGroups.CompactFlags flags) + { + bool changed = false; + + // Should we check for same direction sub-sequences? + if ((flags & Controls.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 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; + } + + 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; + } + + 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; + } + + 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; + } + } + + protected void RemoveWindowSpace(Decimal space) + { + // Are there any children to process? + if (_children.Count != 0) + { + // Is there only a single group left? + if (_children.Count == 1) + { + // Give it all the space + _children[0].Space = 100m; + } + else + { + // Is there any space to reallocate? + if (space > 0) + { + // Total up all the values + Decimal totalAllocated = 0m; + + // How much space should we add to each of the others + Decimal freedSpace = space / _children.Count; + + foreach (TabGroupBase group in _children) + { + // We only retain a sensible level of precision + Decimal newSpace = Decimal.Round(group.Space + freedSpace, SPACE_PRECISION); + + // Assign back new space + group.Space = newSpace; + + // Total up all space so far + totalAllocated += newSpace; + } + + // Look for minor errors because not all fractions can be accurately represented in binary! + if (totalAllocated > 100m) + { + // Remove from first entry + _children[0].Space -= totalAllocated - 100m; + } + else if (totalAllocated < 100m) + { + // Add to first entry + _children[0].Space += 100m - totalAllocated; + } + } + } + } + } + + protected void RepositionChildren() + { + // Area available for repositioning + Rectangle clientRect = _control.ClientRectangle; + + // Is there anything to reposition? + if (_children.Count > 0) + { + // Space available for allocation + int space; + + // Starting position of first control + int delta; + + // Values depend on sequence direction + if (_direction == Direction.Vertical) + { + space = clientRect.Height; + delta = clientRect.Top; + } + else + { + space = clientRect.Width; + delta = clientRect.Left; + } + + // Ensure this is not negative + if (space < 0) + space = 0; + + int barSpace = 0; + int allocation = space; + + // 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 group requests. + AllocateMandatorySizes(ref positions, ref barSpace, ref space); + + // Is there any more space left? + if (space > 0) + { + // Pass 2, allocate any space left over according to the requested + // percent space that each group would like to achieve. + AllocateRemainingSpace(ref positions, space); + } + + // Pass 3, reposition the controls according to allocated values. + RepositionChildren(ref positions, clientRect, delta); + } + } + + protected void AllocateMandatorySizes(ref int[] positions, ref int barSpace, ref int space) + { + // Process each control + for (int index = 0, child = 0; index < _control.Controls.Count; index++) + { + ResizeBar bar = _control.Controls[index] as ResizeBar; + + // Is this a resize bar control? + if (bar != null) + { + // Length needed is dependant on direction + positions[index] = bar.Length; + + // Add up how much space was allocated to ResizeBars + barSpace += positions[index]; + } + else + { + Size minimal = _children[child++].MinimumSize; + + // Length needed is depends on direction + if (_direction == Direction.Vertical) + positions[index] = minimal.Height; + else + positions[index] = minimal.Width; + } + + // Reduce available space by that just allocated + space -= positions[index]; + } + } + + protected void AllocateRemainingSpace(ref int[] positions, int windowSpace) + { + // Space allocated so far + int allocated = 0; + + // Process each control + for (int index = 0, childIndex = 0; index < _control.Controls.Count; index++) + { + Control c = _control.Controls[index]; + + bool isResizeBar = (c is ResizeBar); + + // We do not allocate any more space for resize bars + if (!isResizeBar) + { + int extra; + + // How much of remaining space does the group request to have? + extra = (int)(windowSpace / 100m * _children[childIndex++].Space); + + // Is this the last group to be positioned? + if (childIndex == _children.Count) + { + // Use up all the remaining space, this handles the case of the above + // vector calculation giving rounding errors so that the last element + // needs adusting to fill exactly all the available space + extra = windowSpace - allocated; + } + + // Add the extra space to any existing space it has + positions[index] += extra; + + // Keep count of all allocated so far + allocated += extra; + } + } + } + + protected void RepositionChildren(ref int[] positions, Rectangle clientRect, int delta) + { + // Process each control + for (int index = 0; index < _control.Controls.Count; index++) + { + // Delta length for this particular control + int newDelta = positions[index]; + + ResizeBar bar = _control.Controls[index] as ResizeBar; + + if (bar != null) + { + if (_direction == Direction.Vertical) + { + // Set new position + bar.Location = new Point(clientRect.X, delta); + bar.Width = clientRect.Width; + bar.Height = newDelta; + + // Move delta down to next position + delta += newDelta; + } + else + { + // Set new position + bar.Location = new Point(delta, clientRect.Y); + bar.Height = clientRect.Height; + bar.Width = newDelta; + + // Move delta across to next position + delta += newDelta; + } + } + else + { + Control c = _control.Controls[index]; + + if (c != null) + { + if (newDelta == 0) + c.Hide(); + else + { + // Set new position/size based on direction + if (_direction == Direction.Vertical) + { + c.Location = new Point(clientRect.X, delta); + c.Width = clientRect.Width; + c.Height = newDelta; + } + else + { + c.Location = new Point(delta, clientRect.Y); + c.Height = clientRect.Height; + c.Width = newDelta; + } + + if (!c.Visible) + c.Show(); + + // Move delta to next position + delta += newDelta; + } + } + } + } + } + + protected void OnControlResize(object sender, EventArgs e) + { + // Change the layout of the children to match new size + RepositionChildren(); + } + + public bool CanResize(ResizeBar bar) + { + // Cannot resize when in prominent mode + if (!_tabbedGroups.ResizeBarLock && (_tabbedGroups.ProminentLeaf == null)) + { + // Find position of this ResizeBar in the Controls collection + int barIndex = _control.Controls.IndexOf(bar); + + // Convert from control to children indexing + int beforeIndex = (barIndex - 1) / 2; + + TabGroupBase before = _children[beforeIndex]; + TabGroupBase after = _children[beforeIndex + 1]; + + // If groups on both sides have no space then cannot resize there relative positions + if (((before.Space <= 0m) && (after.Space <= 0m))) + return false; + else + return true; + } + else + { + // Must exit prominent mode before resize can occur + return false; + } + } + + public bool StartResizeOperation(ResizeBar bar, ref Rectangle screenBoundary) + { + // Find position of this ResizeBar in the Controls collection + int barIndex = _control.Controls.IndexOf(bar); + + // Convert from control to children indexing + int beforeIndex = (barIndex - 1) / 2; + + // Get groups before and after the resize bar + TabGroupBase before = _children[beforeIndex]; + TabGroupBase after = _children[beforeIndex + 1]; + + // Resizing boundary is defaulted to whole control area + screenBoundary = _control.RectangleToScreen(_control.ClientRectangle); + + // Find screen rectangle for the groups either side of the bar + Rectangle rectBefore = before.GroupControl.RectangleToScreen(before.GroupControl.ClientRectangle); + Rectangle rectAfter = after.GroupControl.RectangleToScreen(after.GroupControl.ClientRectangle); + + // Reduce the boundary in the appropriate direction + if (_direction == Direction.Vertical) + { + screenBoundary.Y = rectBefore.Y + before.MinimumSize.Height; + screenBoundary.Height -= screenBoundary.Bottom - rectAfter.Bottom; + screenBoundary.Height -= after.MinimumSize.Height; + } + else + { + screenBoundary.X = rectBefore.X + before.MinimumSize.Width; + screenBoundary.Width -= screenBoundary.Right - rectAfter.Right; + screenBoundary.Width -= after.MinimumSize.Width; + } + + // Allow resize operation to occur + return true; + } + + public void EndResizeOperation(ResizeBar bar, int delta) + { + // Find position of this ResizeBar in the Controls collection + int barIndex = _control.Controls.IndexOf(bar); + + // Convert from control to children indexing + int beforeIndex = (barIndex - 1) / 2; + + // The Window relating to this bar must be the one before it in the collection + TabGroupBase before = _children[beforeIndex]; + + // Is the Window being expanded + DeltaGroupSpace(before, delta); + + // Mark layout as dirty + if (_tabbedGroups.AutoCalculateDirty) + _tabbedGroups.Dirty = true; + } + + 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(); + } + + internal Control.ControlCollection ChildControls + { + get { return _control.Controls; } + } + } +} \ No newline at end of file diff --git a/Labyrinth3/Crownwood.Magic/Controls/TabbedGroups/TabbedGroupEventArgs.cs b/Labyrinth3/Crownwood.Magic/Controls/TabbedGroups/TabbedGroupEventArgs.cs new file mode 100644 index 0000000..47d51b9 --- /dev/null +++ b/Labyrinth3/Crownwood.Magic/Controls/TabbedGroups/TabbedGroupEventArgs.cs @@ -0,0 +1,126 @@ +// ***************************************************************************** +// +// (c) Crownwood Consulting Limited 2002-2003 +// All rights reserved. The software and associated documentation +// supplied hereunder are the proprietary information of Crownwood Consulting +// Limited, Crownwood, Bracknell, Berkshire, England and are supplied subject +// to licence terms. +// +// Magic Version 1.7.4.0 www.dotnetmagic.com +// ***************************************************************************** + +using Crownwood.Magic.Menus; +using System.Xml; + +namespace Crownwood.Magic.Controls +{ + public class TGCloseRequestEventArgs + { + protected TabGroupLeaf _tgl; + protected Controls.TabControl _tc; + protected Controls.TabPage _tp; + protected bool _cancel; + + public TGCloseRequestEventArgs(TabGroupLeaf tgl, Controls.TabControl tc, Controls.TabPage tp) + { + // Definie initial state + _tgl = tgl; + _tc = tc; + _tp = tp; + _cancel = false; + } + + public TabGroupLeaf Leaf + { + get { return _tgl; } + } + + public Controls.TabControl TabControl + { + get { return _tc; } + } + + public Controls.TabPage TabPage + { + get { return _tp; } + } + + public bool Cancel + { + get { return _cancel; } + set { _cancel = value; } + } + } + + public class TGContextMenuEventArgs : TGCloseRequestEventArgs + { + protected PopupMenu _contextMenu; + + public TGContextMenuEventArgs(TabGroupLeaf tgl, Controls.TabControl tc, + Controls.TabPage tp, PopupMenu contextMenu) + : base(tgl, tc, tp) + { + // Definie initial state + _contextMenu = contextMenu; + } + + public PopupMenu ContextMenu + { + get { return _contextMenu; } + } + } + + public class TGPageLoadingEventArgs + { + protected Controls.TabPage _tp; + protected XmlTextReader _xmlIn; + protected bool _cancel; + + public TGPageLoadingEventArgs(Controls.TabPage tp, XmlTextReader xmlIn) + { + // Definie initial state + _tp = tp; + _xmlIn = xmlIn; + _cancel = false; + } + + public Controls.TabPage TabPage + { + get { return _tp; } + } + + public XmlTextReader XmlIn + { + get { return _xmlIn; } + } + + public bool Cancel + { + get { return _cancel; } + set { _cancel = value; } + } + } + + public class TGPageSavingEventArgs + { + protected Controls.TabPage _tp; + protected XmlTextWriter _xmlOut; + + public TGPageSavingEventArgs(Controls.TabPage tp, XmlTextWriter xmlOut) + { + // Definie initial state + _tp = tp; + _xmlOut = xmlOut; + } + + public Controls.TabPage TabPage + { + get { return _tp; } + } + + public XmlTextWriter XmlOut + { + get { return _xmlOut; } + } + } +} \ No newline at end of file diff --git a/Labyrinth3/Crownwood.Magic/Controls/TabbedGroups/TabbedGroups.cs b/Labyrinth3/Crownwood.Magic/Controls/TabbedGroups/TabbedGroups.cs new file mode 100644 index 0000000..eaaf2dd --- /dev/null +++ b/Labyrinth3/Crownwood.Magic/Controls/TabbedGroups/TabbedGroups.cs @@ -0,0 +1,1943 @@ +// ***************************************************************************** +// +// (c) Crownwood Consulting Limited 2002-2003 +// All rights reserved. The software and associated documentation +// supplied hereunder are the proprietary information of Crownwood Consulting +// Limited, Crownwood, Bracknell, Berkshire, England and are supplied subject +// to licence terms. +// +// Magic Version 1.7.4.0 www.dotnetmagic.com +// ***************************************************************************** + +//using Crownwood.Magic.Win32; +using Crownwood.Magic.Common; +using System; +using System.ComponentModel; +using System.Drawing; +using System.IO; +using System.Text; +using System.Windows.Forms; +using System.Xml; + +namespace Crownwood.Magic.Controls +{ + [ToolboxBitmap(typeof(TabbedGroups))] + public class TabbedGroups : UserControl, ISupportInitialize, IMessageFilter + { + public class DragProvider + { + protected object _tag; + + public DragProvider() + { + _tag = null; + } + + public DragProvider(object tag) + { + _tag = tag; + } + + public object Tag + { + get { return _tag; } + set { _tag = value; } + } + } + + public enum DisplayTabModes + { + HideAll, + ShowAll, + ShowActiveLeaf, + ShowMouseOver, + ShowActiveAndMouseOver + } + + public enum CompactFlags + { + RemoveEmptyTabLeaf = 1, + RemoveEmptyTabSequence = 2, + ReduceSingleEntries = 4, + ReduceSameDirection = 8, + All = 15 + } + + // Instance fields + protected int _numLeafs; + + protected int _defMinWidth; + protected int _defMinHeight; + protected int _resizeBarVector; + protected int _suspendLeafCount; + protected string _closeMenuText; + protected string _prominentMenuText; + protected string _rebalanceMenuText; + protected string _movePreviousMenuText; + protected string _moveNextMenuText; + protected string _newVerticalMenuText; + protected string _newHorizontalMenuText; + protected ImageList _imageList; + protected bool _dirty; + protected bool _autoCalculateDirty; + protected bool _saveControls; + protected bool _initializing; + protected bool _atLeastOneLeaf; + protected bool _autoCompact; + protected bool _compacting; + protected bool _resizeBarLock; + protected bool _layoutLock; + protected bool _pageCloseWhenEmpty; + protected Color _resizeBarColor; + protected Shortcut _closeShortcut; + protected Shortcut _prominentShortcut; + protected Shortcut _rebalanceShortcut; + protected Shortcut _movePreviousShortcut; + protected Shortcut _moveNextShortcut; + protected Shortcut _splitVerticalShortcut; + protected Shortcut _splitHorizontalShortcut; + protected Shortcut _nextTabShortcut; + protected CompactFlags _compactOptions; + protected DisplayTabModes _displayTabMode; + protected TabGroupLeaf _prominentLeaf; + protected TabGroupLeaf _activeLeaf; + protected TabGroupSequence _root; + protected VisualStyle _style; + protected Controls.TabPage _activeTabPage; + + // Delegates for events + public delegate void TabControlCreatedHandler(TabbedGroups tg, Controls.TabControl tc); + + public delegate void PageCloseRequestHandler(TabbedGroups tg, TGCloseRequestEventArgs e); + + public delegate void PageContextMenuHandler(TabbedGroups tg, TGContextMenuEventArgs e); + + public delegate void GlobalSavingHandler(TabbedGroups tg, XmlTextWriter xmlOut); + + public delegate void GlobalLoadingHandler(TabbedGroups tg, XmlTextReader xmlIn); + + public delegate void PageSavingHandler(TabbedGroups tg, TGPageSavingEventArgs e); + + public delegate void PageLoadingHandler(TabbedGroups tg, TGPageLoadingEventArgs e); + + public delegate void ExternalDropHandler(TabbedGroups tg, TabGroupLeaf tgl, Controls.TabControl tc, DragProvider dp); + + public delegate void PageChangeHandler(TabbedGroups tg, Controls.TabPage tp); + + // Instance events + public event TabControlCreatedHandler TabControlCreated; + + public event PageCloseRequestHandler PageCloseRequest; + + public event PageContextMenuHandler PageContextMenu; + + public event GlobalSavingHandler GlobalSaving; + + public event GlobalLoadingHandler GlobalLoading; + + public event PageSavingHandler PageSaving; + + public event PageLoadingHandler PageLoading; + + public event EventHandler ProminentLeafChanged; + + public event EventHandler ActiveLeafChanged; + + public event EventHandler DirtyChanged; + + public event ExternalDropHandler ExternalDrop; + + public event PageChangeHandler PageChanged; + + public TabbedGroups() + { + InternalConstruct(VisualStyle.IDE); + } + + public TabbedGroups(VisualStyle style) + { + InternalConstruct(style); + } + + 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); + } + + protected override void Dispose(bool disposing) + { + if (disposing) + { + // Remove message filter to remove circular reference + Application.RemoveMessageFilter(this); + } + + base.Dispose(disposing); + } + + [Category("TabbedGroups")] + [DefaultValue(typeof(VisualStyle), "IDE")] + public VisualStyle Style + { + get { return _style; } + + set + { + if (_style != value) + { + _style = value; + + // Propogate to all children + Notify(TabGroupBase.NotifyCode.StyleChanged); + } + } + } + + public void ResetStyle() + { + Style = VisualStyle.IDE; + } + + [Browsable(false)] + public TabGroupSequence RootSequence + { + get { return _root; } + } + + [Category("TabbedGroups")] + [DefaultValue(-1)] + public int ResizeBarVector + { + get { return _resizeBarVector; } + + set + { + if (_resizeBarVector != value) + { + _resizeBarVector = value; + + // Propogate to all children + Notify(TabGroupBase.NotifyCode.ResizeBarVectorChanged); + } + } + } + + public void ResetResizeBarVector() + { + ResizeBarVector = -1; + } + + [Category("TabbedGroups")] + public Color ResizeBarColor + { + get { return _resizeBarColor; } + + set + { + if (!_resizeBarColor.Equals(value)) + { + _resizeBarColor = value; + + // Propogate to all children + Notify(TabGroupBase.NotifyCode.ResizeBarColorChanged); + } + } + } + + protected bool ShouldSerializeResizeBackColor() + { + return _resizeBarColor != base.BackColor; + } + + public void ResetResizeBarColor() + { + ResizeBarColor = base.BackColor; + } + + [Category("TabbedGroups")] + [DefaultValue(false)] + public bool ResizeBarLock + { + get { return _resizeBarLock; } + set { _resizeBarLock = value; } + } + + public void ResetResizeBarLock() + { + ResizeBarLock = false; + } + + [Category("TabbedGroups")] + [DefaultValue(false)] + public bool LayoutLock + { + get { return _layoutLock; } + set { _layoutLock = value; } + } + + public void ResetLayoutLock() + { + LayoutLock = false; + } + + [Category("TabbedGroups")] + public TabGroupLeaf ProminentLeaf + { + get { return _prominentLeaf; } + + set + { + if (_prominentLeaf != value) + { + _prominentLeaf = value; + + // Mark layout as dirty + if (_autoCalculateDirty) + _dirty = true; + + // Propogate to all children + Notify(TabGroupBase.NotifyCode.ProminentChanged); + + OnProminentLeafChanged(EventArgs.Empty); + } + } + } + + public void ResetProminentLeaf() + { + ProminentLeaf = null; + } + + [Category("TabbedGroups")] + [DefaultValue(typeof(CompactFlags), "All")] + public CompactFlags CompactOptions + { + get { return _compactOptions; } + set { _compactOptions = value; } + } + + public void ResetCompactOptions() + { + CompactOptions = CompactFlags.All; + } + + [Category("TabbedGroups")] + [DefaultValue(4)] + public int DefaultGroupMinimumWidth + { + get { return _defMinWidth; } + + set + { + if (_defMinWidth != value) + { + _defMinWidth = value; + + // Propogate to all children + Notify(TabGroupBase.NotifyCode.MinimumSizeChanged); + } + } + } + + public void ResetDefaultGroupMinimumWidth() + { + DefaultGroupMinimumWidth = 4; + } + + [Category("TabbedGroups")] + [DefaultValue(4)] + public int DefaultGroupMinimumHeight + { + get { return _defMinHeight; } + + set + { + if (_defMinHeight != value) + { + _defMinHeight = value; + + // Propogate to all children + Notify(TabGroupBase.NotifyCode.MinimumSizeChanged); + } + } + } + + public void ResetDefaultGroupMinimumHeight() + { + DefaultGroupMinimumHeight = 4; + } + + [Localizable(true)] + [Category("Text String")] + [DefaultValue("&Close")] + public string CloseMenuText + { + get { return _closeMenuText; } + set { _closeMenuText = value; } + } + + public void ResetCloseMenuText() + { + CloseMenuText = "&Close"; + } + + [Localizable(true)] + [Category("Text String")] + [DefaultValue("Pro&minent")] + public string ProminentMenuText + { + get { return _prominentMenuText; } + set { _prominentMenuText = value; } + } + + public void ResetProminentMenuText() + { + ProminentMenuText = "Pro&minent"; + } + + [Localizable(true)] + [Category("Text String")] + [DefaultValue("&Rebalance")] + public string RebalanceMenuText + { + get { return _rebalanceMenuText; } + set { _rebalanceMenuText = value; } + } + + public void ResetRebalanceMenuText() + { + RebalanceMenuText = "&Rebalance"; + } + + [Localizable(true)] + [Category("Text String")] + [DefaultValue("Move to &Previous Tab Group")] + public string MovePreviousMenuText + { + get { return _movePreviousMenuText; } + set { _movePreviousMenuText = value; } + } + + public void ResetMovePreviousMenuText() + { + MovePreviousMenuText = "Move to &Previous Tab Group"; + } + + [Localizable(true)] + [Category("Text String")] + [DefaultValue("Move to &Next Tab Group")] + public string MoveNextMenuText + { + get { return _moveNextMenuText; } + set { _moveNextMenuText = value; } + } + + public void ResetMoveNextMenuText() + { + MoveNextMenuText = "Move to &Next Tab Group"; + } + + [Localizable(true)] + [Category("Text String")] + [DefaultValue("New &Vertical Tab Group")] + public string NewVerticalMenuText + { + get { return _newVerticalMenuText; } + set { _newVerticalMenuText = value; } + } + + public void ResetNewVerticalMenuText() + { + NewVerticalMenuText = "New &Vertical Tab Group"; + } + + [Localizable(true)] + [Category("Text String")] + [DefaultValue("New &Horizontal Tab Group")] + public string NewHorizontalMenuText + { + get { return _newHorizontalMenuText; } + set { _newHorizontalMenuText = value; } + } + + public void ResetNewHorizontalMenuText() + { + NewHorizontalMenuText = "New &Horizontal Tab Group"; + } + + [Category("Shortcuts")] + public Shortcut CloseShortcut + { + get { return _closeShortcut; } + set { _closeShortcut = value; } + } + + protected bool ShouldSerializeCloseShortcut() + { + return !_closeShortcut.Equals(Shortcut.CtrlShiftC); + } + + public void ResetCloseShortcut() + { + CloseShortcut = Shortcut.CtrlShiftC; + } + + [Category("Shortcuts")] + public Shortcut ProminentShortcut + { + get { return _prominentShortcut; } + set { _prominentShortcut = value; } + } + + protected bool ShouldSerializeProminentShortcut() + { + return !_prominentShortcut.Equals(Shortcut.CtrlShiftT); + } + + public void ResetProminentShortcut() + { + ProminentShortcut = Shortcut.CtrlShiftT; + } + + [Category("Shortcuts")] + public Shortcut RebalanceShortcut + { + get { return _rebalanceShortcut; } + set { _rebalanceShortcut = value; } + } + + protected bool ShouldSerializeRebalanceShortcut() + { + return !_rebalanceShortcut.Equals(Shortcut.CtrlShiftR); + } + + public void ResetRebalanceShortcut() + { + RebalanceShortcut = Shortcut.CtrlShiftR; + } + + [Category("Shortcuts")] + public Shortcut MovePreviousShortcut + { + get { return _movePreviousShortcut; } + set { _movePreviousShortcut = value; } + } + + protected bool ShouldSerializeMovePreviousShortcut() + { + return !_movePreviousShortcut.Equals(Shortcut.CtrlShiftP); + } + + public void ResetMovePreviousShortcut() + { + MovePreviousShortcut = Shortcut.CtrlShiftP; + } + + [Category("Shortcuts")] + public Shortcut MoveNextShortcut + { + get { return _moveNextShortcut; } + set { _moveNextShortcut = value; } + } + + protected bool ShouldSerializeMoveNextShortcut() + { + return !_moveNextShortcut.Equals(Shortcut.CtrlShiftN); + } + + public void ResetMoveNextShortcut() + { + MoveNextShortcut = Shortcut.CtrlShiftN; + } + + [Category("Shortcuts")] + public Shortcut SplitVerticalShortcut + { + get { return _splitVerticalShortcut; } + set { _splitVerticalShortcut = value; } + } + + protected bool ShouldSerializeSplitVerticalShortcut() + { + return !_splitVerticalShortcut.Equals(Shortcut.CtrlShiftV); + } + + public void ResetSplitVerticalShortcut() + { + SplitVerticalShortcut = Shortcut.CtrlShiftV; + } + + [Category("Shortcuts")] + public Shortcut SplitHorizontalShortcut + { + get { return _splitHorizontalShortcut; } + set { _splitHorizontalShortcut = value; } + } + + protected bool ShouldSerializeSplitHorizontalShortcut() + { + return !_splitHorizontalShortcut.Equals(Shortcut.CtrlShiftH); + } + + public void ResetSplitHorizontalShortcut() + { + SplitHorizontalShortcut = Shortcut.CtrlShiftH; + } + + [Category("TabbedGroups")] + public ImageList ImageList + { + get { return _imageList; } + + set + { + if (_imageList != value) + { + // Propogate to all children + Notify(TabGroupBase.NotifyCode.ImageListChanging); + + _imageList = value; + + // Propogate to all children + Notify(TabGroupBase.NotifyCode.ImageListChanged); + } + } + } + + protected bool ShouldSerializeImageList() + { + return _imageList != null; + } + + public void ResetImageList() + { + ImageList = null; + } + + [Category("TabbedGroups")] + [DefaultValue(typeof(DisplayTabModes), "ShowAll")] + public DisplayTabModes DisplayTabMode + { + get { return _displayTabMode; } + + set + { + if (_displayTabMode != value) + { + _displayTabMode = value; + + // Propogate to all children + Notify(TabGroupBase.NotifyCode.DisplayTabMode); + } + } + } + + public void ResetDisplayTabMode() + { + DisplayTabMode = DisplayTabModes.ShowAll; + } + + [Category("TabbedGroups")] + [DefaultValue(true)] + public bool SaveControls + { + get { return _saveControls; } + set { _saveControls = value; } + } + + public void ResetSaveControls() + { + SaveControls = true; + } + + [Category("TabbedGroups")] + public bool Dirty + { + get { return _dirty; } + + set + { + if (_dirty != value) + { + _dirty = value; + + OnDirtyChanged(EventArgs.Empty); + } + } + } + + protected bool ShouldSerializeDirty() + { + return false; + } + + public void ResetDirty() + { + Dirty = false; + } + + [Category("TabbedGroups")] + [DefaultValue(false)] + public bool PageCloseWhenEmpty + { + get { return _pageCloseWhenEmpty; } + set { _pageCloseWhenEmpty = value; } + } + + public void ResetPageCloseWhenEmpty() + { + PageCloseWhenEmpty = false; + } + + [Category("TabbedGroups")] + [DefaultValue(true)] + public bool AutoCalculateDirty + { + get { return _autoCalculateDirty; } + set { _autoCalculateDirty = value; } + } + + public void ResetAutoCalculateDirty() + { + AutoCalculateDirty = true; + } + + [Category("TabbedGroups")] + public TabGroupLeaf ActiveLeaf + { + get { return _activeLeaf; } + + set + { + if (_activeLeaf != value) + { + // Cannot get rid of the active leaf when there must be one + if (_atLeastOneLeaf && (value == null)) + return; + + // Mark layout as dirty + if (_autoCalculateDirty) + _dirty = true; + + // Remove selection highlight from old leaf + if (_activeLeaf != null) + { + if (_activeLeaf.GroupControl != null) + { + // Get access to the contained tab control + TabControl tc = _activeLeaf.GroupControl as Controls.TabControl; + + // Remove bold text for the selected page + tc.BoldSelectedPage = false; + } + + _activeLeaf = null; + } + + // Set selection highlight on new active leaf + if (value != null) + { + // Get access to the contained tab control + TabControl tc = value.GroupControl as Controls.TabControl; + + // Remove bold text for the selected page + tc.BoldSelectedPage = true; + + _activeLeaf = value; + } + + // Is the tab mode dependant on the active leaf value + if ((_displayTabMode == DisplayTabModes.ShowActiveLeaf) || + (_displayTabMode == DisplayTabModes.ShowActiveAndMouseOver)) + { + // Yes, better notify a change in value so it can be applied + Notify(TabGroupBase.NotifyCode.DisplayTabMode); + } + + CheckForActivePageChange(); + + OnActiveLeafChanged(EventArgs.Empty); + } + } + } + + public void ResetActiveLeaf() + { + ActiveLeaf = null; + } + + private bool ShouldSerializeActiveLeaf() + { + // Never persist this information + return false; + } + + [Category("TabbedGroups")] + public bool AtLeastOneLeaf + { + get { return _atLeastOneLeaf; } + + set + { + if (_atLeastOneLeaf != value) + { + _atLeastOneLeaf = value; + + // Do always need at least one leaf? + if (_atLeastOneLeaf) + { + // Is there at least one? + if (_numLeafs == 0) + { + // No, create a default entry for the root sequence + _root.AddNewLeaf(); + + // Update the active leaf + ActiveLeaf = FirstLeaf(); + + // Mark layout as dirty + if (_autoCalculateDirty) + _dirty = true; + } + } + else + { + // Are there some potential leaves not needed + if (_numLeafs > 0) + { + // Use compaction so only needed ones are retained + if (_autoCompact) + Compact(); + } + } + } + } + } + + public void ResetAtLeastOneLeaf() + { + AtLeastOneLeaf = true; + } + + public Controls.TabPage ActiveTabPage + { + get { return _activeTabPage; } + } + + [Category("TabbedGroups")] + [DefaultValue(true)] + public bool AutoCompact + { + get { return _autoCompact; } + set { _autoCompact = value; } + } + + public void ResetAutoCompact() + { + _autoCompact = true; + } + + public void Rebalance() + { + _root.Rebalance(true); + } + + public void Rebalance(bool recurse) + { + _root.Rebalance(recurse); + } + + public void Compact() + { + Compact(_compactOptions); + } + + public void Compact(CompactFlags flags) + { + // When entries are removed because of compacting this may cause the container object + // to start a compacting request. Prevent this recursion by using a simple varible. + if (!_compacting) + { + // We never compact when loading/initializing the contents + if (!_initializing) + { + _compacting = true; + _root.Compact(flags); + _compacting = false; + + EnforceAtLeastOneLeaf(); + } + } + } + + public TabGroupLeaf FirstLeaf() + { + return RecursiveFindLeafInSequence(_root, true); + } + + public TabGroupLeaf LastLeaf() + { + return RecursiveFindLeafInSequence(_root, false); + } + + public TabGroupLeaf NextLeaf(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, true); + else + return null; + } + + 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; + } + + 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); + } + } + } + + 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); + } + } + } + + public virtual void OnTabControlCreated(Controls.TabControl tc) + { + // Only modify leaf count when not suspended + if (_suspendLeafCount == 0) + { + // Remember how many leafs there are + _numLeafs++; + } + + // Define default values + tc.Appearance = Magic.Controls.TabControl.VisualAppearance.MultiDocument; + tc.BoldSelectedPage = false; + tc.DragOverSelect = false; + tc.IDEPixelBorder = true; + tc.ImageList = _imageList; + tc.Style = _style; + + // Apply the current display tab mode setting + switch (_displayTabMode) + { + case TabbedGroups.DisplayTabModes.ShowAll: + tc.HideTabsMode = Magic.Controls.TabControl.HideTabsModes.ShowAlways; + break; + + case TabbedGroups.DisplayTabModes.HideAll: + tc.HideTabsMode = Magic.Controls.TabControl.HideTabsModes.HideAlways; + break; + } + + tc.SelectionChanged += new EventHandler(OnSelectedTabPageChanged); + + // Has anyone registered for the event? + if (TabControlCreated != null) + TabControlCreated(this, tc); + } + + private void OnSelectedTabPageChanged(Object sender, EventArgs e) + { + CheckForActivePageChange(); + } + + private void CheckForActivePageChange() + { + Controls.TabPage tp = null; + + if (ActiveLeaf != null) + { + Controls.TabControl tc = ActiveLeaf.GroupControl as Controls.TabControl; + if (tc.SelectedIndex != -1) + tp = tc.TabPages[tc.SelectedIndex]; + } + + if (_activeTabPage != tp) + { + _activeTabPage = tp; + OnPageChanged(tp); + } + } + + public virtual void OnPageCloseRequested(TGCloseRequestEventArgs e) + { + // Has anyone registered for the event? + if (PageCloseRequest != null) + PageCloseRequest(this, e); + } + + public virtual void OnPageContextMenu(TGContextMenuEventArgs e) + { + // Has anyone registered for the event? + if (PageContextMenu != null) + PageContextMenu(this, e); + } + + public virtual void OnGlobalSaving(XmlTextWriter xmlOut) + { + // Has anyone registered for the event? + if (GlobalSaving != null) + GlobalSaving(this, xmlOut); + } + + public virtual void OnGlobalLoading(XmlTextReader xmlIn) + { + // Has anyone registered for the event? + if (GlobalLoading != null) + GlobalLoading(this, xmlIn); + } + + public virtual void OnPageSaving(TGPageSavingEventArgs e) + { + // Has anyone registered for the event? + if (PageSaving != null) + PageSaving(this, e); + } + + public virtual void OnPageLoading(TGPageLoadingEventArgs e) + { + // Has anyone registered for the event? + if (PageLoading != null) + PageLoading(this, e); + } + + public virtual void OnProminentLeafChanged(EventArgs e) + { + // Has anyone registered for the event? + if (ProminentLeafChanged != null) + ProminentLeafChanged(this, e); + } + + public virtual void OnActiveLeafChanged(EventArgs e) + { + // Has anyone registered for the event? + if (ActiveLeafChanged != null) + ActiveLeafChanged(this, e); + } + + public virtual void OnDirtyChanged(EventArgs e) + { + // Has anyone registered for the event? + if (DirtyChanged != null) + DirtyChanged(this, e); + } + + public virtual void OnExternalDrop(TabGroupLeaf tgl, Controls.TabControl tc, DragProvider dp) + { + // Has anyone registered for the event? + if (ExternalDrop != null) + ExternalDrop(this, tgl, tc, dp); + } + + public virtual void OnPageChanged(Controls.TabPage tp) + { + if (PageChanged != null) + PageChanged(this, tp); + } + + public void BeginInit() + { + _initializing = true; + } + + public void EndInit() + { + _initializing = false; + + // If don't need a default leaf then compact to get rid of extras + if (AtLeastOneLeaf == false) + Compact(); + + // Inform the root sequence to reposition itself + _root.Reposition(); + } + + public bool Initializing + { + get { return _initializing; } + } + + 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(" Magic, The User Interface library for .NET (www.dotnetmagic.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 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); + } + + 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 Notify(TabGroupBase.NotifyCode notifyCode) + { + // Propogate change notification only is we have a root sequence + if (_root != null) + _root.Notify(notifyCode); + } + + internal void SuspendLeafCount() + { + _suspendLeafCount++; + } + + internal void ResumeLeafCount(int adjust) + { + _suspendLeafCount--; + + // Apply adjustment factor + _numLeafs += adjust; + } + + internal void EnforceAtLeastOneLeaf() + { + // Should not add items during compacting operation + if (!_compacting) + { + // Ensure we enfore policy of at least one leaf + if (_atLeastOneLeaf) + { + // Is there at least one? + if (_numLeafs == 0) + { + // No, create a default entry for the root sequence + _root.AddNewLeaf(); + + // Update the active leaf + ActiveLeaf = FirstLeaf(); + + // Mark layout as dirty + if (_autoCalculateDirty) + _dirty = true; + } + } + } + } + + 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; + } + } + + internal void SetRootSequence(TabGroupSequence tgs) + { + // Use the new sequence as the root + _root = tgs; + } + + public bool PreFilterMessage(ref Message msg) + { + Form parentForm = this.FindForm(); + + // Only interested if the Form we are on is activate (i.e. contains focus) + if ((parentForm != null) && (parentForm == Form.ActiveForm) && parentForm.ContainsFocus) + { + switch (msg.Msg) + { + case (int)Win32.Msgs.WM_KEYDOWN: + // Ignore keyboard input if the control is disabled + if (this.Enabled) + { + // Find up/down state of shift and control keys + ushort shiftKey = 0; //User32.GetKeyState((int)Win32.VirtualKeys.VK_SHIFT); + ushort controlKey = 0; //User32.GetKeyState((int)Win32.VirtualKeys.VK_CONTROL); + + // Basic code we are looking for is the key pressed + int code = (int)msg.WParam; + + // Is SHIFT pressed? + bool shiftPressed = (((int)shiftKey & 0x00008000) != 0); + + // Is CONTROL pressed? + bool controlPressed = (((int)controlKey & 0x00008000) != 0); + + // Was the TAB key pressed? + if ((code == (int)Win32.VirtualKeys.VK_TAB) && controlPressed) + { + if (shiftPressed) + return SelectPreviousTab(); + else + return SelectNextTab(); + } + else + { + // Plus the modifier for SHIFT... + if (shiftPressed) + code += 0x00010000; + + // Plus the modifier for CONTROL + if (controlPressed) + code += 0x00020000; + + // Construct shortcut from keystate and keychar + Shortcut sc = (Shortcut)(code); + + // Search for a matching command + return TestShortcut(sc); + } + } + break; + + case (int)Win32.Msgs.WM_SYSKEYDOWN: + // Ignore keyboard input if the control is disabled + if (this.Enabled) + { + if ((int)msg.WParam != (int)Win32.VirtualKeys.VK_MENU) + { + // Construct shortcut from ALT + keychar + Shortcut sc = (Shortcut)(0x00040000 + (int)msg.WParam); + + // Search for a matching command + return TestShortcut(sc); + } + } + break; + + default: + break; + } + } + + return false; + } + + protected bool TestShortcut(Shortcut sc) + { + bool result = false; + + // Must have an active leaf for shortcuts to operate against + if (_activeLeaf != null) + { + Controls.TabControl tc = _activeLeaf.GroupControl as Controls.TabControl; + + // Must have an active tab for these shortcuts to work against + if (tc.SelectedTab != null) + { + // Close selected page requested? + if (sc.Equals(_closeShortcut)) + { + _activeLeaf.OnClose(_activeLeaf, EventArgs.Empty); + result = true; + } + + // Toggle the prominence state? + if (sc.Equals(_prominentShortcut)) + { + _activeLeaf.OnToggleProminent(_activeLeaf, EventArgs.Empty); + result = true; + } + + // Move page to the next group? + if (sc.Equals(_moveNextShortcut)) + { + _activeLeaf.OnMoveNext(_activeLeaf, EventArgs.Empty); + result = true; + } + + // Move page to the previous group? + if (sc.Equals(_movePreviousShortcut)) + { + _activeLeaf.OnMovePrevious(_activeLeaf, EventArgs.Empty); + result = true; + } + + // Cannot split a group unless at least two entries exist + if (tc.TabPages.Count > 1) + { + bool allowVert = false; + bool allowHorz = false; + + if (_root.Count <= 1) + { + allowVert = true; + allowHorz = true; + } + else + { + if (_root.Direction == Direction.Vertical) + allowVert = true; + else + allowHorz = true; + } + + // Create two vertical groups + if (allowHorz && sc.Equals(_splitVerticalShortcut)) + { + _activeLeaf.NewHorizontalGroup(_activeLeaf, false); + result = true; + } + + // Create two horizontal groups + if (allowVert && sc.Equals(_splitHorizontalShortcut)) + { + _activeLeaf.NewVerticalGroup(_activeLeaf, false); + result = true; + } + } + } + + // Request to rebalance all spacing + if (sc.Equals(_rebalanceShortcut)) + { + _activeLeaf.OnRebalance(_activeLeaf, EventArgs.Empty); + result = true; + } + } + + return result; + } + + protected bool SelectNextTab() + { + // If no active leaf... + if (_activeLeaf == null) + SelectFirstPage(); + else + { + bool selectFirst = false; + TabGroupLeaf startLeaf = _activeLeaf; + TabGroupLeaf thisLeaf = startLeaf; + + do + { + // Access to the embedded tab control + Controls.TabControl tc = thisLeaf.GroupControl as Controls.TabControl; + + // Does it have any pages? + if (tc.TabPages.Count > 0) + { + // Are we allowed to select the first page? + if (selectFirst) + { + // Do it and exit loop + tc.SelectedIndex = 0; + + // Must ensure this becomes the active leaf + if (thisLeaf != _activeLeaf) + ActiveLeaf = thisLeaf; + + break; + } + else + { + // Is there another page after the selected one? + if (tc.SelectedIndex < tc.TabPages.Count - 1) + { + // Select new page and exit loop + tc.SelectedIndex = tc.SelectedIndex + 1; + break; + } + } + } + + selectFirst = true; + + // Find the next leaf in sequence + thisLeaf = NextLeaf(thisLeaf); + + // No more leafs, wrap back to first + if (thisLeaf == null) + thisLeaf = FirstLeaf(); + + // Back at starting leaf? + if (thisLeaf == startLeaf) + { + // If it was not the first page that we started from + if (tc.SelectedIndex > 0) + { + // Then we have circles all the way around, select first page + tc.SelectedIndex = 0; + } + } + } while (thisLeaf != startLeaf); + } + + return true; + } + + protected bool SelectPreviousTab() + { + // If no active leaf... + if (_activeLeaf == null) + SelectLastPage(); + else + { + bool selectLast = false; + TabGroupLeaf startLeaf = _activeLeaf; + TabGroupLeaf thisLeaf = startLeaf; + + do + { + // Access to the embedded tab control + Controls.TabControl tc = thisLeaf.GroupControl as Controls.TabControl; + + // Does it have any pages? + if (tc.TabPages.Count > 0) + { + // Are we allowed to select the last page? + if (selectLast) + { + // Do it and exit loop + tc.SelectedIndex = tc.TabPages.Count - 1; + + // Must ensure this becomes the active leaf + if (thisLeaf != _activeLeaf) + ActiveLeaf = thisLeaf; + + break; + } + else + { + // Is there another page before the selected one? + if (tc.SelectedIndex > 0) + { + // Select previous page and exit loop + tc.SelectedIndex = tc.SelectedIndex - 1; + break; + } + } + } + + selectLast = true; + + // Find the previous leaf in sequence + thisLeaf = PreviousLeaf(thisLeaf); + + // No more leafs, wrap back to first + if (thisLeaf == null) + thisLeaf = LastLeaf(); + + // Back at starting leaf? + if (thisLeaf == startLeaf) + { + // If it was not the first page that we started from + if (tc.SelectedIndex == 0) + { + // Then we have circles all the way around, select last page + tc.SelectedIndex = tc.TabPages.Count - 1; + } + } + } while (thisLeaf != startLeaf); + } + + return true; + } + + protected void SelectFirstPage() + { + // Find the first leaf + ActiveLeaf = FirstLeaf(); + + // Did we find a leaf? + if (_activeLeaf != null) + { + // Is there a page that can be selected? + if (_activeLeaf.TabPages.Count > 0) + _activeLeaf.TabPages[0].Selected = true; + } + } + + protected void SelectLastPage() + { + // Find the first leaf + ActiveLeaf = LastLeaf(); + + // Did we find a leaf? + if (_activeLeaf != null) + { + // Is there a page that can be selected? + if (_activeLeaf.TabPages.Count > 0) + _activeLeaf.TabPages[_activeLeaf.TabPages.Count - 1].Selected = true; + } + } + } +} \ No newline at end of file diff --git a/Labyrinth3/Crownwood.Magic/Controls/TabbedGroups/TabbedGroups.resx b/Labyrinth3/Crownwood.Magic/Controls/TabbedGroups/TabbedGroups.resx new file mode 100644 index 0000000..7e32396 --- /dev/null +++ b/Labyrinth3/Crownwood.Magic/Controls/TabbedGroups/TabbedGroups.resx @@ -0,0 +1,42 @@ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + text/microsoft-resx + + + 1.0.0.0 + + + System.Resources.ResXResourceReader, System.Windows.Forms, Version=1.0.3102.0, Culture=neutral, PublicKeyToken=b77a5c561934e089 + + + System.Resources.ResXResourceWriter, System.Windows.Forms, Version=1.0.3102.0, Culture=neutral, PublicKeyToken=b77a5c561934e089 + + diff --git a/Labyrinth3/Crownwood.Magic/Controls/TabbedGroups/Target.cs b/Labyrinth3/Crownwood.Magic/Controls/TabbedGroups/Target.cs new file mode 100644 index 0000000..9aa91b3 --- /dev/null +++ b/Labyrinth3/Crownwood.Magic/Controls/TabbedGroups/Target.cs @@ -0,0 +1,253 @@ +// ***************************************************************************** +// +// (c) Crownwood Consulting Limited 2002-2003 +// All rights reserved. The software and associated documentation +// supplied hereunder are the proprietary information of Crownwood Consulting +// Limited, Crownwood, Bracknell, Berkshire, England and are supplied subject +// to licence terms. +// +// Magic Version 1.7.4.0 www.dotnetmagic.com +// ***************************************************************************** + +using Crownwood.Magic.Collections; +using Crownwood.Magic.Common; +using System; +using System.Drawing; +using System.Windows.Forms; + +namespace Crownwood.Magic.Controls +{ + public class Target + { + public enum TargetActions + { + Transfer, + GroupLeft, + GroupRight, + GroupTop, + GroupBottom + } + + // Instance fields + protected Rectangle _hotRect; + + protected Rectangle _drawRect; + protected TabGroupLeaf _leaf; + protected TargetActions _action; + + public Target(Rectangle hotRect, Rectangle drawRect, TabGroupLeaf leaf, TargetActions action) + { + // Define state + _hotRect = hotRect; + _drawRect = drawRect; + _leaf = leaf; + _action = action; + } + + public Rectangle HotRect + { + get { return _hotRect; } + } + + public Rectangle DrawRect + { + get { return _drawRect; } + } + + public TabGroupLeaf Leaf + { + get { return _leaf; } + } + + public TargetActions Action + { + get { return _action; } + } + } + + public class TargetManager + { + // Class fields + protected const int _rectWidth = 4; + + protected static Cursor _validCursor; + protected static Cursor _invalidCursor; + + // Instance fields + protected TabbedGroups _host; + + protected TabGroupLeaf _leaf; + protected Controls.TabControl _source; + protected Target _lastTarget; + protected TargetCollection _targets; + + static TargetManager() + { + _validCursor = ResourceHelper.LoadCursor(Type.GetType("Crownwood.Magic.Controls.TabbedGroups"), + "Crownwood.Magic.Resources.TabbedValid.cur"); + + _invalidCursor = ResourceHelper.LoadCursor(Type.GetType("Crownwood.Magic.Controls.TabbedGroups"), + "Crownwood.Magic.Resources.TabbedInvalid.cur"); + } + + public TargetManager(TabbedGroups host, TabGroupLeaf leaf, Controls.TabControl source) + { + // Define state + _host = host; + _leaf = leaf; + _source = source; + _lastTarget = null; + + // Create collection to hold generated targets + _targets = new TargetCollection(); + + // Process each potential leaf in turn + TabGroupLeaf tgl = host.FirstLeaf(); + + while (tgl != null) + { + // Create all possible targets for this leaf + CreateTargets(tgl); + + // Enumerate all leafs + tgl = host.NextLeaf(tgl); + } + } + + 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)); + } + } + + public void MouseMove(Point mousePos) + { + // Find the Target the mouse is currently over (if any) + Target t = _targets.Contains(mousePos); + + // Set appropriate cursor + if (t != null) + _source.Cursor = _validCursor; + else + _source.Cursor = _invalidCursor; + + if (t != _lastTarget) + { + // Remove the old indicator + if (_lastTarget != null) + DrawHelper.DrawDragRectangle(_lastTarget.DrawRect, _rectWidth); + + // Draw the new indicator + if (t != null) + DrawHelper.DrawDragRectangle(t.DrawRect, _rectWidth); + + // Remember for next time around + _lastTarget = t; + } + } + + public void Exit() + { + // Remove any showing indicator + Quit(); + + if (_lastTarget != null) + { + // Perform action specific operation + switch (_lastTarget.Action) + { + case Target.TargetActions.Transfer: + // Transfer selecte page from source to destination + _leaf.MovePageToLeaf(_lastTarget.Leaf); + break; + + case Target.TargetActions.GroupLeft: + _lastTarget.Leaf.NewHorizontalGroup(_leaf, true); + break; + + case Target.TargetActions.GroupRight: + _lastTarget.Leaf.NewHorizontalGroup(_leaf, false); + break; + + case Target.TargetActions.GroupTop: + _lastTarget.Leaf.NewVerticalGroup(_leaf, true); + break; + + case Target.TargetActions.GroupBottom: + _lastTarget.Leaf.NewVerticalGroup(_leaf, false); + break; + } + } + } + + public void Quit() + { + // Remove drawing of any indicator + if (_lastTarget != null) + DrawHelper.DrawDragRectangle(_lastTarget.DrawRect, _rectWidth); + } + + public static void DrawDragRectangle(Rectangle rect) + { + DrawHelper.DrawDragRectangle(rect, _rectWidth); + } + } +} \ No newline at end of file diff --git a/Labyrinth3/Crownwood.Magic/Controls/WizardControl.bmp b/Labyrinth3/Crownwood.Magic/Controls/WizardControl.bmp new file mode 100644 index 0000000..e619008 Binary files /dev/null and b/Labyrinth3/Crownwood.Magic/Controls/WizardControl.bmp differ diff --git a/Labyrinth3/Crownwood.Magic/Controls/WizardControl/WizardControl.cs b/Labyrinth3/Crownwood.Magic/Controls/WizardControl/WizardControl.cs new file mode 100644 index 0000000..474a997 --- /dev/null +++ b/Labyrinth3/Crownwood.Magic/Controls/WizardControl/WizardControl.cs @@ -0,0 +1,1844 @@ +// ***************************************************************************** +// +// (c) Crownwood Consulting Limited 2002-2003 +// All rights reserved. The software and associated documentation +// supplied hereunder are the proprietary information of Crownwood Consulting +// Limited, Crownwood, Bracknell, Berkshire, England and are supplied subject +// to licence terms. +// +// Magic Version 1.7.4.0 www.dotnetmagic.com +// ***************************************************************************** + +using Crownwood.Magic.Collections; +using Crownwood.Magic.Common; +using System; +using System.ComponentModel; +using System.Drawing; +using System.Windows.Forms; + +namespace Crownwood.Magic.Controls +{ + [ToolboxBitmap(typeof(WizardControl))] + [DefaultProperty("Profile")] + [Designer(typeof(WizardControlDesigner))] + public class WizardControl : UserControl + { + // Define enumerations and structures + public enum Status + { + Default, + Yes, + No + } + + public enum Profiles + { + Install, + Configure, + Controller + } + + // Class wide constants + protected const int _panelGap = 10; + + protected const int _buttonGap = 10; + protected static Image _standardPicture; + + // Instance fields + protected Image _picture; + + protected string _title; + protected Font _fontTitle; + protected Font _fontSubTitle; + protected Color _colorTitle; + protected Color _colorSubTitle; + protected Profiles _profile; + protected bool _assignDefault; + protected WizardPage _selectedPage; + protected Status _showUpdate, _enableUpdate; + protected Status _showCancel, _enableCancel; + protected Status _showBack, _enableBack; + protected Status _showNext, _enableNext; + protected Status _showFinish, _enableFinish; + protected Status _showClose, _enableClose; + protected Status _showHelp, _enableHelp; + protected WizardPageCollection _wizardPages; + + // Instance designer fields + protected System.Windows.Forms.Panel _panelTop; + + protected System.Windows.Forms.Panel _panelBottom; + protected System.Windows.Forms.Button _buttonUpdate; + protected System.Windows.Forms.Button _buttonCancel; + protected System.Windows.Forms.Button _buttonBack; + protected System.Windows.Forms.Button _buttonNext; + protected System.Windows.Forms.Button _buttonFinish; + protected System.Windows.Forms.Button _buttonClose; + protected System.Windows.Forms.Button _buttonHelp; + protected Crownwood.Magic.Controls.TabControl _tabControl; + protected System.ComponentModel.Container components = null; + + // Delegate definitions + public delegate void WizardPageHandler(WizardPage wp, WizardControl wc); + + // Instance events + public event WizardPageHandler WizardPageEnter; + + public event WizardPageHandler WizardPageLeave; + + public event EventHandler WizardCaptionTitleChanged; + + public event EventHandler SelectionChanged; + + public event EventHandler UpdateClick; + + public event EventHandler CancelClick; + + public event EventHandler FinishClick; + + public event EventHandler CloseClick; + + public event EventHandler HelpClick; + + public event CancelEventHandler NextClick; + + public event CancelEventHandler BackClick; + + static WizardControl() + { + // Create a strip of images by loading an embedded bitmap resource + _standardPicture = ResourceHelper.LoadBitmap(Type.GetType("Crownwood.Magic.Controls.WizardControl"), + "Crownwood.Magic.Resources.WizardPicture.bmp"); + } + + public WizardControl() + { + InitializeComponent(); + + // No page currently selected + _selectedPage = null; + + // Hook into tab control events + _tabControl.SelectionChanged += new EventHandler(OnTabSelectionChanged); + + // Create our collection of wizard pages + _wizardPages = new WizardPageCollection(); + + // Hook into collection events + _wizardPages.Cleared += new Collections.CollectionClear(OnWizardCleared); + _wizardPages.Inserted += new Collections.CollectionChange(OnWizardInserted); + _wizardPages.Removed += new Collections.CollectionChange(OnWizardRemoved); + + // Hook into drawing events + _panelTop.Resize += new EventHandler(OnRepaintPanels); + _panelTop.Paint += new PaintEventHandler(OnPaintTopPanel); + _panelBottom.Resize += new EventHandler(OnRepaintPanels); + _panelBottom.Paint += new PaintEventHandler(OnPaintBottomPanel); + + // Initialize state + _showUpdate = _enableUpdate = Status.Default; + _showCancel = _enableUpdate = Status.Default; + _showBack = _enableBack = Status.Default; + _showNext = _enableNext = Status.Default; + _showFinish = _enableFinish = Status.Default; + _showClose = _enableClose = Status.Default; + _showHelp = _enableHelp = Status.Default; + + // Default properties + ResetProfile(); + ResetTitle(); + ResetTitleFont(); + ResetTitleColor(); + ResetSubTitleFont(); + ResetSubTitleColor(); + ResetPicture(); + ResetAssignDefaultButton(); + + // Position and enable/disable control button state + UpdateControlButtons(); + } + + protected override void Dispose(bool disposing) + { + if (disposing) + { + if (components != null) + { + components.Dispose(); + } + } + base.Dispose(disposing); + } + + #region Component Designer generated code + + /// + /// Required method for Designer support - do not modify + /// the contents of this method with the code editor. + /// + private void InitializeComponent() + { + this._tabControl = new Crownwood.Magic.Controls.TabControl(); + this._panelTop = new System.Windows.Forms.Panel(); + this._panelBottom = new System.Windows.Forms.Panel(); + this._buttonUpdate = new System.Windows.Forms.Button(); + this._buttonBack = new System.Windows.Forms.Button(); + this._buttonNext = new System.Windows.Forms.Button(); + this._buttonCancel = new System.Windows.Forms.Button(); + this._buttonFinish = new System.Windows.Forms.Button(); + this._buttonClose = new System.Windows.Forms.Button(); + this._buttonHelp = new System.Windows.Forms.Button(); + this._panelBottom.SuspendLayout(); + this.SuspendLayout(); + // + // _tabControl + // + this._tabControl.Anchor = (((System.Windows.Forms.AnchorStyles.Top | System.Windows.Forms.AnchorStyles.Bottom) + | System.Windows.Forms.AnchorStyles.Left) + | System.Windows.Forms.AnchorStyles.Right); + this._tabControl.Appearance = Crownwood.Magic.Controls.TabControl.VisualAppearance.MultiDocument; + this._tabControl.IDEPixelBorder = false; + this._tabControl.Location = new System.Drawing.Point(0, 80); + this._tabControl.Multiline = true; + this._tabControl.MultilineFullWidth = true; + this._tabControl.Name = "_tabControl"; + this._tabControl.ShowArrows = false; + this._tabControl.ShowClose = false; + this._tabControl.Size = new System.Drawing.Size(424, 264); + this._tabControl.TabIndex = 0; + // + // _panelTop + // + this._panelTop.BackColor = System.Drawing.SystemColors.Window; + this._panelTop.Dock = System.Windows.Forms.DockStyle.Top; + this._panelTop.Name = "_panelTop"; + this._panelTop.Size = new System.Drawing.Size(424, 80); + this._panelTop.TabIndex = 1; + // + // _panelBottom + // + this._panelBottom.Controls.AddRange(new System.Windows.Forms.Control[] { + this._buttonUpdate, + this._buttonBack, + this._buttonNext, + this._buttonCancel, + this._buttonFinish, + this._buttonClose, + this._buttonHelp}); + this._panelBottom.Dock = System.Windows.Forms.DockStyle.Bottom; + this._panelBottom.Location = new System.Drawing.Point(0, 344); + this._panelBottom.Name = "_panelBottom"; + this._panelBottom.Size = new System.Drawing.Size(424, 48); + this._panelBottom.TabIndex = 2; + // + // _buttonUpdate + // + this._buttonUpdate.Anchor = (System.Windows.Forms.AnchorStyles.Top | System.Windows.Forms.AnchorStyles.Right); + this._buttonUpdate.FlatStyle = FlatStyle.System; + this._buttonUpdate.Location = new System.Drawing.Point(8, 14); + this._buttonUpdate.Name = "_buttonUpdate"; + this._buttonUpdate.TabIndex = 4; + this._buttonUpdate.Text = "Update"; + this._buttonUpdate.Click += new System.EventHandler(this.OnButtonUpdate); + // + // _buttonBack + // + this._buttonBack.Anchor = (System.Windows.Forms.AnchorStyles.Top | System.Windows.Forms.AnchorStyles.Right); + this._buttonBack.FlatStyle = FlatStyle.System; + this._buttonBack.Location = new System.Drawing.Point(56, 14); + this._buttonBack.Name = "_buttonBack"; + this._buttonBack.TabIndex = 3; + this._buttonBack.Text = "< Back"; + this._buttonBack.Click += new System.EventHandler(this.OnButtonBack); + // + // _buttonNext + // + this._buttonNext.Anchor = (System.Windows.Forms.AnchorStyles.Top | System.Windows.Forms.AnchorStyles.Right); + this._buttonNext.FlatStyle = FlatStyle.System; + this._buttonNext.Location = new System.Drawing.Point(120, 14); + this._buttonNext.Name = "_buttonNext"; + this._buttonNext.TabIndex = 2; + this._buttonNext.Text = "Next >"; + this._buttonNext.Click += new System.EventHandler(this.OnButtonNext); + // + // _buttonCancel + // + this._buttonCancel.Anchor = (System.Windows.Forms.AnchorStyles.Top | System.Windows.Forms.AnchorStyles.Right); + this._buttonCancel.FlatStyle = FlatStyle.System; + this._buttonCancel.Location = new System.Drawing.Point(184, 14); + this._buttonCancel.Name = "_buttonCancel"; + this._buttonCancel.TabIndex = 1; + this._buttonCancel.Text = "Cancel"; + this._buttonCancel.Click += new System.EventHandler(this.OnButtonCancel); + // + // _buttonFinish + // + this._buttonFinish.Anchor = (System.Windows.Forms.AnchorStyles.Top | System.Windows.Forms.AnchorStyles.Right); + this._buttonFinish.FlatStyle = FlatStyle.System; + this._buttonFinish.Location = new System.Drawing.Point(248, 14); + this._buttonFinish.Name = "_buttonFinish"; + this._buttonFinish.TabIndex = 0; + this._buttonFinish.Text = "Finish"; + this._buttonFinish.Click += new System.EventHandler(this.OnButtonFinish); + // + // _buttonClose + // + this._buttonClose.Anchor = (System.Windows.Forms.AnchorStyles.Top | System.Windows.Forms.AnchorStyles.Right); + this._buttonClose.FlatStyle = FlatStyle.System; + this._buttonClose.Location = new System.Drawing.Point(304, 14); + this._buttonClose.Name = "_buttonClose"; + this._buttonClose.TabIndex = 0; + this._buttonClose.Text = "Close"; + this._buttonClose.Click += new System.EventHandler(this.OnButtonClose); + // + // _buttonHelp + // + this._buttonHelp.Anchor = (System.Windows.Forms.AnchorStyles.Top | System.Windows.Forms.AnchorStyles.Right); + this._buttonHelp.FlatStyle = FlatStyle.System; + this._buttonHelp.Location = new System.Drawing.Point(360, 14); + this._buttonHelp.Name = "_buttonHelp"; + this._buttonHelp.TabIndex = 0; + this._buttonHelp.Text = "Help"; + this._buttonHelp.Click += new System.EventHandler(this.OnButtonHelp); + // + // WizardControl + // + this.Controls.AddRange(new System.Windows.Forms.Control[] { + this._tabControl, + this._panelTop, + this._panelBottom}); + this.Name = "WizardControl"; + this.Size = new System.Drawing.Size(424, 392); + this._panelBottom.ResumeLayout(false); + this.ResumeLayout(false); + } + + #endregion Component Designer generated code + + [Category("Wizard")] + [Description("Access to underlying TabControl instance")] + public Controls.TabControl TabControl + { + get { return _tabControl; } + } + + [Category("Wizard")] + [Description("Access to underlying header panel")] + public Panel HeaderPanel + { + get { return _panelTop; } + } + + [Category("Wizard")] + [Description("Access to underlying trailer panel")] + public Panel TrailerPanel + { + get { return _panelBottom; } + } + + [Category("Wizard")] + [Description("Collection of wizard pages")] + [DesignerSerializationVisibility(DesignerSerializationVisibility.Content)] + public WizardPageCollection WizardPages + { + get { return _wizardPages; } + } + + [Category("Wizard")] + [Description("Determine default operation of buttons")] + [DefaultValue(typeof(Profiles), "Configure")] + public Profiles Profile + { + get { return _profile; } + + set + { + if (_profile != value) + { + _profile = value; + + switch (_profile) + { + case Profiles.Install: + case Profiles.Configure: + // Current page selection determines if full page is needed + if (_tabControl.SelectedIndex != -1) + { + // Get the selected wizard page + WizardPage wp = _wizardPages[_tabControl.SelectedIndex]; + + // Should we be presented in full page? + if (wp.FullPage) + EnterFullPage(); + else + { + // Controller profile is not allowed to be outside of FullMode + if (_profile != Profiles.Controller) + LeaveFullPage(); + } + } + else + LeaveFullPage(); + + _tabControl.HideTabsMode = Magic.Controls.TabControl.HideTabsModes.HideAlways; + break; + + case Profiles.Controller: + // Controller is always full page + EnterFullPage(); + + _tabControl.HideTabsMode = Magic.Controls.TabControl.HideTabsModes.ShowAlways; + break; + } + + // Position and enable/disable control button state + UpdateControlButtons(); + } + } + } + + public void ResetProfile() + { + Profile = Profiles.Configure; + } + + [Category("Wizard")] + [Description("Main title text")] + public Image Picture + { + get { return _picture; } + + set + { + _picture = value; + _panelTop.Invalidate(); + } + } + + protected bool ShouldSerializePicture() + { + return !_picture.Equals(_standardPicture); + } + + public void ResetPicture() + { + Picture = _standardPicture; + } + + [Category("Wizard")] + [Description("Main title text")] + [Localizable(true)] + public string Title + { + get { return _title; } + + set + { + _title = value; + _panelTop.Invalidate(); + } + } + + public void ResetTitle() + { + Title = "Welcome to the Wizard Control"; + } + + protected bool ShouldSerializeTitle() + { + return !_title.Equals("Welcome to the Wizard Control"); + } + + [Category("Wizard")] + [Description("Font for drawing main title text")] + public Font TitleFont + { + get { return _fontTitle; } + + set + { + _fontTitle = value; + _panelTop.Invalidate(); + } + } + + public void ResetTitleFont() + { + TitleFont = new Font("Tahoma", 10, FontStyle.Bold); + } + + protected bool ShouldSerializeTitleFont() + { + return !_fontTitle.Equals(new Font("Tahoma", 10, FontStyle.Bold)); + } + + [Category("Wizard")] + [Description("Font for drawing main sub-title text")] + public Font SubTitleFont + { + get { return _fontSubTitle; } + + set + { + _fontSubTitle = value; + _panelTop.Invalidate(); + } + } + + public void ResetSubTitleFont() + { + _fontSubTitle = new Font("Tahoma", 8, FontStyle.Regular); + } + + protected bool ShouldSerializeSubTitleFont() + { + return !_fontSubTitle.Equals(new Font("Tahoma", 8, FontStyle.Regular)); + } + + [Category("Wizard")] + [Description("Color for drawing main title text")] + public Color TitleColor + { + get { return _colorTitle; } + + set + { + _colorTitle = value; + _panelTop.Invalidate(); + } + } + + public void ResetTitleColor() + { + TitleColor = base.ForeColor; + } + + protected bool ShouldSerializeTitleColor() + { + return !_colorTitle.Equals(base.ForeColor); + } + + [Category("Wizard")] + [Description("Determine is a default button should be auto-assigned")] + [DefaultValue(false)] + public bool AssignDefaultButton + { + get { return _assignDefault; } + + set + { + if (_assignDefault != value) + { + _assignDefault = value; + AutoAssignDefaultButton(); + } + } + } + + public void ResetAssignDefaultButton() + { + AssignDefaultButton = false; + } + + [Category("Wizard")] + [Description("Color for drawing main sub-title text")] + public Color SubTitleColor + { + get { return _colorSubTitle; } + + set + { + _colorSubTitle = value; + _panelTop.Invalidate(); + } + } + + public void ResetSubTitleColor() + { + SubTitleColor = base.ForeColor; + } + + protected bool ShouldSerializeSubTitleColor() + { + return !_colorSubTitle.Equals(base.ForeColor); + } + + [Category("Control Buttons")] + [Description("Modify default button properties")] + [Browsable(false)] + public Button UpdateButton + { + get { return _buttonUpdate; } + } + + [Category("Control Buttons")] + [Description("Define visibility of Update button")] + [DefaultValue(typeof(Status), "Default")] + public Status ShowUpdateButton + { + get { return _showUpdate; } + + set + { + if (_showUpdate != value) + { + _showUpdate = value; + UpdateControlButtons(); + } + } + } + + [Category("Control Buttons")] + [Description("Define selectability of Update button")] + [DefaultValue(typeof(Status), "Default")] + public Status EnableUpdateButton + { + get { return _enableUpdate; } + + set + { + if (_enableUpdate != value) + { + _enableUpdate = value; + UpdateControlButtons(); + } + } + } + + [Category("Control Buttons")] + [Description("Modify the text for the Update control button")] + [DefaultValue("Update")] + [Localizable(true)] + public string ButtonUpdateText + { + get { return _buttonUpdate.Text; } + set { _buttonUpdate.Text = value; } + } + + [Category("Control Buttons")] + [Description("Modify default button properties")] + [Browsable(false)] + public Button CancelButton + { + get { return _buttonCancel; } + } + + [Category("Control Buttons")] + [Description("Define visibility of Cancel button")] + [DefaultValue(typeof(Status), "Default")] + public Status ShowCancelButton + { + get { return _showCancel; } + + set + { + if (_showCancel != value) + { + _showCancel = value; + UpdateControlButtons(); + } + } + } + + [Category("Control Buttons")] + [Description("Define selectability of Cancel button")] + [DefaultValue(typeof(Status), "Default")] + public Status EnableCancelButton + { + get { return _enableCancel; } + + set + { + if (_enableCancel != value) + { + _enableCancel = value; + UpdateControlButtons(); + } + } + } + + [Category("Control Buttons")] + [Description("Modify the text for the Cancel control button")] + [DefaultValue("Cancel")] + [Localizable(true)] + public string ButtonCancelText + { + get { return _buttonCancel.Text; } + set { _buttonCancel.Text = value; } + } + + [Category("Control Buttons")] + [Description("Modify default button properties")] + [Browsable(false)] + public Button BackButton + { + get { return _buttonBack; } + } + + [Category("Control Buttons")] + [Description("Define visibility of Back button")] + [DefaultValue(typeof(Status), "Default")] + public Status ShowBackButton + { + get { return _showBack; } + + set + { + if (_showBack != value) + { + _showBack = value; + UpdateControlButtons(); + } + } + } + + [Category("Control Buttons")] + [Description("Define selectability of Back button")] + [DefaultValue(typeof(Status), "Default")] + public Status EnableBackButton + { + get { return _enableBack; } + + set + { + if (_enableBack != value) + { + _enableBack = value; + UpdateControlButtons(); + } + } + } + + [Category("Control Buttons")] + [Description("Modify the text for the Back control button")] + [DefaultValue("< Back")] + [Localizable(true)] + public string ButtonBackText + { + get { return _buttonBack.Text; } + set { _buttonBack.Text = value; } + } + + [Category("Control Buttons")] + [Description("Modify default button properties")] + [Browsable(false)] + public Button NextButton + { + get { return _buttonNext; } + } + + [Category("Control Buttons")] + [Description("Define visibility of Next button")] + [DefaultValue(typeof(Status), "Default")] + public Status ShowNextButton + { + get { return _showNext; } + + set + { + if (_showNext != value) + { + _showNext = value; + UpdateControlButtons(); + } + } + } + + [Category("Control Buttons")] + [Description("Define selectability of Next button")] + [DefaultValue(typeof(Status), "Default")] + public Status EnableNextButton + { + get { return _enableBack; } + + set + { + if (_enableNext != value) + { + _enableNext = value; + UpdateControlButtons(); + } + } + } + + [Category("Control Buttons")] + [Description("Modify the text for the Next control button")] + [DefaultValue("Next >")] + [Localizable(true)] + public string ButtonNextText + { + get { return _buttonNext.Text; } + set { _buttonNext.Text = value; } + } + + [Category("Control Buttons")] + [Description("Modify default button properties")] + [Browsable(false)] + public Button FinishButton + { + get { return _buttonFinish; } + } + + [Category("Control Buttons")] + [Description("Define visibility of Finish button")] + [DefaultValue(typeof(Status), "Default")] + public Status ShowFinishButton + { + get { return _showFinish; } + + set + { + if (_showFinish != value) + { + _showFinish = value; + UpdateControlButtons(); + } + } + } + + [Category("Control Buttons")] + [Description("Define selectability of Finish button")] + [DefaultValue(typeof(Status), "Default")] + public Status EnableFinishButton + { + get { return _enableFinish; } + + set + { + if (_enableFinish != value) + { + _enableFinish = value; + UpdateControlButtons(); + } + } + } + + [Category("Control Buttons")] + [Description("Modify the text for the Finish control button")] + [DefaultValue("Finish")] + [Localizable(true)] + public string ButtonFinishText + { + get { return _buttonFinish.Text; } + set { _buttonFinish.Text = value; } + } + + [Category("Control Buttons")] + [Description("Modify default button properties")] + [Browsable(false)] + public Button CloseButton + { + get { return _buttonClose; } + } + + [Category("Control Buttons")] + [Description("Define visibility of Close button")] + [DefaultValue(typeof(Status), "Default")] + public Status ShowCloseButton + { + get { return _showClose; } + + set + { + if (_showClose != value) + { + _showClose = value; + UpdateControlButtons(); + } + } + } + + [Category("Control Buttons")] + [Description("Define selectability of Close button")] + [DefaultValue(typeof(Status), "Default")] + public Status EnableCloseButton + { + get { return _enableClose; } + + set + { + if (_enableClose != value) + { + _enableClose = value; + UpdateControlButtons(); + } + } + } + + [Category("Control Buttons")] + [Description("Modify the text for the Close control button")] + [DefaultValue("Close")] + [Localizable(true)] + public string ButtonCloseText + { + get { return _buttonClose.Text; } + set { _buttonClose.Text = value; } + } + + [Category("Control Buttons")] + [Description("Modify default button properties")] + [Browsable(false)] + public Button HelpButton + { + get { return _buttonHelp; } + } + + [Category("Control Buttons")] + [Description("Define visibility of Help button")] + [DefaultValue(typeof(Status), "Default")] + public Status ShowHelpButton + { + get { return _showHelp; } + + set + { + if (_showHelp != value) + { + _showHelp = value; + UpdateControlButtons(); + } + } + } + + [Category("Control Buttons")] + [Description("Define selectability of Help button")] + [DefaultValue(typeof(Status), "Default")] + public Status EnableHelpButton + { + get { return _enableHelp; } + + set + { + if (_enableHelp != value) + { + _enableHelp = value; + UpdateControlButtons(); + } + } + } + + [Category("Control Buttons")] + [Description("Modify the text for the Help control button")] + [DefaultValue("Help")] + [Localizable(true)] + public string ButtonHelpText + { + get { return _buttonHelp.Text; } + set { _buttonHelp.Text = value; } + } + + [Category("Wizard")] + [Description("Index of currently selected WizardPage")] + public int SelectedIndex + { + get { return _tabControl.SelectedIndex; } + set { _tabControl.SelectedIndex = value; } + } + + public virtual void OnWizardPageEnter(WizardPage wp) + { + if (WizardPageEnter != null) + WizardPageEnter(wp, this); + } + + public virtual void OnWizardPageLeave(WizardPage wp) + { + if (WizardPageLeave != null) + WizardPageLeave(wp, this); + } + + public virtual void OnSelectionChanged(EventArgs e) + { + if (SelectionChanged != null) + SelectionChanged(this, e); + } + + public virtual void OnCloseClick(EventArgs e) + { + if (CloseClick != null) + CloseClick(this, e); + } + + public virtual void OnFinishClick(EventArgs e) + { + if (FinishClick != null) + FinishClick(this, e); + } + + public virtual void OnNextClick(CancelEventArgs e) + { + if (NextClick != null) + NextClick(this, e); + } + + public virtual void OnBackClick(CancelEventArgs e) + { + if (BackClick != null) + BackClick(this, e); + } + + public virtual void OnCancelClick(EventArgs e) + { + if (CancelClick != null) + CancelClick(this, e); + } + + public virtual void OnUpdateClick(EventArgs e) + { + if (UpdateClick != null) + UpdateClick(this, e); + } + + public virtual void OnHelpClick(EventArgs e) + { + if (HelpClick != null) + HelpClick(this, e); + } + + protected void UpdateControlButtons() + { + // Track next button inserted position + int x = this.Width - _buttonGap - _buttonFinish.Width; + + bool showHelp = ShouldShowHelp(); + bool showClose = ShouldShowClose(); + bool showFinish = ShouldShowFinish(); + bool showNext = ShouldShowNext(); + bool showBack = ShouldShowBack(); + bool showCancel = ShouldShowCancel(); + bool showUpdate = ShouldShowUpdate(); + + if (showHelp) + { + _buttonHelp.Left = x; + x -= _buttonHelp.Width + _buttonGap; + _buttonHelp.Enabled = ShouldEnableHelp(); + _buttonHelp.Show(); + } + else + _buttonHelp.Hide(); + + if (showClose) + { + _buttonClose.Left = x; + x -= _buttonClose.Width + _buttonGap; + _buttonClose.Enabled = ShouldEnableClose(); + _buttonClose.Show(); + } + else + _buttonClose.Hide(); + + if (showFinish) + { + _buttonFinish.Left = x; + x -= _buttonFinish.Width + _buttonGap; + _buttonFinish.Enabled = ShouldEnableFinish(); + _buttonFinish.Show(); + } + else + _buttonFinish.Hide(); + + if (showNext) + { + _buttonNext.Left = x; + x -= _buttonNext.Width + _buttonGap; + _buttonNext.Enabled = ShouldEnableNext(); + _buttonNext.Show(); + } + else + _buttonNext.Hide(); + + if (showBack) + { + _buttonBack.Left = x; + x -= _buttonBack.Width + _buttonGap; + _buttonBack.Enabled = ShouldEnableBack(); + _buttonBack.Show(); + } + else + _buttonBack.Hide(); + + if (showCancel) + { + _buttonCancel.Left = x; + x -= _buttonCancel.Width + _buttonGap; + _buttonCancel.Enabled = ShouldEnableCancel(); + _buttonCancel.Show(); + } + else + _buttonCancel.Hide(); + + if (showUpdate) + { + _buttonUpdate.Left = x; + x -= _buttonUpdate.Width + _buttonGap; + _buttonUpdate.Enabled = ShouldEnableUpdate(); + _buttonUpdate.Show(); + } + else + _buttonUpdate.Hide(); + + AutoAssignDefaultButton(); + } + + protected void AutoAssignDefaultButton() + { + // Get our parent Form instance + Form parentForm = this.FindForm(); + + // Cannot assign a default button if we are not on a Form + if (parentForm != null) + { + // Can only assign a particular button if we have been requested + // to auto- assign and we are on a selected page + if (_assignDefault && (_tabControl.SelectedIndex >= 0)) + { + // Button default depends on the profile mode + switch (_profile) + { + case Profiles.Install: + // Is this the last page? + if (_tabControl.SelectedIndex == (_tabControl.TabPages.Count - 1)) + { + // Then use the Close button + parentForm.AcceptButton = _buttonClose; + } + else + { + // Is this the second from last page? + if (_tabControl.SelectedIndex == (_tabControl.TabPages.Count - 2)) + { + // Then use the Cancel button + parentForm.AcceptButton = _buttonCancel; + } + else + { + // Then use the Next button + parentForm.AcceptButton = _buttonNext; + } + } + break; + + case Profiles.Configure: + // Is this the last page? + if (_tabControl.SelectedIndex == (_tabControl.TabPages.Count - 1)) + { + // Then always use the Finish button + parentForm.AcceptButton = _buttonFinish; + } + else + { + // Else we are not on last page, use the Next button + parentForm.AcceptButton = _buttonNext; + } + break; + + case Profiles.Controller: + // Always use the Update button + parentForm.AcceptButton = _buttonUpdate; + break; + } + } + else + { + // Remove any assigned default button + parentForm.AcceptButton = null; + } + } + } + + protected bool ShouldShowClose() + { + bool ret = false; + + switch (_showClose) + { + case Status.No: + break; + + case Status.Yes: + ret = true; + break; + + case Status.Default: + switch (_profile) + { + case Profiles.Install: + // Must have at least one page + if (_tabControl.SelectedIndex != -1) + { + // Cannot 'Close' unless on the last page + if (_tabControl.SelectedIndex == (_tabControl.TabPages.Count - 1)) + ret = true; + } + break; + + case Profiles.Configure: + break; + + case Profiles.Controller: + break; + } + break; + } + + return ret; + } + + protected bool ShouldEnableClose() + { + bool ret = false; + + switch (_enableClose) + { + case Status.No: + break; + + case Status.Yes: + ret = true; + break; + + case Status.Default: + ret = true; + break; + } + + return ret; + } + + protected bool ShouldShowFinish() + { + bool ret = false; + + switch (_showFinish) + { + case Status.No: + break; + + case Status.Yes: + ret = true; + break; + + case Status.Default: + switch (_profile) + { + case Profiles.Install: + break; + + case Profiles.Configure: + ret = true; + break; + + case Profiles.Controller: + break; + } + break; + } + + return ret; + } + + protected bool ShouldEnableFinish() + { + bool ret = false; + + switch (_enableFinish) + { + case Status.No: + break; + + case Status.Yes: + ret = true; + break; + + case Status.Default: + ret = true; + break; + } + + return ret; + } + + protected bool ShouldShowNext() + { + bool ret = false; + + switch (_showNext) + { + case Status.No: + break; + + case Status.Yes: + ret = true; + break; + + case Status.Default: + switch (_profile) + { + case Profiles.Install: + // Must have at least one page + if (_tabControl.SelectedIndex != -1) + { + // Cannot 'Next' when at the last or second to last pages + if (_tabControl.SelectedIndex < (_tabControl.TabPages.Count - 2)) + ret = true; + } + break; + + case Profiles.Configure: + ret = true; + break; + + case Profiles.Controller: + break; + } + break; + } + + return ret; + } + + protected bool ShouldEnableNext() + { + bool ret = false; + + switch (_enableNext) + { + case Status.No: + break; + + case Status.Yes: + ret = true; + break; + + case Status.Default: + switch (_profile) + { + case Profiles.Install: + // Must have at least one page + if (_tabControl.SelectedIndex != -1) + { + // Cannot 'Next' when at the last or second to last pages + if (_tabControl.SelectedIndex < (_tabControl.TabPages.Count - 2)) + ret = true; + } + break; + + case Profiles.Configure: + case Profiles.Controller: + // Must have at least one page + if (_tabControl.SelectedIndex != -1) + { + // Cannot 'Next' when at the last or second to last pages + if (_tabControl.SelectedIndex < (_tabControl.TabPages.Count - 1)) + ret = true; + } + break; + } + break; + } + + return ret; + } + + protected bool ShouldShowBack() + { + bool ret = false; + + switch (_showBack) + { + case Status.No: + break; + + case Status.Yes: + ret = true; + break; + + case Status.Default: + switch (_profile) + { + case Profiles.Install: + // Cannot 'Back' when one the first page or on the last two special pages + if ((_tabControl.SelectedIndex > 0) && (_tabControl.SelectedIndex < (_tabControl.TabPages.Count - 2))) + ret = true; + break; + + case Profiles.Configure: + ret = true; + break; + + case Profiles.Controller: + break; + } + break; + } + + return ret; + } + + protected bool ShouldEnableBack() + { + bool ret = false; + + switch (_enableBack) + { + case Status.No: + break; + + case Status.Yes: + ret = true; + break; + + case Status.Default: + // Cannot 'Back' when one the first page + if (_tabControl.SelectedIndex > 0) + ret = true; + break; + } + + return ret; + } + + protected bool ShouldShowCancel() + { + bool ret = false; + + switch (_showCancel) + { + case Status.No: + break; + + case Status.Yes: + ret = true; + break; + + case Status.Default: + switch (_profile) + { + case Profiles.Install: + // Must have at least one page + if (_tabControl.SelectedIndex != -1) + { + // Cannot 'Cancel' on the last page of an Install + if (_tabControl.SelectedIndex < (_tabControl.TabPages.Count - 1)) + ret = true; + } + break; + + case Profiles.Configure: + ret = true; + break; + + case Profiles.Controller: + ret = true; + break; + } + break; + } + + return ret; + } + + protected bool ShouldEnableCancel() + { + bool ret = false; + + switch (_enableCancel) + { + case Status.No: + break; + + case Status.Yes: + ret = true; + break; + + case Status.Default: + ret = true; + break; + } + + return ret; + } + + protected bool ShouldShowUpdate() + { + bool ret = false; + + switch (_showUpdate) + { + case Status.No: + break; + + case Status.Yes: + ret = true; + break; + + case Status.Default: + switch (_profile) + { + case Profiles.Install: + break; + + case Profiles.Configure: + break; + + case Profiles.Controller: + ret = true; + break; + } + break; + } + + return ret; + } + + protected bool ShouldEnableUpdate() + { + bool ret = false; + + switch (_enableUpdate) + { + case Status.No: + break; + + case Status.Yes: + ret = true; + break; + + case Status.Default: + ret = true; + break; + } + + return ret; + } + + protected bool ShouldEnableHelp() + { + bool ret = false; + + switch (_enableCancel) + { + case Status.No: + break; + + case Status.Yes: + ret = true; + break; + + case Status.Default: + ret = true; + break; + } + + return ret; + } + + protected bool ShouldShowHelp() + { + bool ret = false; + + switch (_showUpdate) + { + case Status.No: + break; + + case Status.Yes: + ret = true; + break; + + case Status.Default: + break; + } + + return ret; + } + + protected void LeaveFullPage() + { + _panelTop.Show(); + _tabControl.Top = _panelTop.Height; + _tabControl.Height = _panelBottom.Top - _panelTop.Height - 1; + } + + protected void EnterFullPage() + { + _panelTop.Hide(); + _tabControl.Top = 0; + _tabControl.Height = _panelBottom.Top - 1; + } + + protected void OnTabSelectionChanged(object sender, EventArgs e) + { + // Update buttons to reflect change + UpdateControlButtons(); + + if (_tabControl.SelectedIndex != -1) + { + // Get the selected wizard page + WizardPage wp = _wizardPages[_tabControl.SelectedIndex]; + + // Should we be presented in full page? + if (wp.FullPage) + EnterFullPage(); + else + { + // Controller profile is not allowed to be outside of FullMode + if (_profile != Profiles.Controller) + LeaveFullPage(); + } + } + else + { + // Controller profile is not allowed to be outside of FullMode + if (_profile != Profiles.Controller) + LeaveFullPage(); + } + + // Update manual drawn text + _panelTop.Invalidate(); + + // Generate raw selection changed event + OnSelectionChanged(EventArgs.Empty); + + // Generate page leave event if currently on a valid page + if (_selectedPage != null) + { + OnWizardPageLeave(_selectedPage); + _selectedPage = null; + } + + // Remember which is the newly seleced page + if (_tabControl.SelectedIndex != -1) + _selectedPage = _wizardPages[_tabControl.SelectedIndex] as WizardPage; + + // Generate page enter event is now on a valid page + if (_selectedPage != null) + OnWizardPageEnter(_selectedPage); + } + + protected void OnButtonHelp(object sender, EventArgs e) + { + // Fire event for interested handlers + OnHelpClick(EventArgs.Empty); + } + + protected void OnButtonClose(object sender, EventArgs e) + { + // Fire event for interested handlers + OnCloseClick(EventArgs.Empty); + } + + protected void OnButtonFinish(object sender, EventArgs e) + { + // Fire event for interested handlers + OnFinishClick(EventArgs.Empty); + } + + protected void OnButtonNext(object sender, EventArgs e) + { + CancelEventArgs ce = new CancelEventArgs(false); + + // Give handlers chance to cancel this action + OnNextClick(ce); + + if (!ce.Cancel) + { + // Move to the next page if there is one + if (_tabControl.SelectedIndex < _tabControl.TabPages.Count - 1) + _tabControl.SelectedIndex++; + } + } + + protected void OnButtonBack(object sender, EventArgs e) + { + CancelEventArgs ce = new CancelEventArgs(false); + + // Give handlers chance to cancel this action + OnBackClick(ce); + + if (!ce.Cancel) + { + // Move to the next page if there is one + if (_tabControl.SelectedIndex > 0) + _tabControl.SelectedIndex--; + } + } + + protected void OnButtonCancel(object sender, EventArgs e) + { + // Fire event for interested handlers + OnCancelClick(EventArgs.Empty); + } + + protected void OnButtonUpdate(object sender, EventArgs e) + { + // Fire event for interested handlers + OnUpdateClick(EventArgs.Empty); + } + + protected void OnWizardCleared() + { + // Unhook from event handlers for each page + foreach (WizardPage wp in _tabControl.TabPages) + { + wp.FullPageChanged -= new EventHandler(OnWizardFullPageChanged); + wp.SubTitleChanged -= new EventHandler(OnWizardSubTitleChanged); + wp.CaptionTitleChanged -= new EventHandler(OnWizardCaptionTitleChanged); + } + + // Reflect change on underlying tab control + _tabControl.TabPages.Clear(); + + // Update buttons to reflect status + UpdateControlButtons(); + } + + protected void OnWizardInserted(int index, object value) + { + WizardPage wp = value as WizardPage; + + // Monitor property changes + wp.FullPageChanged += new EventHandler(OnWizardFullPageChanged); + wp.SubTitleChanged += new EventHandler(OnWizardSubTitleChanged); + wp.CaptionTitleChanged += new EventHandler(OnWizardCaptionTitleChanged); + + // Reflect change on underlying tab control + _tabControl.TabPages.Insert(index, wp); + + // Update buttons to reflect status + UpdateControlButtons(); + } + + protected void OnWizardRemoved(int index, object value) + { + WizardPage wp = _tabControl.TabPages[index] as WizardPage; + + // Unhook from event handlers + wp.FullPageChanged -= new EventHandler(OnWizardFullPageChanged); + wp.SubTitleChanged -= new EventHandler(OnWizardSubTitleChanged); + wp.CaptionTitleChanged -= new EventHandler(OnWizardCaptionTitleChanged); + + // Reflect change on underlying tab control + _tabControl.TabPages.RemoveAt(index); + + // Update buttons to reflect status + UpdateControlButtons(); + } + + protected void OnWizardFullPageChanged(object sender, EventArgs e) + { + WizardPage wp = sender as WizardPage; + + // Is it the current page that has changed FullPage? + if (_tabControl.SelectedIndex == _wizardPages.IndexOf(wp)) + { + // Should we be presented in full page? + if (wp.FullPage) + EnterFullPage(); + else + { + // Controller profile is not allowed to be outside of FullMode + if (_profile != Profiles.Controller) + LeaveFullPage(); + } + } + } + + protected void OnWizardSubTitleChanged(object sender, EventArgs e) + { + WizardPage wp = sender as WizardPage; + + // Is it the current page that has changed sub title? + if (_tabControl.SelectedIndex == _wizardPages.IndexOf(wp)) + { + // Force the sub title to be updated now + _panelTop.Invalidate(); + } + } + + protected void OnWizardCaptionTitleChanged(object sender, EventArgs e) + { + // Generate event so any dialog containing use can be notify + if (WizardCaptionTitleChanged != null) + WizardCaptionTitleChanged(this, e); + } + + protected override void OnResize(EventArgs e) + { + this.PerformLayout(); + } + + protected void OnRepaintPanels(object sender, EventArgs e) + { + _panelTop.Invalidate(); + _panelBottom.Invalidate(); + } + + protected void OnPaintTopPanel(object sender, PaintEventArgs pe) + { + int right = _panelTop.Width; + + // Any picture to draw? + if (_picture != null) + { + // Calculate starting Y position to give equal space above and below image + int Y = (int)((_panelTop.Height - _picture.Height) / 2); + + pe.Graphics.DrawImage(_picture, _panelTop.Width - _picture.Width - Y, Y, _picture.Width, _picture.Height); + + // Adjust right side by width of width and gaps around it + right -= _picture.Width + Y + _panelGap; + } + + // Create main title drawing rectangle + RectangleF drawRectF = new Rectangle(_panelGap, _panelGap, right - _panelGap, _fontTitle.Height); + + StringFormat drawFormat = new StringFormat(); + drawFormat.Alignment = StringAlignment.Near; + drawFormat.LineAlignment = StringAlignment.Center; + drawFormat.Trimming = StringTrimming.EllipsisCharacter; + drawFormat.FormatFlags = StringFormatFlags.NoClip | + StringFormatFlags.NoWrap; + + using (SolidBrush mainTitleBrush = new SolidBrush(_colorTitle)) + pe.Graphics.DrawString(_title, _fontTitle, mainTitleBrush, drawRectF, drawFormat); + + // Is there a selected tab for display? + if (_tabControl.SelectedIndex != -1) + { + // Adjust rectangle for rest of the drawing text space + drawRectF.Y = drawRectF.Bottom + (_panelGap / 2); + drawRectF.X += _panelGap; + drawRectF.Width -= _panelGap; + drawRectF.Height = _panelTop.Height - drawRectF.Y - (_panelGap / 2); + + // No longer want to prevent word wrap to extra lines + drawFormat.LineAlignment = StringAlignment.Near; + drawFormat.FormatFlags = StringFormatFlags.NoClip; + + WizardPage wp = _tabControl.TabPages[_tabControl.SelectedIndex] as WizardPage; + + using (SolidBrush subTitleBrush = new SolidBrush(_colorSubTitle)) + pe.Graphics.DrawString(wp.SubTitle, _fontSubTitle, subTitleBrush, drawRectF, drawFormat); + } + + using (Pen lightPen = new Pen(_panelTop.BackColor), + darkPen = new Pen(ControlPaint.Light(ControlPaint.Dark(this.BackColor)))) + { + pe.Graphics.DrawLine(darkPen, 0, _panelTop.Height - 2, _panelTop.Width, _panelTop.Height - 2); + pe.Graphics.DrawLine(lightPen, 0, _panelTop.Height - 1, _panelTop.Width, _panelTop.Height - 1); + } + } + + protected void OnPaintBottomPanel(object sender, PaintEventArgs pe) + { + using (Pen lightPen = new Pen(ControlPaint.Light(this.BackColor)), + darkPen = new Pen(ControlPaint.Light(ControlPaint.Dark(this.BackColor)))) + { + pe.Graphics.DrawLine(darkPen, 0, 0, _panelBottom.Width, 0); + pe.Graphics.DrawLine(lightPen, 0, 1, _panelBottom.Width, 1); + } + } + } +} \ No newline at end of file diff --git a/Labyrinth3/Crownwood.Magic/Controls/WizardControl/WizardControl.resx b/Labyrinth3/Crownwood.Magic/Controls/WizardControl/WizardControl.resx new file mode 100644 index 0000000..13b2902 --- /dev/null +++ b/Labyrinth3/Crownwood.Magic/Controls/WizardControl/WizardControl.resx @@ -0,0 +1,135 @@ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + text/microsoft-resx + + + 1.3 + + + System.Resources.ResXResourceReader, System.Windows.Forms, Version=1.0.3300.0, Culture=neutral, PublicKeyToken=b77a5c561934e089 + + + System.Resources.ResXResourceWriter, System.Windows.Forms, Version=1.0.3300.0, Culture=neutral, PublicKeyToken=b77a5c561934e089 + + + True + + + Family + + + Family + + + Family + + + Family + + + Family + + + Family + + + Family + + + Family + + + Family + + + Family + + + WizardControl + + \ No newline at end of file diff --git a/Labyrinth3/Crownwood.Magic/Controls/WizardControl/WizardControlDesigner.cs b/Labyrinth3/Crownwood.Magic/Controls/WizardControl/WizardControlDesigner.cs new file mode 100644 index 0000000..5684982 --- /dev/null +++ b/Labyrinth3/Crownwood.Magic/Controls/WizardControl/WizardControlDesigner.cs @@ -0,0 +1,117 @@ +// ***************************************************************************** +// +// (c) Crownwood Consulting Limited 2002-2003 +// All rights reserved. The software and associated documentation +// supplied hereunder are the proprietary information of Crownwood Consulting +// Limited, Crownwood, Bracknell, Berkshire, England and are supplied subject +// to licence terms. +// +// Magic Version 1.7.4.0 www.dotnetmagic.com +// ***************************************************************************** + +using System.Collections; +using System.ComponentModel.Design; +using System.Drawing; +using System.Windows.Forms; + +//using Crownwood.Magic.Win32; + +namespace Crownwood.Magic.Controls +{ + public class WizardControlDesigner : System.Windows.Forms.Design.ParentControlDesigner + { + private ISelectionService _selectionService = null; + + public override ICollection AssociatedComponents + { + get + { + if (base.Control is Crownwood.Magic.Controls.WizardControl) + return ((Crownwood.Magic.Controls.WizardControl)base.Control).WizardPages; + else + return base.AssociatedComponents; + } + } + + protected override bool DrawGrid + { + get { return false; } + } + + public ISelectionService SelectionService + { + get + { + // Is this the first time the accessor has been called? + if (_selectionService == null) + { + // Then grab and cache the required interface + _selectionService = (ISelectionService)GetService(typeof(ISelectionService)); + } + + return _selectionService; + } + } + + protected override void WndProc(ref Message msg) + { + // Test for the left mouse down windows message + if (msg.Msg == (int)Win32.Msgs.WM_LBUTTONDOWN) + { + Crownwood.Magic.Controls.WizardControl wizardControl = this.SelectionService.PrimarySelection as Crownwood.Magic.Controls.WizardControl; + + // Check we have a valid object reference + if (wizardControl != null) + { + Crownwood.Magic.Controls.TabControl tabControl = wizardControl.TabControl; + + // Check we have a valid object reference + if (tabControl != null) + { + // Extract the mouse position + int xPos = (short)((uint)msg.LParam & 0x0000FFFFU); + int yPos = (short)(((uint)msg.LParam & 0xFFFF0000U) >> 16); + + Point screenCoord = wizardControl.PointToScreen(new Point(xPos, yPos)); + Point clientCoord = tabControl.PointToClient(screenCoord); + + // Ask the TabControl to change tabs according to mouse message + tabControl.ExternalMouseTest(msg.HWnd, clientCoord); + } + } + } + else + { + if (msg.Msg == (int)Win32.Msgs.WM_LBUTTONDBLCLK) + { + Crownwood.Magic.Controls.WizardControl wizardControl = this.SelectionService.PrimarySelection as Crownwood.Magic.Controls.WizardControl; + + // Check we have a valid object reference + if (wizardControl != null) + { + Crownwood.Magic.Controls.TabControl tabControl = wizardControl.TabControl; + + // Check we have a valid object reference + if (tabControl != null) + { + // Extract the mouse position + int xPos = (short)((uint)msg.LParam & 0x0000FFFFU); + int yPos = (short)(((uint)msg.LParam & 0xFFFF0000U) >> 16); + + Point screenCoord = wizardControl.PointToScreen(new Point(xPos, yPos)); + Point clientCoord = tabControl.PointToClient(screenCoord); + + // Ask the TabControl to process a double click over an arrow as a simple + // click of the arrow button. In which case we return immediately to prevent + // the base class from using the double to generate the default event + if (tabControl.WantDoubleClick(msg.HWnd, clientCoord)) + return; + } + } + } + } + + base.WndProc(ref msg); + } + } +} \ No newline at end of file diff --git a/Labyrinth3/Crownwood.Magic/Controls/WizardControl/WizardPage.cs b/Labyrinth3/Crownwood.Magic/Controls/WizardControl/WizardPage.cs new file mode 100644 index 0000000..6676bdb --- /dev/null +++ b/Labyrinth3/Crownwood.Magic/Controls/WizardControl/WizardPage.cs @@ -0,0 +1,103 @@ +// ***************************************************************************** +// +// (c) Crownwood Consulting Limited 2002-2003 +// All rights reserved. The software and associated documentation +// supplied hereunder are the proprietary information of Crownwood Consulting +// Limited, Crownwood, Bracknell, Berkshire, England and are supplied subject +// to licence terms. +// +// Magic Version 1.7.4.0 www.dotnetmagic.com +// ***************************************************************************** + +using System; +using System.ComponentModel; +using System.Windows.Forms.Design; + +namespace Crownwood.Magic.Controls +{ + [Designer(typeof(ParentControlDesigner))] + public class WizardPage : Crownwood.Magic.Controls.TabPage + { + // Instance fields + protected bool _fullPage; + + protected string _subTitle; + protected string _captionTitle; + + // Instance events + public event EventHandler FullPageChanged; + + public event EventHandler SubTitleChanged; + + public event EventHandler CaptionTitleChanged; + + public WizardPage() + { + _fullPage = false; + _subTitle = "(Page Description not defined)"; + _captionTitle = "(Page Title)"; + } + + public bool FullPage + { + get { return _fullPage; } + + set + { + if (_fullPage != value) + { + _fullPage = value; + OnFullPageChanged(EventArgs.Empty); + } + } + } + + [Localizable(true)] + public string SubTitle + { + get { return _subTitle; } + + set + { + if (_subTitle != value) + { + _subTitle = value; + OnSubTitleChanged(EventArgs.Empty); + } + } + } + + [Localizable(true)] + public string CaptionTitle + { + get { return _captionTitle; } + + set + { + if (_captionTitle != value) + { + _captionTitle = value; + OnCaptionTitleChanged(EventArgs.Empty); + } + } + } + + public virtual void OnFullPageChanged(EventArgs e) + { + if (FullPageChanged != null) + FullPageChanged(this, e); + } + + public virtual void OnSubTitleChanged(EventArgs e) + { + if (SubTitleChanged != null) + SubTitleChanged(this, e); + } + + public virtual void OnCaptionTitleChanged(EventArgs e) + { + if (CaptionTitleChanged != null) + CaptionTitleChanged(this, e); + } + } +} \ No newline at end of file diff --git a/Labyrinth3/Crownwood.Magic/Controls/WizardControl/WizardPage.resx b/Labyrinth3/Crownwood.Magic/Controls/WizardControl/WizardPage.resx new file mode 100644 index 0000000..7e32396 --- /dev/null +++ b/Labyrinth3/Crownwood.Magic/Controls/WizardControl/WizardPage.resx @@ -0,0 +1,42 @@ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + text/microsoft-resx + + + 1.0.0.0 + + + System.Resources.ResXResourceReader, System.Windows.Forms, Version=1.0.3102.0, Culture=neutral, PublicKeyToken=b77a5c561934e089 + + + System.Resources.ResXResourceWriter, System.Windows.Forms, Version=1.0.3102.0, Culture=neutral, PublicKeyToken=b77a5c561934e089 + + diff --git a/Labyrinth3/Crownwood.Magic/Docking/AutoHidePanel.cs b/Labyrinth3/Crownwood.Magic/Docking/AutoHidePanel.cs new file mode 100644 index 0000000..b87739e --- /dev/null +++ b/Labyrinth3/Crownwood.Magic/Docking/AutoHidePanel.cs @@ -0,0 +1,1655 @@ +// ***************************************************************************** +// +// (c) Crownwood Consulting Limited 2002-2003 +// All rights reserved. The software and associated documentation +// supplied hereunder are the proprietary information of Crownwood Consulting +// Limited, Crownwood, Bracknell, Berkshire, England and are supplied subject +// to licence terms. +// +// Magic Version 1.7.4.0 www.dotnetmagic.com +// ***************************************************************************** + +using Crownwood.Magic.Collections; + +//using Crownwood.Magic.Win32; +using Crownwood.Magic.Common; +using Crownwood.Magic.Controls; +using System; +using System.ComponentModel; +using System.Drawing; +using System.Windows.Forms; + +namespace Crownwood.Magic.Docking +{ + [ToolboxItem(false)] + public class AutoHidePanel : Panel, IMessageFilter + { + [ToolboxItem(false)] + protected class AutoHostPanel : Panel, IResizeSource + { + protected Edge _borderEdge; + protected ResizeAutoBar _resizeAutoBar; + protected AutoHidePanel _autoHidePanel; + protected DockingManager _manager; + + public AutoHostPanel(DockingManager manager, AutoHidePanel autoHidePanel, Edge borderEdge) + { + // Remember parameters + _manager = manager; + _autoHidePanel = autoHidePanel; + _borderEdge = borderEdge; + + Direction direction; + + if ((borderEdge == Edge.Left) || (borderEdge == Edge.Right)) + direction = Direction.Horizontal; + else + direction = Direction.Vertical; + + // Create a resizing bar + _resizeAutoBar = new ResizeAutoBar(direction, this); + + // Add to the display + Controls.Add(_resizeAutoBar); + + // Define correct position based on Edge + switch (_borderEdge) + { + case Edge.Left: + _resizeAutoBar.Dock = DockStyle.Left; + break; + + case Edge.Right: + _resizeAutoBar.Dock = DockStyle.Right; + break; + + case Edge.Top: + _resizeAutoBar.Dock = DockStyle.Top; + break; + + case Edge.Bottom: + _resizeAutoBar.Dock = DockStyle.Bottom; + break; + } + } + + public Size ResizeBarSize() + { + return _resizeAutoBar.Size; + } + + public int MinimumWidth + { + get { return _resizeAutoBar.Width * 5; } + } + + public int MinimumHeight + { + get { return _resizeAutoBar.Height * 6; } + } + + public Color ResizeBarColor + { + get { return _manager.ResizeBarColor; } + } + + public int ResizeBarVector + { + get { return _manager.ResizeBarVector; } + } + + public VisualStyle Style + { + get { return _manager.Style; } + } + + public Color BackgroundColor + { + get { return _manager.BackColor; } + } + + public bool CanResize(ResizeBar bar) + { + return true; + } + + public bool StartResizeOperation(ResizeBar bar, ref Rectangle screenBoundary) + { + // Set focus into the WCT to prevent it siding away during resize + _autoHidePanel.SetFocusToWCT(); + + // Define resize boundary as the inner area of the Form containing the Zone + screenBoundary = this.Parent.RectangleToScreen(_manager.InnerResizeRectangle(this)); + + // Find the screen limits of this Zone + Rectangle panelBoundary = RectangleToScreen(this.ClientRectangle); + + int minHeight = this.MinimumHeight; + int minWidth = this.MinimumWidth; + + // Restrict resize based on which edge we are attached against + switch (_borderEdge) + { + case Edge.Bottom: + { + // Restrict Zone being made smaller than its minimum height + int diff = panelBoundary.Top - screenBoundary.Top + minHeight; + screenBoundary.Y += diff; + screenBoundary.Height -= diff; + + // Restrict Zone from making inner control smaller than minimum allowed + int innerMinimumWidth = _manager.InnerMinimum.Height; + screenBoundary.Height -= innerMinimumWidth; + } + break; + + case Edge.Top: + { + // Restrict Zone being made smaller than its minimum height + int diff = panelBoundary.Bottom - screenBoundary.Bottom - minHeight; + screenBoundary.Height += diff; + + // Restrict Zone from making inner control smaller than minimum allowed + int innerMinimumWidth = _manager.InnerMinimum.Height; + screenBoundary.Y += innerMinimumWidth; + screenBoundary.Height -= innerMinimumWidth; + } + break; + + case Edge.Right: + { + // Restrict Zone being made smaller than its minimum width + int diff = panelBoundary.Left - screenBoundary.Left + minWidth; + screenBoundary.X += diff; + screenBoundary.Width -= diff; + + // Restrict Zone from making inner control smaller than minimum allowed + int innerMinimumWidth = _manager.InnerMinimum.Width; + screenBoundary.Width -= innerMinimumWidth; + } + break; + + case Edge.Left: + { + // Restrict Zone being made smaller than its minimum width + int diff = panelBoundary.Right - screenBoundary.Right - minWidth; + screenBoundary.Width += diff; + + // Restrict Zone from making inner control smaller than minimum allowed + int innerMinimumWidth = _manager.InnerMinimum.Width; + screenBoundary.X += innerMinimumWidth; + screenBoundary.Width -= innerMinimumWidth; + } + break; + } + + return true; + } + + public void EndResizeOperation(ResizeBar bar, int delta) + { + switch (_borderEdge) + { + case Edge.Right: + Controls[1].Width += delta; + this.Width += delta; + _autoHidePanel.UpdateContentSize(Controls[1].Width, true); + break; + + case Edge.Left: + Controls[1].Width -= delta; + this.Width -= delta; + this.Left += delta; + _autoHidePanel.UpdateContentSize(Controls[1].Width, true); + break; + + case Edge.Bottom: + Controls[1].Height += delta; + this.Height += delta; + _autoHidePanel.UpdateContentSize(Controls[1].Height, false); + break; + + case Edge.Top: + Controls[1].Height -= delta; + this.Height -= delta; + this.Top += delta; + _autoHidePanel.UpdateContentSize(Controls[1].Height, false); + break; + } + + _autoHidePanel.DefineRectangles(); + } + + public void PropogateNameValue(PropogateName name, object value) + { + switch (name) + { + case PropogateName.BackColor: + this.BackColor = (Color)value; + Invalidate(); + break; + } + + // Pass onto the Resize bar control + _resizeAutoBar.PropogateNameValue(name, value); + } + + protected override void OnPaintBackground(PaintEventArgs e) + { + // Overriden to prevent background being painted + } + + protected override void OnPaint(PaintEventArgs e) + { + // Overriden to paint just the inward facing edge + } + } + + // Static fields + protected static int _num = 0; + + protected static int _slideSteps = 4; + protected static int _slideInterval = 15; + protected static int _dismissInterval = 1000; + + // Instance fields + protected int _number; + + protected bool _killing; + protected bool _defaultColor; + protected bool _dismissRunning; + protected bool _slideRunning; + protected bool _ignoreDismiss; + protected bool _slideOut; + protected int _slideStep; + protected Timer _slideTimer; + protected Timer _dismissTimer; + protected Rectangle _slideRect; + protected Rectangle _rememberRect; + protected DockingManager _manager; + protected AutoHostPanel _currentPanel; + protected WindowContentTabbed _currentWCT; + + public AutoHidePanel(DockingManager manager, DockStyle dockEdge) + { + // Define initial state + _number = _num++; + _defaultColor = true; + _dismissRunning = false; + _slideRunning = false; + _ignoreDismiss = false; + _killing = false; + _manager = manager; + _currentWCT = null; + _currentPanel = null; + _slideRect = new Rectangle(); + _rememberRect = new Rectangle(); + + // Get the minimum vector length used for sizing + int vector = TabStub.TabStubVector(this.Font); + + // Use for both directions, the appropriate one will be ignored because of docking style + this.Size = new Size(vector, vector); + + // Dock ourself against requested position + this.Dock = dockEdge; + + // We should be hidden until some Contents are added + this.Hide(); + + // We want to perform special action when container is resized + _manager.Container.Resize += new EventHandler(OnContainerResized); + + // Add ourself to the application filtering list + Application.AddMessageFilter(this); + + // Configuration timer objects + CreateTimers(); + } + + public void PropogateNameValue(PropogateName name, object value) + { + switch (name) + { + case PropogateName.BackColor: + this.BackColor = (Color)value; + Invalidate(); + break; + + case PropogateName.CaptionFont: + this.Font = (Font)value; + + // Recalculate the window size + int vector = TabStub.TabStubVector(this.Font); + this.Size = new Size(vector, vector); + + Invalidate(); + break; + } + + // Pass onto each TabStub instance + foreach (TabStub ts in Controls) + ts.PropogateNameValue(name, value); + + // Pass onto any current Panel object + if (_currentPanel != null) + _currentPanel.PropogateNameValue(name, value); + } + + public override Color BackColor + { + get { return base.BackColor; } + + set + { + if (this.BackColor != value) + { + _defaultColor = (value == SystemColors.Control); + base.BackColor = value; + Invalidate(); + } + } + } + + protected override void OnSystemColorsChanged(EventArgs e) + { + if (_defaultColor) + Invalidate(); + } + + protected void CreateTimers() + { + // Define the Sliding timer + _slideTimer = new Timer(); + _slideTimer.Interval = _slideInterval; + _slideTimer.Tick += new EventHandler(OnSlideTick); + + // Define the Dismiss timer + _dismissTimer = new Timer(); + _dismissTimer.Interval = _dismissInterval; + _dismissTimer.Tick += new EventHandler(OnDismissTick); + } + + protected void StartDismissTimer() + { + // If dismiss timer not running, then start it off + if (!_dismissRunning) + { + // Start the dismiss timer + _dismissRunning = true; + _dismissTimer.Start(); + } + } + + protected void StopDismissTimer() + { + // Stop the dismiss timer from reoccuring + _dismissRunning = false; + _dismissTimer.Stop(); + } + + protected void StartSlideTimer() + { + // If slide timer not running, then start it off + if (!_slideRunning) + { + // Start the dismiss timer + _slideStep = 0; + _slideRunning = true; + _slideTimer.Start(); + } + } + + protected void StopSlideTimer() + { + // Stop the slide timer from reoccuring + _slideRunning = false; + _slideTimer.Stop(); + } + + public bool ContainsContent(Content c) + { + return (TabStubForContent(c) != null); + } + + protected TabStub TabStubForContent(Content c) + { + // Test each of the TabStub child controls + foreach (TabStub ts in this.Controls) + { + // Test each page inside the TabStub + foreach (Crownwood.Magic.Controls.TabPage page in ts.TabPages) + { + if (c.Title == (page.Tag as Content).Title) + return ts; + } + } + + return null; + } + + public void BringContentIntoView(Content c) + { + // Test each of the TabStub child controls + foreach (TabStub ts in this.Controls) + { + // Test each page inside the TabStub + foreach (Crownwood.Magic.Controls.TabPage page in ts.TabPages) + { + if (c.Title == (page.Tag as Content).Title) + { + // Remove any existing window + RemoveShowingWindow(); + + // Use existing method to cause content to be displayed + OnPageClicked(ts, ts.TabPages.IndexOf(page)); + return; + } + } + } + } + + public Restore RestoreObjectForContent(Content c) + { + StringCollection next = new StringCollection(); + StringCollection previous = new StringCollection(); + StringCollection nextAll = new StringCollection(); + StringCollection previousAll = new StringCollection(); + + // Which group has the marked content? + TabStub marked = TabStubForContent(c); + + // Have we found the marked group yet? + bool foundGroup = false; + + // Found the content in the marked group yet? + bool foundContent = false; + + int controlCount = this.Controls.Count; + + // Process each TabStub in turn + for (int controlIndex = controlCount - 1; controlIndex >= 0; controlIndex--) + { + TabStub ts = this.Controls[controlIndex] as TabStub; + + // Process each Page in the TabStub + foreach (Crownwood.Magic.Controls.TabPage page in ts.TabPages) + { + Content content = page.Tag as Content; + + // Is this the marked group + if (marked == ts) + { + // Add into the 'nextAll' rather than 'previousAll' groups from now on + foundGroup = true; + + // No need to save ourself in our best friends list! + if (content.Title == c.Title) + { + // Add into the 'next' rather than 'previous' contents now + foundContent = true; + } + else + { + if (!foundContent) + previous.Add(content.Title); + else + next.Add(content.Title); + } + } + else + { + if (!foundGroup) + previousAll.Add(content.Title); + else + nextAll.Add(content.Title); + } + } + } + + // Calculate state from docking value + State windowState = State.DockLeft; + + // Define stub settings based on our docking position + switch (this.Dock) + { + case DockStyle.Left: + windowState = State.DockLeft; + break; + + case DockStyle.Right: + windowState = State.DockRight; + break; + + case DockStyle.Top: + windowState = State.DockTop; + break; + + case DockStyle.Bottom: + windowState = State.DockBottom; + break; + } + + return new RestoreAutoHideAffinity(null, windowState, c, next, previous, nextAll, previousAll); + } + + public void AddContent(Content content, + StringCollection next, + StringCollection previous, + StringCollection nextAll, + StringCollection previousAll) + { + int nextIndex = 0; + int previousIndex = 0; + TabStub nextTabStub = null; + TabStub previousTabStub = null; + TabStub nextAllTabStub = null; + TabStub previousAllTabStub = null; + + int controlCount = this.Controls.Count; + + // Process each TabStub in turn + for (int controlIndex = controlCount - 1; controlIndex >= 0; controlIndex--) + { + TabStub ts = this.Controls[controlIndex] as TabStub; + + // Process each Page in the TabStub + foreach (Crownwood.Magic.Controls.TabPage page in ts.TabPages) + { + Content c = page.Tag as Content; + + // Always use the last 'previous' discovered + if (previous.Contains(c.Title)) + { + previousIndex = ts.TabPages.IndexOf(page); + previousTabStub = ts; + } + + // Only remember the first 'next' discovered + if (next.Contains(c.Title)) + { + if (nextTabStub == null) + { + nextIndex = ts.TabPages.IndexOf(page); + nextTabStub = ts; + } + } + + // Always use the last 'previousAll' discovered + if (previousAll.Contains(c.Title)) + previousAllTabStub = ts; + + // Only remember the first 'next' discovered + if (nextAll.Contains(c.Title)) + { + if (nextAllTabStub == null) + nextAllTabStub = ts; + } + } + } + + // If no matches at all found + if ((previousTabStub == null) && (nextTabStub == null)) + { + // Default to inserting at end of list + int insertIndex = Controls.Count; + + // If found some friends contents, then insert relative to them + if (previousAllTabStub != null) + insertIndex = Controls.IndexOf(previousAllTabStub); + else + { + if (nextAllTabStub != null) + insertIndex = Controls.IndexOf(nextAllTabStub) + 1; + } + + ContentCollection cs = new ContentCollection(); + + cs.Add(content); + + // Add at end of current list of TabStubs + AddContentsAsGroup(cs, insertIndex); + } + else + { + if (previousTabStub != null) + AddContentIntoTabStub(content, previousTabStub, previousIndex + 1); + else + AddContentIntoTabStub(content, nextTabStub, nextIndex); + } + } + + public void AddContentIntoTabStub(Content content, TabStub ts, int index) + { + // Is focus leaving the entire WindowContentTabbed control? + if ((_currentWCT != null) && (_currentWCT == ts.WindowContentTabbed)) + { + // Remove Panel/WCT from display and stop timers + RemoveDisplayedWindow(); + } + + // Create a new tab page + Crownwood.Magic.Controls.TabPage page = new Crownwood.Magic.Controls.TabPage(); + + // Copy across the visual properties + page.Title = content.Title; + page.ImageList = content.ImageList; + page.ImageIndex = content.ImageIndex; + page.Icon = content.Icon; + + // Remember reference to Content it represents + page.Tag = content; + + // Add into the stub + ts.TabPages.Insert(index, page); + + // Mark Content as being in AutoHide mode + content.AutoHidePanel = this; + content.AutoHidden = true; + + // Add content into the WCT of the TabStub + ts.WindowContentTabbed.Contents.Insert(index, content); + + // Make sure this AutoHidePanel is visible + if (!this.Visible) + this.Show(); + + Invalidate(); + } + + public void AddContentsAsGroup(ContentCollection contents) + { + // By default, insert new group at the end of display which is start of list + AddContentsAsGroup(contents, 0); + } + + public void AddContentsAsGroup(ContentCollection contents, int index) + { + // Create new TabStub to represent the Contents + TabStub ts = new TabStub(_manager.Style); + + // Set manager requested settings + ts.Font = _manager.CaptionFont; + ts.BackColor = _manager.BackColor; + ts.ForeColor = _manager.InactiveTextColor; + + // Hook into events + ts.PageOver += new TabStub.TabStubIndexHandler(OnPageOver); + ts.PageClicked += new TabStub.TabStubIndexHandler(OnPageClicked); + ts.PagesLeave += new TabStub.TabStubHandler(OnPagesLeave); + + // Add a page for each Content instance + foreach (Content c in contents) + { + // Create page object + Crownwood.Magic.Controls.TabPage page = new Crownwood.Magic.Controls.TabPage(); + + // Copy across the visual properties + page.Title = c.Title; + page.ImageList = c.ImageList; + page.ImageIndex = c.ImageIndex; + page.Icon = c.Icon; + + // Remember reference to Content it represents + page.Tag = c; + + // Add into the stub + ts.TabPages.Add(page); + + // Mark Content as being in AutoHide mode + c.AutoHidePanel = this; + c.AutoHidden = true; + } + + State windowState = State.DockLeft; + + // Define stub settings based on our docking position + switch (this.Dock) + { + case DockStyle.Left: + windowState = State.DockLeft; + ts.Edging = Edge.Left; + ts.Dock = DockStyle.Top; + break; + + case DockStyle.Right: + windowState = State.DockRight; + ts.Edging = Edge.Right; + ts.Dock = DockStyle.Top; + break; + + case DockStyle.Top: + windowState = State.DockTop; + ts.Edging = Edge.Top; + ts.Dock = DockStyle.Left; + break; + + case DockStyle.Bottom: + windowState = State.DockBottom; + ts.Edging = Edge.Bottom; + ts.Dock = DockStyle.Left; + break; + } + + // Add stub into the view + Controls.Add(ts); + + // Set correct new position + Controls.SetChildIndex(ts, index); + + // Each TabStub has a WCT created and ready to be shown when needed + WindowContentTabbed wct = _manager.CreateWindowForContent(null, new EventHandler(OnPageClose), + null, new EventHandler(OnPageAutoHide), + new ContextHandler(OnPageContextMenu)) as WindowContentTabbed; + + // Add each Content instance in turn + foreach (Content c in contents) + wct.Contents.Add(c); + + // By default the first Content added to a WCT will define the size + // of the WCT control. We need to override this to use the AutoHideSize + // from the first Content instead. + wct.Size = contents[0].AutoHideSize; + + // Ensure Window caption bar reflects correct docking status + wct.State = windowState; + + // Inform Window it should not allow user initiated redocking + wct.RedockAllowed = false; + + // Hide tab selection from user + wct.TabControl.HideTabsMode = Magic.Controls.TabControl.HideTabsModes.HideAlways; + + // Associate WCT with matching TabStub + ts.WindowContentTabbed = wct; + + // Make sure this AutoHidePanel is visible + if (!this.Visible) + this.Show(); + + Invalidate(); + } + + public void InvertAutoHideWindowContent(WindowContentTabbed wct) + { + UnAutoHideWindowContent(wct, true); + } + + protected void RemoveDisplayedWindow() + { + if (_currentPanel != null) + { + // Remove snooping of changes to focus + MonitorPanel(false); + + // Remove the child WindowContentTabbed + ControlHelper.Remove(_currentPanel.Controls, _currentWCT); + + // Remove Panel from managed container + ControlHelper.Remove(_manager.Container.Controls, _currentPanel); + } + + if (_currentWCT != null) + { + // Restore the original sizes + _currentWCT.Width = _rememberRect.Width; + _currentWCT.Height = _rememberRect.Height; + } + + if (_currentPanel != null) + { + // Destroy the panel + _currentPanel.Dispose(); + _currentPanel = null; + } + } + + protected void KillDisplayedWindow(WindowContentTabbed wct) + { + _killing = true; + + // If dismiss timer running, then turn it off + StopDismissTimer(); + + // Sometimes this method is called when _currentWCT is not set + if (wct != null) + { + // Remove content objects from WCT to update state + int count = wct.Contents.Count; + + for (int index = 0; index < count; index++) + { + // Remove it from collection + wct.Contents.RemoveAt(0); + } + + // Get rid of the displayed Panel immediately + RemoveDisplayedWindow(); + + // No longer considered the shown window + wct.Dispose(); + + // Make sure instance reference is nulled where appropriate + if (wct == _currentWCT) + _currentWCT = null; + } + + _killing = false; + } + + protected void UpdateContentSize(int newVector, bool isWidth) + { + // Ensure we have a Panel to work with + if (_currentPanel != null) + { + // Should always have WCT, but just in case... + if (_currentWCT != null) + { + // Modify the remembered AutoHide vector + foreach (Content c in _currentWCT.Contents) + { + // Get existing Size + Size s = c.AutoHideSize; + + // Update appropriate vector + if (isWidth) + s.Width = newVector; + else + s.Height = newVector; + + // Save it away + c.AutoHideSize = s; + } + } + } + } + + protected void DefineRectangles() + { + // Store original WCT size to be restored later + _rememberRect = _currentWCT.ClientRectangle; + + // Default showing size to that requested by WCT + _slideRect = _rememberRect; + + // Find actual available Form size for sliding into + Rectangle availableSize = _manager.InnerResizeRectangle(this); + + // Reduce actual displayed size by limits of Form size + if (availableSize.Width < _slideRect.Width) + _slideRect.Width = availableSize.Width; + + if (availableSize.Height < _slideRect.Height) + _slideRect.Height = availableSize.Height; + } + + protected void SetFocusToWCT() + { + // Ensure we have a Panel to work with + if (_currentPanel != null) + { + // If the Panel does not already contain the focus... + if (!_currentWCT.ContainsFocus) + { + _currentWCT.Focus(); + _currentWCT.Refresh(); + } + } + } + + protected void OnPageClicked(TabStub sender, int pageIndex) + { + // Remove any showing auto hide windows except our own + _manager.RemoveShowingAutoHideWindowsExcept(this); + + // A click is the same as an immediate hover over + OnPageOver(sender, pageIndex); + + // A click implies the panel takes the focus immediately + SetFocusToWCT(); + } + + protected void OnPageOver(TabStub sender, int pageIndex) + { + // Remove any showing auto hide windows except our own + _manager.RemoveShowingAutoHideWindowsExcept(this); + + // No need for running timer, this action supercedes it + StopDismissTimer(); + + // Hovering over a different TabStub? + if (_currentWCT != sender.WindowContentTabbed) + { + // Remove any currently displayed Panel/WCT + if (_currentWCT != null) + RemoveDisplayedWindow(); + } + else + { + // Different tab in the same TabStub? + if (pageIndex != _currentWCT.TabControl.SelectedIndex) + { + // Remove any currently displayed Panel/WCT + if (_currentWCT != null) + RemoveDisplayedWindow(); + } + else + { + // Hover over the current window, so do nothing + return; + } + } + + Edge borderEdge = Edge.None; + + // Define which edge of the host panel shown have a border drawn + switch (this.Dock) + { + case DockStyle.Left: + borderEdge = Edge.Right; + break; + + case DockStyle.Right: + borderEdge = Edge.Left; + break; + + case DockStyle.Top: + borderEdge = Edge.Bottom; + break; + + case DockStyle.Bottom: + borderEdge = Edge.Top; + break; + } + + // Create a Panel that will host the actual WindowContentTabbed control, + // the Panel is resized to slide into/from view. The WCT is a fixed size + // within the Panel and so only the partial view of the WCT is shown and + // at any point in time. Cannot resize the WCT into view as it would keep + // repainting the caption details and effect and docking items inside it. + _currentPanel = new AutoHostPanel(_manager, this, borderEdge); + + // Do not show it until we have resizing it as needed + _currentPanel.Hide(); + + // Get access to the WindowContentTabbed that is to be hosted + _currentWCT = sender.WindowContentTabbed; + + // Select the correct page for view in the WCT + _currentWCT.TabControl.SelectedIndex = pageIndex; + + // Place the WCT inside the host Panel + _currentPanel.Controls.Add(_currentWCT); + + // Now add the Panel to the container display + _manager.Container.Controls.Add(_currentPanel); + + // Make it top of the Z-Order + _manager.Container.Controls.SetChildIndex(_currentPanel, 0); + + // Define the remember and slide rectangle values + DefineRectangles(); + + // Set the modified WCT size + _currentWCT.Width = _slideRect.Width; + _currentWCT.Height = _slideRect.Height; + + Size barSize = _currentPanel.ResizeBarSize(); + + // Set the initial size/location of Panel and hosted WCT + switch (this.Dock) + { + case DockStyle.Left: + _currentPanel.Size = new Size(0, this.Height); + _currentPanel.Location = new Point(this.Right, this.Top); + _currentWCT.Height = this.Height; + break; + + case DockStyle.Right: + _currentPanel.Size = new Size(0, this.Height); + _currentPanel.Location = new Point(this.Left, this.Top); + _currentWCT.Height = this.Height; + break; + + case DockStyle.Top: + _currentPanel.Size = new Size(this.Width, 0); + _currentPanel.Location = new Point(this.Left, this.Bottom); + _currentWCT.Width = this.Width; + break; + + case DockStyle.Bottom: + _currentPanel.Size = new Size(this.Width, 0); + _currentPanel.Location = new Point(this.Left, this.Top); + _currentWCT.Width = this.Width; + break; + } + + // Finally we are ready to show it + _currentPanel.Show(); + + // We want to snoop of changes of focus to and from Panel and its children + MonitorPanel(true); + + // We are showing and not hiding with the timer + _slideOut = true; + + // Kick off the slide timer + StartSlideTimer(); + } + + protected void OnPagesLeave(TabStub sender) + { + // Do we have anything to dismiss? + if ((_currentPanel != null) && (_currentWCT != null)) + { + // Only dimiss if the panel does not have focus + if (!_currentPanel.ContainsFocus) + StartDismissTimer(); + } + } + + public void RemoveContent(Content c) + { + TabStub targetTS = null; + Crownwood.Magic.Controls.TabPage targetPage = null; + + // Find the TabStub group this content is inside + foreach (TabStub ts in this.Controls) + { + // Test each page of the TabStub control + foreach (Crownwood.Magic.Controls.TabPage page in ts.TabPages) + { + Content pageC = page.Tag as Content; + + if (pageC == c) + { + // Remember found target + targetTS = ts; + targetPage = page; + break; + } + } + } + + // Found a target? + if ((targetTS != null) && (targetPage != null)) + { + // Are we removing the last entry in the WCT? + if (targetTS.TabPages.Count == 1) + { + int count = targetTS.WindowContentTabbed.Contents.Count; + + // Remove all contents from the WCT + for (int i = 0; i < count; i++) + targetTS.WindowContentTabbed.Contents.RemoveAt(0); + + // If any panel/WCT showing + if (targetTS.WindowContentTabbed == _currentWCT) + { + // Remove Panel/WCT from display and stop timers + KillDisplayedWindow(_currentWCT); + } + + // Remove the WCT from TabStub + ControlHelper.Remove(targetTS.Controls, targetTS.WindowContentTabbed); + + // Remove the stub from this panel + ControlHelper.Remove(this.Controls, targetTS); + + // Cleanup gracefully + targetTS.Dispose(); + } + else + { + // Currently showing some pages? + if (targetTS.WindowContentTabbed == _currentWCT) + { + bool found = false; + + // Is it our page? + foreach (Content cWCT in _currentWCT.Contents) + { + if (cWCT == c) + { + // Remove our page from view + found = true; + break; + } + } + + // Remove unwanted page + if (found) + { + // Find its position index + int index = _currentWCT.Contents.IndexOf(c); + + // Remove just the selected entry from stub + targetTS.TabPages.RemoveAt(index); + + // Remove the selected entry from WCT + _currentWCT.Contents.RemoveAt(index); + } + } + + // Remove just the selected entry from stub + targetTS.TabPages.Remove(targetPage); + } + + // No longer inside an auto hidden panel + c.AutoHidePanel = null; + } + + // If no more contents remain then hide + if (this.Controls.Count == 0) + this.Hide(); + } + + protected void OnPageClose(object sender, EventArgs e) + { + // Find the TabStub instance for the showing WCT + foreach (TabStub ts in this.Controls) + { + // Does this stub match the one showing? + if (ts.WindowContentTabbed == _currentWCT) + { + ContentCollection cc = new ContentCollection(); + + // Get access to Content instance being hidden + Content current = _currentWCT.Contents[ts.SelectedIndex]; + + // Check if the hide button is allowed to work + if (!_manager.OnContentHiding(current)) + { + // Are we removing the last entry in the WCT? + if (ts.TabPages.Count == 1) + { + // We need to update AutoHide property for all of them + foreach (Content c in _currentWCT.Contents) + { + // Remember this AutoHide state for persistence + c.RecordAutoHideRestore(); + + cc.Add(c); + } + + // Remove Panel/WCT from display and stop timers + KillDisplayedWindow(_currentWCT); + + // Remove the WCT from the WCT + ControlHelper.Remove(ts.Controls, ts.WindowContentTabbed); + + // Remove the stub from this panel + ControlHelper.Remove(this.Controls, ts); + + // Cleanup gracefully + ts.Dispose(); + } + else + { + // Which entry in the stub is currently selected? + int index = ts.SelectedIndex; + + // Remember this AutoHide state for persistence + _currentWCT.Contents[index].RecordAutoHideRestore(); + + // Need to update AutoHide property for removed content + cc.Add(_currentWCT.Contents[index]); + + // Remove just the selected entry from stub + ts.TabPages.RemoveAt(index); + + // Remove the selected entry from WCT + _currentWCT.Contents.RemoveAt(index); + } + + // Content instances no longer in AutoHidden state + foreach (Content c in cc) + { + // No longer in the auto hidden mode + c.AutoHidden = false; + c.AutoHidePanel = null; + } + } + + // Generate hidden event now content is not visible + _manager.OnContentHidden(current); + + break; + } + } + + // If no more contents remain then hide + if (this.Controls.Count == 0) + this.Hide(); + } + + protected void OnPageAutoHide(object sender, EventArgs e) + { + UnAutoHideWindowContent(_currentWCT, false); + } + + protected void UnAutoHideWindowContent(WindowContentTabbed wct, bool forceKill) + { + // Do not generate hiding/hidden/shown events + _manager.SurpressVisibleEvents += 1; + + // Find the TabStub instance for the showing WCT + foreach (TabStub ts in this.Controls) + { + // Does this stub match the one showing? + if (ts.WindowContentTabbed == wct) + { + int count = ts.TabPages.Count; + + // Record the auto hide state in reverse order, must record the state + // before 'KillDisplayedWindow' as the process of recording state requires + // the content to be inside a WindowContent instance + for (int i = count - 1; i >= 0; i--) + { + // Get access to the content the page represents + Content c = ts.TabPages[i].Tag as Content; + + // Remember this AutoHide state for persistence + c.RecordAutoHideRestore(); + } + + // Remove Panel/WCT from display and stop timers + if (forceKill) + KillDisplayedWindow(wct); + else + KillDisplayedWindow(_currentWCT); + + // Remove the stub from this panel + ControlHelper.Remove(this.Controls, ts); + + // Now that the Window/Panel have been killed we are ready to + // alter the AutoHidden state of each content and restore state + for (int i = count - 1; i >= 0; i--) + { + // Get access to the content the page represents + Content c = ts.TabPages[i].Tag as Content; + + // No longer in the auto hidden mode + c.AutoHidden = false; + c.AutoHidePanel = null; + + // Restore into normal docked state + _manager.ShowContent(c); + } + + break; + } + } + + // If no more contents remain then hide + if (this.Controls.Count == 0) + this.Hide(); + + // Enable generation hiding/hidden/shown events + _manager.SurpressVisibleEvents -= 1; + } + + protected void OnPageContextMenu(Point screenPos) + { + _manager.OnShowContextMenu(screenPos); + } + + protected void OnSlideTick(object sender, EventArgs e) + { + // Is the slide timer supposed to be running? + if (_slideRunning) + { + // Safety check that timer does not expire after our death + if (this.IsDisposed || _currentPanel.IsDisposed || _currentWCT.IsDisposed) + { + StopSlideTimer(); + return; + } + + // Use the current size/location as the starting point for changes + Rectangle rect = new Rectangle(_currentPanel.Left, _currentPanel.Top, + _currentPanel.Width, _currentPanel.Height); + + // How big is the resize bar inside the Panel? + Size barSize = _currentPanel.ResizeBarSize(); + + // Is this the last sliding step? + // (increase test by 1 because we have not yet incremented it) + bool lastStep = ((_slideStep + 1) >= _slideSteps); + + // Bringing the Panel into view? + if (_slideOut) + { + // Bring Panel another step into full view + switch (this.Dock) + { + case DockStyle.Left: + if (lastStep) + rect.Width = _slideRect.Width + barSize.Width; + else + rect.Width = (_slideRect.Width + barSize.Width) / + _slideSteps * (_slideStep + 1); + + // Want the right hand side of WCT showing + _currentWCT.Location = new Point(rect.Width - _currentWCT.Width - barSize.Width, 0); + break; + + case DockStyle.Right: + int right = _currentPanel.Right; + + if (lastStep) + rect.Width = _slideRect.Width + barSize.Width; + else + rect.Width = (_slideRect.Width + barSize.Width) / + _slideSteps * (_slideStep + 1); + + rect.X -= rect.Right - right; + + _currentWCT.Location = new Point(barSize.Width, 0); + break; + + case DockStyle.Top: + if (lastStep) + rect.Height = _slideRect.Height + barSize.Height; + else + rect.Height = (_slideRect.Height + barSize.Height) / + _slideSteps * (_slideStep + 1); + + // Want the bottom of the WCT showing + _currentWCT.Location = new Point(0, rect.Height - _currentWCT.Height - barSize.Height); + break; + + case DockStyle.Bottom: + int bottom = _currentPanel.Bottom; + + if (lastStep) + rect.Height = _slideRect.Height + barSize.Height; + else + rect.Height = (_slideRect.Height + barSize.Height) / + _slideSteps * (_slideStep + 1); + + rect.Y -= rect.Bottom - bottom; + + _currentWCT.Location = new Point(0, barSize.Height); + break; + } + + // Have to use Win32 API call to alter the Panel size and position at the same time, no + // Control method/property is available to do both at the same time. Otherwise you can see + // the Panel being moved in two steps which looks naff! + //User32.MoveWindow(_currentPanel.Handle, rect.Left, rect.Top, rect.Width, rect.Height, true); + _currentPanel.Location = new Point(rect.Left, rect.Top); + _currentPanel.Size = new Size(rect.Width, rect.Height); + + // Stop timer when all required steps performed + if (lastStep) + { + StopSlideTimer(); + + // If sliding into view from bottom + if (this.Dock == DockStyle.Top) + { + // Must cause repaint to prevent artifacts + _currentPanel.Refresh(); + } + } + } + else + { + int steps = _slideSteps - _slideStep; + + // Move Window another step towards required position + switch (this.Dock) + { + case DockStyle.Left: + if (lastStep) + rect.Width = 0; + else + rect.Width = (_slideRect.Width + barSize.Width) / + _slideSteps * steps; + break; + + case DockStyle.Right: + int right = _currentPanel.Right; + + if (lastStep) + rect.Width = 0; + else + rect.Width = (_slideRect.Width + barSize.Width) / + _slideSteps * steps; + + rect.X += right - rect.Right; + break; + + case DockStyle.Top: + if (lastStep) + rect.Height = 0; + else + rect.Height = (_slideRect.Height + barSize.Height) / + _slideSteps * steps; + break; + + case DockStyle.Bottom: + int bottom = _currentPanel.Bottom; + + if (lastStep) + rect.Height = 0; + else + rect.Height = (_slideRect.Height + barSize.Height) / + _slideSteps * steps; + + rect.Y += bottom - rect.Bottom; + break; + } + + // Have to use Win32 API call to alter the Panel size and position at the same time, no + // Control method/property is available to do both at the same time. Otherwise you can see + // the Panel being moved in two steps which looks naff! + //User32.MoveWindow(_currentPanel.Handle, rect.Left, rect.Top, rect.Width, rect.Height, true); + _currentPanel.Location = new Point(rect.Left, rect.Top); + _currentPanel.Size = new Size(rect.Width, rect.Height); + + // Stop timer when all required steps performed + if (lastStep) + { + StopSlideTimer(); + + // No longer need to show it + RemoveDisplayedWindow(); + + // No longer considered the shown window + _currentWCT = null; + } + } + + // Increment the step value + _slideStep++; + } + } + + protected void OnDismissTick(object sender, EventArgs e) + { + // Safety check that timer does not expire after our death + if (this.IsDisposed || (_currentPanel == null) || _currentPanel.IsDisposed) + { + StopDismissTimer(); + return; + } + + // Should any dismiss attempt from timer be ignored? + if (!_ignoreDismiss) + { + // Are we currently showing a Window? + if (_currentPanel != null) + { + // Timer is being used to hide the Panel + _slideOut = false; + + // Kick off the timer + StartSlideTimer(); + } + } + + // Stop the dismiss timer from reoccuring + StopDismissTimer(); + } + + protected void OnContainerResized(object sender, EventArgs e) + { + RemoveShowingWindow(); + } + + public void RemoveShowingWindow() + { + _ignoreDismiss = false; + + // Is focus leaving the entire WindowContentTabbed control? + if (_currentWCT != null) + { + // Remember current focus + // IntPtr hWnd = User32.GetFocus(); + + // Do not slide a window in the process of being removed + StopDismissTimer(); + StopSlideTimer(); + + // Remove Panel/WCT from display and stop timers + RemoveDisplayedWindow(); + + // No longer considered the shown window + _currentWCT = null; + + // Replace the focus + // User32.SetFocus(hWnd); + } + + // Prevent drawing artifacts by invalidating window + Invalidate(); + } + + protected void OnPanelEnter(object sender, EventArgs e) + { + _ignoreDismiss = true; + } + + protected void OnPanelLeave(object sender, EventArgs e) + { + _ignoreDismiss = false; + + // Is focus leaving the entire WindowContentTabbed control? + if (!_killing && (_currentWCT != null) && !_currentWCT.ContainsFocus) + { + // Remember current focus + // IntPtr hWnd = User32.GetFocus(); + + // Do not slide a window in the process of being removed + StopDismissTimer(); + StopSlideTimer(); + + // Remove Panel/WCT from display and stop timers + RemoveDisplayedWindow(); + + // No longer considered the shown window + _currentWCT = null; + + // Replace the focus + // User32.SetFocus(hWnd); + } + } + + protected void MonitorPanel(bool add) + { + MonitorControl(_currentPanel, add); + } + + protected void MonitorControl(Control c, bool add) + { + if (add) + { + // Monitor focus changes on the Control + c.GotFocus += new EventHandler(OnPanelEnter); + c.LostFocus += new EventHandler(OnPanelLeave); + } + else + { + // Unmonitor focus changes on the Control + c.GotFocus -= new EventHandler(OnPanelEnter); + c.LostFocus -= new EventHandler(OnPanelLeave); + } + + foreach (Control child in c.Controls) + MonitorControl(child, add); + } + + protected override void OnPaintBackground(PaintEventArgs e) + { + Color backColor = base.BackColor; + + if (_manager.Style == VisualStyle.IDE) + { + if (_defaultColor) + backColor = ColorHelper.TabBackgroundFromBaseColor(SystemColors.Control); + else + backColor = ColorHelper.TabBackgroundFromBaseColor(backColor); + } + else + if (_defaultColor) + backColor = SystemColors.Control; + + using (SolidBrush brush = new SolidBrush(backColor)) + e.Graphics.FillRectangle(brush, this.ClientRectangle); + } + + public bool PreFilterMessage(ref Message msg) + { + Form parentForm = this.FindForm(); + + // Only interested if the Form we are on contains the focus and we are showing a Panel + if ((parentForm != null) && (parentForm == Form.ActiveForm) && + parentForm.ContainsFocus && (_currentPanel != null) && + !_currentPanel.IsDisposed) + { + switch (msg.Msg) + { + case (int)Win32.Msgs.WM_MOUSEMOVE: + Win32.POINT screenPos; + screenPos.x = (int)((uint)msg.LParam & 0x0000FFFFU); + screenPos.y = (int)(((uint)msg.LParam & 0xFFFF0000U) >> 16); + + // Convert the mouse position to screen coordinates + //User32.ClientToScreen(msg.HWnd, ref screenPos); + PointToScreen(new Point(screenPos.x, screenPos.y)); + + // Get the screen rectangle for the showing panel and this object + Rectangle panelRect = _currentPanel.RectangleToScreen(_currentPanel.ClientRectangle); + Rectangle thisRect = this.RectangleToScreen(this.ClientRectangle); + + // Do we think the mouse is not over the tab or panel? + if (_dismissRunning) + { + // Is mouse moving over the panel? + if (panelRect.Contains(new Point(screenPos.x, screenPos.y))) + { + // Cancel timer + StopDismissTimer(); + } + } + else + { + // If mouse not over the Panel or the ourself + if (!panelRect.Contains(new Point(screenPos.x, screenPos.y)) && + !thisRect.Contains(new Point(screenPos.x, screenPos.y))) + { + // Simulate the mouse leaving ourself so that dismiss timer is started + OnPagesLeave(null); + } + } + + break; + } + } + + return false; + } + } +} \ No newline at end of file diff --git a/Labyrinth3/Crownwood.Magic/Docking/AutoHidePanel.resx b/Labyrinth3/Crownwood.Magic/Docking/AutoHidePanel.resx new file mode 100644 index 0000000..7e32396 --- /dev/null +++ b/Labyrinth3/Crownwood.Magic/Docking/AutoHidePanel.resx @@ -0,0 +1,42 @@ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + text/microsoft-resx + + + 1.0.0.0 + + + System.Resources.ResXResourceReader, System.Windows.Forms, Version=1.0.3102.0, Culture=neutral, PublicKeyToken=b77a5c561934e089 + + + System.Resources.ResXResourceWriter, System.Windows.Forms, Version=1.0.3102.0, Culture=neutral, PublicKeyToken=b77a5c561934e089 + + diff --git a/Labyrinth3/Crownwood.Magic/Docking/Content.cs b/Labyrinth3/Crownwood.Magic/Docking/Content.cs new file mode 100644 index 0000000..58b725e --- /dev/null +++ b/Labyrinth3/Crownwood.Magic/Docking/Content.cs @@ -0,0 +1,753 @@ +// ***************************************************************************** +// +// (c) Crownwood Consulting Limited 2002-2003 +// All rights reserved. The software and associated documentation +// supplied hereunder are the proprietary information of Crownwood Consulting +// Limited, Crownwood, Bracknell, Berkshire, England and are supplied subject +// to licence terms. +// +// Magic Version 1.7.4.0 www.dotnetmagic.com +// ***************************************************************************** + +using Crownwood.Magic.Common; +using System; +using System.Drawing; +using System.Windows.Forms; +using System.Xml; + +namespace Crownwood.Magic.Docking +{ + public class Content + { + // Enumeration of property change events + public enum Property + { + Control, + Title, + FullTitle, + ImageList, + ImageIndex, + Icon, + CaptionBar, + CloseButton, + HideButton, + DisplaySize, + AutoHideSize, + FloatingSize, + DisplayLocation + } + + // Declare the property change event signature + public delegate void PropChangeHandler(Content obj, Property prop); + + // Class constant + protected static int _defaultDisplaySize = 150; + + protected static int _defaultAutoHideSize = 150; + protected static int _defaultFloatingSize = 150; + protected static int _defaultLocation = 150; + protected static int _counter = 0; + + // Instance fields + protected Control _control; + + protected string _title; + protected string _fullTitle; + protected Icon _icon; + protected ImageList _imageList; + protected int _imageIndex; + protected int _order; + protected Size _displaySize; + protected Size _autoHideSize; + protected Size _floatingSize; + protected Point _displayLocation; + protected DockingManager _manager; + protected bool _docked; + protected bool _autoHidden; + protected bool _visible; + protected bool _captionBar; + protected bool _closeButton; + protected bool _hideButton; + protected bool _closeOnHide; + protected object _tag; + protected AutoHidePanel _autoHidePanel; + protected WindowContent _parentWindowContent; + protected Restore _defaultRestore; + protected Restore _autoHideRestore; + protected Restore _dockingRestore; + protected Restore _floatingRestore; + + // Instance events + public event PropChangeHandler PropertyChanging; + + public event PropChangeHandler PropertyChanged; + + public Content(XmlTextReader xmlIn, int formatVersion) + { + // Define the initial object state + _control = null; + _title = ""; + _fullTitle = ""; + _imageList = null; + _icon = null; + _imageIndex = -1; + _manager = null; + _parentWindowContent = null; + _displaySize = new Size(_defaultDisplaySize, _defaultDisplaySize); + _autoHideSize = new Size(_defaultAutoHideSize, _defaultAutoHideSize); + _floatingSize = new Size(_defaultFloatingSize, _defaultFloatingSize); + _displayLocation = new Point(_defaultLocation, _defaultLocation); + _order = _counter++; + _tag = null; + _visible = false; + _defaultRestore = null; + _autoHideRestore = null; + _floatingRestore = null; + _dockingRestore = null; + _autoHidePanel = null; + _docked = true; + _captionBar = true; + _closeButton = true; + _hideButton = true; + _autoHidden = false; + _closeOnHide = false; + + // Overwrite default with values read in + LoadFromXml(xmlIn, formatVersion); + } + + public Content(DockingManager manager) + { + InternalConstruct(manager, null, "", null, -1, null); + } + + public Content(DockingManager manager, Control control) + { + InternalConstruct(manager, control, "", null, -1, null); + } + + public Content(DockingManager manager, Control control, string title) + { + InternalConstruct(manager, control, title, null, -1, null); + } + + public Content(DockingManager manager, Control control, string title, ImageList imageList, int imageIndex) + { + InternalConstruct(manager, control, title, imageList, imageIndex, null); + } + + public Content(DockingManager manager, Control control, string title, Icon icon) + { + InternalConstruct(manager, control, title, null, -1, icon); + } + + protected void InternalConstruct(DockingManager manager, + Control control, + string title, + ImageList imageList, + int imageIndex, + Icon icon) + { + // Must provide a valid manager instance + if (manager == null) + throw new ArgumentNullException("DockingManager"); + + // Define the initial object state + _control = control; + _title = title; + _imageList = imageList; + _imageIndex = imageIndex; + _icon = icon; + _manager = manager; + _parentWindowContent = null; + _order = _counter++; + _visible = false; + _displaySize = new Size(_defaultDisplaySize, _defaultDisplaySize); + _autoHideSize = new Size(_defaultAutoHideSize, _defaultAutoHideSize); + _floatingSize = new Size(_defaultFloatingSize, _defaultFloatingSize); + _displayLocation = new Point(_defaultLocation, _defaultLocation); + _defaultRestore = new RestoreContentState(State.DockLeft, this); + _floatingRestore = new RestoreContentState(State.Floating, this); + _autoHideRestore = new RestoreAutoHideState(State.DockLeft, this); + _dockingRestore = _defaultRestore; + _autoHidePanel = null; + _tag = null; + _docked = true; + _captionBar = true; + _closeButton = true; + _hideButton = true; + _autoHidden = false; + _closeOnHide = false; + _fullTitle = title; + } + + public DockingManager DockingManager + { + get { return _manager; } + set { _manager = value; } + } + + public Control Control + { + get { return _control; } + + set + { + if (_control != value) + { + OnPropertyChanging(Property.Control); + _control = value; + OnPropertyChanged(Property.Control); + } + } + } + + public string Title + { + get { return _title; } + + set + { + if (_title != value) + { + OnPropertyChanging(Property.Title); + _title = value; + OnPropertyChanged(Property.Title); + } + } + } + + public string FullTitle + { + get { return _fullTitle; } + + set + { + if (_fullTitle != value) + { + OnPropertyChanging(Property.FullTitle); + _fullTitle = value; + OnPropertyChanged(Property.FullTitle); + } + } + } + + public ImageList ImageList + { + get { return _imageList; } + + set + { + if (_imageList != value) + { + OnPropertyChanging(Property.ImageList); + _imageList = value; + OnPropertyChanged(Property.ImageList); + } + } + } + + public int ImageIndex + { + get { return _imageIndex; } + + set + { + if (_imageIndex != value) + { + OnPropertyChanging(Property.ImageIndex); + _imageIndex = value; + OnPropertyChanged(Property.ImageIndex); + } + } + } + + public Icon Icon + { + get { return _icon; } + + set + { + if (_icon != value) + { + OnPropertyChanging(Property.Icon); + _icon = value; + OnPropertyChanged(Property.Icon); + } + } + } + + public bool CaptionBar + { + get { return _captionBar; } + + set + { + if (_captionBar != value) + { + OnPropertyChanging(Property.CaptionBar); + _captionBar = value; + OnPropertyChanged(Property.CaptionBar); + } + } + } + + public bool CloseButton + { + get { return _closeButton; } + + set + { + if (_closeButton != value) + { + OnPropertyChanging(Property.CloseButton); + _closeButton = value; + OnPropertyChanged(Property.CloseButton); + } + } + } + + public bool HideButton + { + get { return _hideButton; } + + set + { + if (_hideButton != value) + { + OnPropertyChanging(Property.HideButton); + _hideButton = value; + OnPropertyChanged(Property.HideButton); + } + } + } + + public Size DisplaySize + { + get { return _displaySize; } + + set + { + if (_displaySize != value) + { + OnPropertyChanging(Property.DisplaySize); + _displaySize = value; + OnPropertyChanged(Property.DisplaySize); + } + } + } + + public Size AutoHideSize + { + get { return _autoHideSize; } + + set + { + if (_autoHideSize != value) + { + OnPropertyChanging(Property.AutoHideSize); + _autoHideSize = value; + OnPropertyChanged(Property.AutoHideSize); + } + } + } + + public Size FloatingSize + { + get { return _floatingSize; } + + set + { + if (_floatingSize != value) + { + OnPropertyChanging(Property.FloatingSize); + _floatingSize = value; + OnPropertyChanged(Property.FloatingSize); + } + } + } + + public Point DisplayLocation + { + get { return _displayLocation; } + + set + { + if (_displayLocation != value) + { + OnPropertyChanging(Property.DisplayLocation); + _displayLocation = value; + OnPropertyChanged(Property.DisplayLocation); + } + } + } + + public int Order + { + get { return _order; } + } + + public bool CloseOnHide + { + get { return _closeOnHide; } + set { _closeOnHide = value; } + } + + public object Tag + { + get { return _tag; } + set { _tag = value; } + } + + public bool Visible + { + get { return _visible; } + } + + public Restore DefaultRestore + { + get { return _defaultRestore; } + set { _defaultRestore = value; } + } + + public Restore AutoHideRestore + { + get { return _autoHideRestore; } + set { _autoHideRestore = value; } + } + + public Restore DockingRestore + { + get { return _dockingRestore; } + set { _dockingRestore = value; } + } + + public Restore FloatingRestore + { + get { return _floatingRestore; } + set { _floatingRestore = value; } + } + + public bool Docked + { + get { return _docked; } + set { _docked = value; } + } + + public WindowContent ParentWindowContent + { + get { return _parentWindowContent; } + + set + { + if (_parentWindowContent != value) + { + _parentWindowContent = value; + + // Recalculate the visibility value + UpdateVisibility(); + } + } + } + + public AutoHidePanel AutoHidePanel + { + get { return _autoHidePanel; } + + set + { + if (_autoHidePanel != value) + { + _autoHidePanel = value; + + // Recalculate the visibility value + UpdateVisibility(); + } + } + } + + internal bool AutoHidden + { + get { return _autoHidden; } + + set + { + if (_autoHidden != value) + { + _autoHidden = value; + + // Recalculate the visibility value + UpdateVisibility(); + } + } + } + + public void UpdateVisibility() + { + _visible = ((_parentWindowContent != null) || (_autoHidden && (_autoHidePanel != null))); + } + + public virtual void OnPropertyChanging(Property prop) + { + // Any attached event handlers? + if (PropertyChanging != null) + PropertyChanging(this, prop); + } + + public virtual void OnPropertyChanged(Property prop) + { + // Any attached event handlers? + if (PropertyChanged != null) + PropertyChanged(this, prop); + } + + public void BringToFront() + { + if (!_visible) + { + // Use docking manager to ensure we are Visible + _manager.ShowContent(this); + } + + if (_autoHidden) + { + // Request docking manager bring to window into view + _manager.BringAutoHideIntoView(this); + } + else + { + // Ask the parent WindowContent to ensure we are the active Content + _parentWindowContent.BringContentToFront(this); + } + } + + public Restore RecordRestore() + { + if (_parentWindowContent != null) + { + if (_autoHidden) + return RecordAutoHideRestore(); + else + { + Form parentForm = _parentWindowContent.ParentZone.FindForm(); + + // Cannot record restore information if not in a Form + if (parentForm != null) + { + // Decide which restore actually needs recording + if (parentForm is FloatingForm) + return RecordFloatingRestore(); + else + return RecordDockingRestore(); + } + } + } + + return null; + } + + public Restore RecordAutoHideRestore() + { + // Remove any existing restore object + _autoHideRestore = null; + + // We should be inside a parent window + if (_parentWindowContent != null) + { + // And in the auto hidden state + if (_autoHidden) + { + // Get access to the AutoHostPanel that contains use + AutoHidePanel ahp = _parentWindowContent.DockingManager.AutoHidePanelForContent(this); + + // Request the ahp create a relevant restore object for us + _autoHideRestore = ahp.RestoreObjectForContent(this); + } + } + + return _autoHideRestore; + } + + public Restore RecordDockingRestore() + { + // Remove any existing Restore object + _dockingRestore = null; + + // Do we have a parent window we are inside? + if (_parentWindowContent != null) + { + // Ask the parent to provide a Restore object for us + _dockingRestore = _parentWindowContent.RecordRestore(this); + } + + // If we cannot get a valid Restore object from the parent then we have no choice + // but to use the default restore which is less accurate but better than nothing + if (_dockingRestore == null) + _dockingRestore = _defaultRestore; + + return _dockingRestore; + } + + public Restore RecordFloatingRestore() + { + // Remove any existing Restore object + _floatingRestore = null; + + // Do we have a parent window we are inside? + if (_parentWindowContent != null) + { + // Ask the parent to provide a Restore object for us + _floatingRestore = _parentWindowContent.RecordRestore(this); + } + + // If we cannot get a valid Restore object from the parent then we have no choice + // but to use the default restore which is less accurate but better than nothing + if (_floatingRestore == null) + _floatingRestore = _defaultRestore; + + return _floatingRestore; + } + + internal void ContentBecomesFloating() + { + _docked = false; + + if (_parentWindowContent != null) + { + switch (_parentWindowContent.State) + { + case State.DockLeft: + case State.DockRight: + case State.DockTop: + case State.DockBottom: + // Record the current position before content is moved + RecordDockingRestore(); + break; + + case State.Floating: + default: + // Do nothing, already floating + break; + } + } + } + + internal void ContentLeavesFloating() + { + _docked = true; + + if (_parentWindowContent != null) + { + switch (_parentWindowContent.State) + { + case State.DockLeft: + case State.DockRight: + case State.DockTop: + case State.DockBottom: + // Do nothing, already floating + break; + + case State.Floating: + default: + // Record the current position before content is moved + RecordFloatingRestore(); + break; + } + } + } + + internal void ReconnectRestore() + { + _defaultRestore.Reconnect(_manager); + _autoHideRestore.Reconnect(_manager); + _dockingRestore.Reconnect(_manager); + _floatingRestore.Reconnect(_manager); + } + + internal void SaveToXml(XmlTextWriter xmlOut) + { + // Output standard values appropriate for all Content + xmlOut.WriteStartElement("Content"); + xmlOut.WriteAttributeString("Name", _title); + xmlOut.WriteAttributeString("Visible", _visible.ToString()); + xmlOut.WriteAttributeString("Docked", _docked.ToString()); + xmlOut.WriteAttributeString("AutoHidden", _autoHidden.ToString()); + xmlOut.WriteAttributeString("CaptionBar", _captionBar.ToString()); + xmlOut.WriteAttributeString("CloseButton", _closeButton.ToString()); + xmlOut.WriteAttributeString("DisplaySize", ConversionHelper.SizeToString(_displaySize)); + xmlOut.WriteAttributeString("DisplayLocation", ConversionHelper.PointToString(_displayLocation)); + xmlOut.WriteAttributeString("AutoHideSize", ConversionHelper.SizeToString(_autoHideSize)); + xmlOut.WriteAttributeString("FloatingSize", ConversionHelper.SizeToString(_floatingSize)); + xmlOut.WriteAttributeString("FullTitle", _fullTitle); + + // Save the Default Restore object to Xml + xmlOut.WriteStartElement("DefaultRestore"); + _defaultRestore.SaveToXml(xmlOut); + xmlOut.WriteEndElement(); + + // Save the AutoHideRestore object to Xml + xmlOut.WriteStartElement("AutoHideRestore"); + _autoHideRestore.SaveToXml(xmlOut); + xmlOut.WriteEndElement(); + + // Save the DockingRestore object to Xml + xmlOut.WriteStartElement("DockingRestore"); + _dockingRestore.SaveToXml(xmlOut); + xmlOut.WriteEndElement(); + + // Save the floating Restore object to Xml + xmlOut.WriteStartElement("FloatingRestore"); + _floatingRestore.SaveToXml(xmlOut); + xmlOut.WriteEndElement(); + + xmlOut.WriteEndElement(); + } + + internal void LoadFromXml(XmlTextReader xmlIn, int formatVersion) + { + // Read in the attribute values + string attrTitle = xmlIn.GetAttribute(0); + string attrVisible = xmlIn.GetAttribute(1); + string attrDocked = xmlIn.GetAttribute(2); + string attrAutoHide = xmlIn.GetAttribute(3); + string attrCaptionBar = xmlIn.GetAttribute(4); + string attrCloseButton = xmlIn.GetAttribute(5); + string attrDisplaySize = xmlIn.GetAttribute(6); + string attrDisplayLocation = xmlIn.GetAttribute(7); + string attrAutoHideSize = xmlIn.GetAttribute(8); + string attrFloatingSize = xmlIn.GetAttribute(9); + string attrFullTitle = attrTitle; + + // 'FullTitle' property added in version 5 format and above + if (formatVersion >= 5) + attrFullTitle = xmlIn.GetAttribute(10); + + // Convert to correct types + _title = attrTitle; + _visible = Convert.ToBoolean(attrVisible); + _docked = Convert.ToBoolean(attrDocked); + _autoHidden = Convert.ToBoolean(attrAutoHide); + _captionBar = Convert.ToBoolean(attrCaptionBar); + _closeButton = Convert.ToBoolean(attrCloseButton); + _displaySize = ConversionHelper.StringToSize(attrDisplaySize); + _displayLocation = ConversionHelper.StringToPoint(attrDisplayLocation); + _autoHideSize = ConversionHelper.StringToSize(attrAutoHideSize); + _floatingSize = ConversionHelper.StringToSize(attrFloatingSize); + _fullTitle = attrFullTitle; + + // Load the Restore objects + _defaultRestore = Restore.CreateFromXml(xmlIn, true, formatVersion); + _autoHideRestore = Restore.CreateFromXml(xmlIn, true, formatVersion); + _dockingRestore = Restore.CreateFromXml(xmlIn, true, formatVersion); + _floatingRestore = Restore.CreateFromXml(xmlIn, true, formatVersion); + + // 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"); + } + } +} \ No newline at end of file diff --git a/Labyrinth3/Crownwood.Magic/Docking/Definitions.cs b/Labyrinth3/Crownwood.Magic/Docking/Definitions.cs new file mode 100644 index 0000000..715a941 --- /dev/null +++ b/Labyrinth3/Crownwood.Magic/Docking/Definitions.cs @@ -0,0 +1,50 @@ +// ***************************************************************************** +// +// (c) Crownwood Consulting Limited 2002-2003 +// All rights reserved. The software and associated documentation +// supplied hereunder are the proprietary information of Crownwood Consulting +// Limited, Crownwood, Bracknell, Berkshire, England and are supplied subject +// to licence terms. +// +// Magic Version 1.7.4.0 www.dotnetmagic.com +// ***************************************************************************** + +using Crownwood.Magic.Collections; +using Crownwood.Magic.Common; +using System; +using System.Drawing; + +namespace Crownwood.Magic.Docking +{ + public enum State + { + Floating, + DockTop, + DockBottom, + DockLeft, + DockRight + } + + public interface IHotZoneSource + { + void AddHotZones(Redocker redock, HotZoneCollection collection); + } + + public interface IZoneMaximizeWindow + { + Direction Direction { get; } + + bool IsMaximizeAvailable(); + + bool IsWindowMaximized(Window w); + + void MaximizeWindow(Window w); + + void RestoreWindow(); + + event EventHandler RefreshMaximize; + } + + // Delegate signatures + public delegate void ContextHandler(Point screenPos); +} \ No newline at end of file diff --git a/Labyrinth3/Crownwood.Magic/Docking/DockingManager.cs b/Labyrinth3/Crownwood.Magic/Docking/DockingManager.cs new file mode 100644 index 0000000..8275ece --- /dev/null +++ b/Labyrinth3/Crownwood.Magic/Docking/DockingManager.cs @@ -0,0 +1,2027 @@ +// ***************************************************************************** +// +// (c) Crownwood Consulting Limited 2002-2003 +// All rights reserved. The software and associated documentation +// supplied hereunder are the proprietary information of Crownwood Consulting +// Limited, Crownwood, Bracknell, Berkshire, England and are supplied subject +// to licence terms. +// +// Magic Version 1.7.4.0 www.dotnetmagic.com +// ***************************************************************************** + +using Crownwood.Magic.Collections; +using Crownwood.Magic.Common; +using Crownwood.Magic.Menus; +using Microsoft.Win32; +using System; +using System.ComponentModel; +using System.Drawing; +using System.IO; +using System.Text; +using System.Windows.Forms; +using System.Xml; + +namespace Crownwood.Magic.Docking +{ + public enum PropogateName + { + BackColor, + ActiveColor, + ActiveTextColor, + InactiveTextColor, + ResizeBarColor, + ResizeBarVector, + CaptionFont, + TabControlFont, + ZoneMinMax, + PlainTabBorder + } + + public class DockingManager + { + // Instance fields + protected bool _zoneMinMax; + + protected bool _insideFill; + protected bool _autoResize; + protected bool _firstHalfWidth; + protected bool _firstHalfHeight; + protected int _surpressVisibleEvents; + protected int _resizeBarVector; + protected Size _innerMinimum; + protected Color _backColor; + protected Color _activeColor; + protected Color _activeTextColor; + protected Color _inactiveTextColor; + protected Color _resizeBarColor; + protected Font _captionFont; + protected Font _tabControlFont; + protected bool _defaultBackColor; + protected bool _defaultActiveColor; + protected bool _defaultActiveTextColor; + protected bool _defaultInactiveTextColor; + protected bool _defaultResizeBarColor; + protected bool _defaultCaptionFont; + protected bool _defaultTabControlFont; + protected bool _plainTabBorder; + protected Control _innerControl; + protected Control _outerControl; + protected AutoHidePanel _ahpTop; + protected AutoHidePanel _ahpLeft; + protected AutoHidePanel _ahpBottom; + protected AutoHidePanel _ahpRight; + protected VisualStyle _visualStyle; + protected ContainerControl _container; + protected ManagerContentCollection _contents; + + public delegate void ContentHandler(Content c, EventArgs cea); + + public delegate void ContentHidingHandler(Content c, CancelEventArgs cea); + + public delegate void ContextMenuHandler(PopupMenu pm, CancelEventArgs cea); + + public delegate void TabControlCreatedHandler(Magic.Controls.TabControl tabControl); + + public delegate void SaveCustomConfigHandler(XmlTextWriter xmlOut); + + public delegate void LoadCustomConfigHandler(XmlTextReader xmlIn); + + // Exposed events + public event ContentHandler ContentShown; + + public event ContentHandler ContentHidden; + + public event ContentHidingHandler ContentHiding; + + public event ContextMenuHandler ContextMenu; + + public event TabControlCreatedHandler TabControlCreated; + + public event SaveCustomConfigHandler SaveCustomConfig; + + public event LoadCustomConfigHandler LoadCustomConfig; + + public DockingManager(ContainerControl container, VisualStyle vs) + { + // Must provide a valid container instance + if (container == null) + throw new ArgumentNullException("Container"); + + // Default state + _container = container; + _visualStyle = vs; + _innerControl = null; + _zoneMinMax = true; + _insideFill = false; + _autoResize = true; + _firstHalfWidth = true; + _firstHalfHeight = true; + _plainTabBorder = false; + _surpressVisibleEvents = 0; + _innerMinimum = new Size(20, 20); + + // Default font/resize + _resizeBarVector = -1; + _captionFont = SystemInformation.MenuFont; + _tabControlFont = SystemInformation.MenuFont; + _defaultCaptionFont = true; + _defaultTabControlFont = true; + + // Create and add hidden auto hide panels + AddAutoHidePanels(); + + // Define initial colors + ResetColors(); + + // Create an object to manage the collection of Content + _contents = new ManagerContentCollection(this); + + // We want notification when contents are removed/cleared + _contents.Clearing += new CollectionClear(OnContentsClearing); + _contents.Removed += new CollectionChange(OnContentRemoved); + + // We want to perform special action when container is resized + _container.Resize += new EventHandler(OnContainerResized); + + // A Form can cause the child controls to be reordered after the initialisation + // but before the Form.Load event. To handle this we hook into the event and force + // the auto hide panels to be ordered back into their proper place. + if (_container is Form) + { + Form formContainer = _container as Form; + formContainer.Load += new EventHandler(OnFormLoaded); + } + + // Need notification when colors change + Microsoft.Win32.SystemEvents.UserPreferenceChanged += new UserPreferenceChangedEventHandler(OnPreferenceChanged); + } + + public ContainerControl Container + { + get { return _container; } + } + + public Control InnerControl + { + get { return _innerControl; } + set { _innerControl = value; } + } + + public Control OuterControl + { + get { return _outerControl; } + set + { + if (_outerControl != value) + { + _outerControl = value; + + // Use helper routine to ensure panels are in correct positions + ReorderAutoHidePanels(); + } + } + } + + public ManagerContentCollection Contents + { + get { return _contents; } + + set + { + _contents.Clear(); + _contents = value; + } + } + + public bool ZoneMinMax + { + get { return _zoneMinMax; } + + set + { + if (value != _zoneMinMax) + { + _zoneMinMax = value; + + // Notify each object in docking hierarchy in case they need to know new value + PropogateNameValue(PropogateName.ZoneMinMax, (object)_zoneMinMax); + } + } + } + + public bool InsideFill + { + get { return _insideFill; } + + set + { + if (_insideFill != value) + { + _insideFill = value; + + if (_insideFill) + { + // Add Fill style to innermost docking window + AddInnerFillStyle(); + } + else + { + // Remove Fill style from innermost docking window + RemoveAnyFillStyle(); + + // Ensure that inner control can be seen + OnContainerResized(null, EventArgs.Empty); + } + } + } + } + + public bool AutoResize + { + get { return _autoResize; } + set { _autoResize = value; } + } + + public Size InnerMinimum + { + get { return _innerMinimum; } + set { _innerMinimum = value; } + } + + public VisualStyle Style + { + get { return _visualStyle; } + } + + public int ResizeBarVector + { + get { return _resizeBarVector; } + + set + { + if (value != _resizeBarVector) + { + _resizeBarVector = value; + + // Notify each object in docking hierarchy in case they need to know new value + PropogateNameValue(PropogateName.ResizeBarVector, (object)_resizeBarVector); + } + } + } + + public Color BackColor + { + get { return _backColor; } + + set + { + if (value != _backColor) + { + _backColor = value; + _defaultBackColor = (_backColor == SystemColors.Control); + + // Notify each object in docking hierarchy in case they need to know new value + PropogateNameValue(PropogateName.BackColor, (object)_backColor); + } + } + } + + public Color ActiveColor + { + get { return _activeColor; } + + set + { + if (value != _activeColor) + { + _activeColor = value; + _defaultActiveColor = (_activeColor == SystemColors.ActiveCaption); + + // Notify each object in docking hierarchy in case they need to know new value + PropogateNameValue(PropogateName.ActiveColor, (object)_activeColor); + } + } + } + + public Color ActiveTextColor + { + get { return _activeTextColor; } + + set + { + if (value != _activeTextColor) + { + _activeTextColor = value; + _defaultActiveTextColor = (_activeTextColor == SystemColors.ActiveCaptionText); + + // Notify each object in docking hierarchy in case they need to know new value + PropogateNameValue(PropogateName.ActiveTextColor, (object)_activeTextColor); + } + } + } + + public Color InactiveTextColor + { + get { return _inactiveTextColor; } + + set + { + if (value != _inactiveTextColor) + { + _inactiveTextColor = value; + _defaultInactiveTextColor = (_inactiveTextColor == SystemColors.ControlText); + + // Notify each object in docking hierarchy in case they need to know new value + PropogateNameValue(PropogateName.InactiveTextColor, (object)_inactiveTextColor); + } + } + } + + public Color ResizeBarColor + { + get { return _resizeBarColor; } + + set + { + if (value != _resizeBarColor) + { + _resizeBarColor = value; + _defaultResizeBarColor = (_resizeBarColor == SystemColors.Control); + + // Notify each object in docking hierarchy in case they need to know new value + PropogateNameValue(PropogateName.ResizeBarColor, (object)_resizeBarColor); + } + } + } + + public Font CaptionFont + { + get { return _captionFont; } + + set + { + if (value != _captionFont) + { + _captionFont = value; + _defaultCaptionFont = (_captionFont == SystemInformation.MenuFont); + + // Notify each object in docking hierarchy in case they need to know new value + PropogateNameValue(PropogateName.CaptionFont, (object)_captionFont); + } + } + } + + public Font TabControlFont + { + get { return _tabControlFont; } + + set + { + if (value != _tabControlFont) + { + _tabControlFont = value; + _defaultTabControlFont = (_captionFont == SystemInformation.MenuFont); + + // Notify each object in docking hierarchy in case they need to know new value + PropogateNameValue(PropogateName.TabControlFont, (object)_tabControlFont); + } + } + } + + public bool PlainTabBorder + { + get { return _plainTabBorder; } + + set + { + if (value != _plainTabBorder) + { + _plainTabBorder = value; + + // Notify each object in docking hierarchy in case they need to know new value + PropogateNameValue(PropogateName.PlainTabBorder, (object)_plainTabBorder); + } + } + } + + public void ResetColors() + { + _backColor = SystemColors.Control; + _inactiveTextColor = SystemColors.ControlText; + _activeColor = SystemColors.ActiveCaption; + _activeTextColor = SystemColors.ActiveCaptionText; + _resizeBarColor = SystemColors.Control; + _defaultBackColor = true; + _defaultActiveColor = true; + _defaultActiveTextColor = true; + _defaultInactiveTextColor = true; + _defaultResizeBarColor = true; + + PropogateNameValue(PropogateName.BackColor, (object)_backColor); + PropogateNameValue(PropogateName.ActiveColor, (object)_activeColor); + PropogateNameValue(PropogateName.ActiveTextColor, (object)_activeTextColor); + PropogateNameValue(PropogateName.InactiveTextColor, (object)_inactiveTextColor); + PropogateNameValue(PropogateName.ResizeBarColor, (object)_resizeBarColor); + } + + public void UpdateInsideFill() + { + // Is inside fill ability enabled? + if (_insideFill) + { + // Reduce flicker + _container.SuspendLayout(); + + // Ensure correct zone has the Fill style + RemoveAnyFillStyle(); + AddInnerFillStyle(); + + _container.ResumeLayout(); + } + } + + public virtual bool ToggleContentAutoHide(Content c) + { + // Content must be visible + if (!c.Visible) + return false; + + // Content is not allows to be floating + // (if visible then content must have a valiud ParentWindowContent) + if (c.ParentWindowContent.State == State.Floating) + return false; + + // Is the content currently in auto hide mode? + if (c.ParentWindowContent.ParentZone == null) + { + // Find the hosting panel for the window content instance + AutoHidePanel ahp = AutoHidePanelForState(c.ParentWindowContent.State); + + // Ask the panel to un-autohide + ahp.InvertAutoHideWindowContent(c.ParentWindowContent as WindowContentTabbed); + } + else + { + // No, so inform the window content to become auto hidden now + InvertAutoHideWindowContent(c.ParentWindowContent); + } + + // Success! + return true; + } + + public virtual bool ShowContent(Content c) + { + // Validate the incoming Content instance is a valid reference + // and is a current instance within our internal collection + if ((c == null) || !_contents.Contains(c)) + return false; + + // Remove it from view by removing from current WindowContent container + if (!c.Visible) + { + // Do not generate hiding/hidden/shown events + _surpressVisibleEvents++; + + // Manageing Zones should remove display AutoHide windows + RemoveShowingAutoHideWindows(); + + // Use the assigned restore object to position the Content appropriately + if (c.Docked) + { + if (c.AutoHidden) + c.AutoHideRestore.PerformRestore(this); + else + c.DockingRestore.PerformRestore(this); + } + else + c.FloatingRestore.PerformRestore(this); + + // Enable generation hiding/hidden/shown events + _surpressVisibleEvents--; + + // Generate event + OnContentShown(c); + + return true; + } + else + return false; + } + + public virtual void ShowAllContents() + { + _container.SuspendLayout(); + + foreach (Content c in _contents) + ShowContent(c); + + UpdateInsideFill(); + + _container.ResumeLayout(); + } + + public virtual void HideContent(Content c) + { + HideContent(c, true, true); + } + + public virtual void HideContent(Content c, bool record, bool reorder) + { + // Remove it from view by removing from current WindowContent container + if (c.Visible) + { + // Do not generate hiding/hidden/shown events + _surpressVisibleEvents++; + + // Manageing Zones should remove display AutoHide windows + RemoveShowingAutoHideWindows(); + + if (record) + { + // Tell the Content to create a new Restore object to record its current location + c.RecordRestore(); + } + + if (c.AutoHidden) + { + // Remove it from its current AutoHidePanel + c.AutoHidePanel.RemoveContent(c); + } + else + { + // Remove the Content from its current WindowContent + c.ParentWindowContent.Contents.Remove(c); + } + + if (reorder) + { + // Move the Content to the start of the list + _contents.SetIndex(0, c); + } + + UpdateInsideFill(); + + // Enable generation hiding/hidden/shown events + _surpressVisibleEvents--; + + // Generate event + OnContentHidden(c); + } + } + + public virtual void HideAllContents() + { + _container.SuspendLayout(); + + int count = _contents.Count; + + // Hide in reverse order so that a ShowAll in forward order gives accurate restore + for (int index = count - 1; index >= 0; index--) + { + // Cannot hide something already hidden + if (_contents[index].Visible) + { + // Generate event + if (!OnContentHiding(_contents[index])) + { + HideContent(_contents[index], true, false); + } + } + } + + UpdateInsideFill(); + + _container.ResumeLayout(); + } + + public virtual Window CreateWindowForContent(Content c) + { + return CreateWindowForContent(c, new EventHandler(OnContentClose), + new EventHandler(OnRestore), + new EventHandler(OnInvertAutoHide), + new ContextHandler(OnShowContextMenu)); + } + + public virtual Window CreateWindowForContent(Content c, + EventHandler contentClose, + EventHandler restore, + EventHandler invertAutoHide, + ContextHandler showContextMenu) + { + // Create new instance with correct style + WindowContent wc = new WindowContentTabbed(this, _visualStyle); + + WindowDetailCaption wdc; + + // Create a style specific caption detail + if (_visualStyle == VisualStyle.IDE) + wdc = new WindowDetailCaptionIDE(this, contentClose, restore, + invertAutoHide, showContextMenu); + else + wdc = new WindowDetailCaptionPlain(this, contentClose, restore, + invertAutoHide, showContextMenu); + + // Add the caption to the window display + wc.WindowDetails.Add(wdc); + + if (c != null) + { + // Add provided Content to this instance + wc.Contents.Add(c); + } + + return wc; + } + + public virtual Zone CreateZoneForContent(State zoneState) + { + return CreateZoneForContent(zoneState, _container); + } + + protected virtual Zone CreateZoneForContent(State zoneState, ContainerControl destination) + { + DockStyle ds; + Direction direction; + + // Find relevant values dependant on required state + ValuesFromState(zoneState, out ds, out direction); + + // Create a new ZoneSequence which can host Content + ZoneSequence zs = new ZoneSequence(this, zoneState, _visualStyle, direction, _zoneMinMax); + + // Set the appropriate docking style + zs.Dock = ds; + + if (destination != null) + { + // Add this Zone to the display + destination.Controls.Add(zs); + } + + return zs; + } + + public WindowContent AddContentWithState(Content c, State newState) + { + // Validate the incoming Content instance is a valid reference + // and is a current instance within our internal collection + if ((c == null) || !_contents.Contains(c)) + return null; + + // Do not generate hiding/hidden/shown events + _surpressVisibleEvents++; + + // Manageing Zones should remove display AutoHide windows + RemoveShowingAutoHideWindows(); + + // Is the window already part of a WindowContent? + if (c.ParentWindowContent != null) + { + // If it used to be in a floating mode, then record state change + if (c.ParentWindowContent.ParentZone.State == State.Floating) + c.ContentLeavesFloating(); + + // Remove the Content from its current WindowContent + c.ParentWindowContent.Contents.Remove(c); + } + + // Create a new Window instance appropriate for hosting a Content object + Window w = CreateWindowForContent(c); + + ContainerControl destination = null; + + if (newState != State.Floating) + { + destination = _container; + destination.SuspendLayout(); + } + + // Create a new Zone capable of hosting a WindowContent + Zone z = CreateZoneForContent(newState, destination); + + if (newState == State.Floating) + { + // Content is not in the docked state + c.Docked = false; + + // destination a new floating form + destination = new FloatingForm(this, z, new ContextHandler(OnShowContextMenu)); + + // Define its location + destination.Location = c.DisplayLocation; + + // ...and its size, add the height of the caption bar to the requested content size + destination.Size = new Size(c.FloatingSize.Width, + c.FloatingSize.Height + SystemInformation.ToolWindowCaptionHeight); + } + + // Add the Window to the Zone + z.Windows.Add(w); + + if (newState != State.Floating) + { + // Set the Zone to be the least important of our Zones + ReorderZoneToInnerMost(z); + + UpdateInsideFill(); + + destination.ResumeLayout(); + } + else + destination.Show(); + + // Enable generation hiding/hidden/shown events + _surpressVisibleEvents--; + + // Generate event to indicate content is now visible + OnContentShown(c); + + return w as WindowContent; + } + + public WindowContent AddContentToWindowContent(Content c, WindowContent wc) + { + // Validate the incoming Content instance is a valid reference + // and is a current instance within our internal collection + if ((c == null) || !_contents.Contains(c)) + return null; + + // Validate the incoming WindowContent instance is a valid reference + if (wc == null) + return null; + + // Is Content already part of given Window then nothing to do + if (c.ParentWindowContent == wc) + return wc; + else + { + bool valid = true; + + // Do not generate hiding/hidden/shown events + _surpressVisibleEvents++; + + // Manageing Zones should remove display AutoHide windows + RemoveShowingAutoHideWindows(); + + if (c.ParentWindowContent != null) + { + // Is there a change in docking state? + if (c.ParentWindowContent.ParentZone.State != wc.ParentZone.State) + { + // If it used to be in a floating mode, then record state change + if (c.ParentWindowContent.ParentZone.State == State.Floating) + c.ContentLeavesFloating(); + else + c.ContentBecomesFloating(); + } + + // Remove the Content from its current WindowContent + c.ParentWindowContent.Contents.Remove(c); + } + else + { + // If a window content is in AutoHide then it will not have a parent zone + if (wc.ParentZone != null) + { + // If adding to a floating window then it is not docked + if (wc.ParentZone.State == State.Floating) + c.Docked = false; + } + else + { + // Cannot dynamically add into an autohide parent + valid = false; + } + } + + if (valid) + { + // Add the existing Content to this instance + wc.Contents.Add(c); + } + + // Enable generation hiding/hidden/shown events + _surpressVisibleEvents--; + + if (valid) + { + // Generate event to indicate content is now visible + OnContentShown(c); + } + + return wc; + } + } + + public Window AddContentToZone(Content c, Zone z, int index) + { + // Validate the incoming Content instance is a valid reference + // and is a current instance within our internal collection + if ((c == null) || !_contents.Contains(c)) + return null; + + // Validate the incoming Zone instance is a valid reference + if (z == null) + return null; + + // Do not generate hiding/hidden/shown events + _surpressVisibleEvents++; + + // Manageing Zones should remove display AutoHide windows + RemoveShowingAutoHideWindows(); + + // Is the window already part of a WindowContent? + if (c.ParentWindowContent != null) + { + // Is there a change in docking state? + if (c.ParentWindowContent.ParentZone.State != z.State) + { + // If it used to be in a floating mode, then record state change + if (c.ParentWindowContent.ParentZone.State == State.Floating) + c.ContentLeavesFloating(); + else + c.ContentBecomesFloating(); + } + + // Remove the Content from its current WindowContent + c.ParentWindowContent.Contents.Remove(c); + } + else + { + // If target zone is floating window then we are no longer docked + if (z.State == State.Floating) + c.Docked = false; + } + + // Create a new WindowContent instance according to our style + Window w = CreateWindowForContent(c); + + // Add the Window to the Zone at given position + z.Windows.Insert(index, w); + + // Enable generation hiding/hidden/shown events + _surpressVisibleEvents--; + + // Generate event to indicate content is now visible + OnContentShown(c); + + return w; + } + + public Rectangle InnerResizeRectangle(Control source) + { + // Start with a rectangle that represents the entire client area + Rectangle client = _container.ClientRectangle; + + int count = _container.Controls.Count; + int inner = _container.Controls.IndexOf(_innerControl); + int sourceIndex = _container.Controls.IndexOf(source); + + // Process each control outside the inner control + for (int index = count - 1; index > inner; index--) + { + Control item = _container.Controls[index]; + + bool insideSource = (index < sourceIndex); + + switch (item.Dock) + { + case DockStyle.Left: + client.Width -= item.Width; + client.X += item.Width; + + if (insideSource) + client.Width -= item.Width; + break; + + case DockStyle.Right: + client.Width -= item.Width; + + if (insideSource) + { + client.Width -= item.Width; + client.X += item.Width; + } + break; + + case DockStyle.Top: + client.Height -= item.Height; + client.Y += item.Height; + + if (insideSource) + client.Height -= item.Height; + break; + + case DockStyle.Bottom: + client.Height -= item.Height; + + if (insideSource) + { + client.Height -= item.Height; + client.Y += item.Height; + } + break; + + case DockStyle.Fill: + case DockStyle.None: + break; + } + } + + return client; + } + + public void ReorderZoneToInnerMost(Zone zone) + { + int index = 0; + + // If there is no control specified as the one for all Zones to be placed + // in front of then simply add the Zone at the start of the list so it is + // in front of all controls. + if (_innerControl != null) + { + // Find position of specified control and place after it in the list + // (hence adding one to the returned value) + index = _container.Controls.IndexOf(_innerControl) + 1; + } + + // Find current position of the Zone to be repositioned + int current = _container.Controls.IndexOf(zone); + + // If the old position is before the new position then we need to + // subtract one. As the collection will remove the Control from the + // old position before inserting it in the new, thus reducing the index + // by 1 before the insert occurs. + if (current < index) + index--; + + // Found a Control that is not a Zone, so need to insert straight it + _container.Controls.SetChildIndex(zone, index); + + // Manageing Zones should remove display AutoHide windows + RemoveShowingAutoHideWindows(); + } + + public void ReorderZoneToOuterMost(Zone zone) + { + // Get index of the outer control (minus AutoHidePanel's) + int index = OuterControlIndex(); + + // Find current position of the Zone to be repositioned + int current = _container.Controls.IndexOf(zone); + + // If the old position is before the new position then we need to + // subtract one. As the collection will remove the Control from the + // old position before inserting it in the new, thus reducing the index + // by 1 before the insert occurs. + if (current < index) + index--; + + // Found a Control that is not a Zone, so need to insert straight it + _container.Controls.SetChildIndex(zone, index); + + // Manageing Zones should remove display AutoHide windows + RemoveShowingAutoHideWindows(); + } + + public int OuterControlIndex() + { + int index = _container.Controls.Count; + + // If there is no control specified as the one for all Zones to be placed behind + // then simply add the Zone at the end of the list so it is behind all controls. + if (_outerControl != null) + { + // Find position of specified control and place before it in the list + index = _container.Controls.IndexOf(_outerControl); + } + + // Adjust backwards to prevent being after any AutoHidePanels + for (; index > 0; index--) + if (!(_container.Controls[index - 1] is AutoHidePanel)) + break; + + return index; + } + + public void RemoveShowingAutoHideWindows() + { + _ahpLeft.RemoveShowingWindow(); + _ahpRight.RemoveShowingWindow(); + _ahpTop.RemoveShowingWindow(); + _ahpBottom.RemoveShowingWindow(); + } + + internal void RemoveShowingAutoHideWindowsExcept(AutoHidePanel except) + { + if (except != _ahpLeft) + _ahpLeft.RemoveShowingWindow(); + + if (except != _ahpRight) + _ahpRight.RemoveShowingWindow(); + + if (except != _ahpTop) + _ahpTop.RemoveShowingWindow(); + + if (except != _ahpBottom) + _ahpBottom.RemoveShowingWindow(); + } + + public void BringAutoHideIntoView(Content c) + { + if (_ahpLeft.ContainsContent(c)) + _ahpLeft.BringContentIntoView(c); + + if (_ahpRight.ContainsContent(c)) + _ahpRight.BringContentIntoView(c); + + if (_ahpTop.ContainsContent(c)) + _ahpTop.BringContentIntoView(c); + + if (_ahpBottom.ContainsContent(c)) + _ahpBottom.BringContentIntoView(c); + } + + public void ValuesFromState(State newState, out DockStyle dockState, out Direction direction) + { + switch (newState) + { + case State.Floating: + dockState = DockStyle.Fill; + direction = Direction.Vertical; + break; + + case State.DockTop: + dockState = DockStyle.Top; + direction = Direction.Horizontal; + break; + + case State.DockBottom: + dockState = DockStyle.Bottom; + direction = Direction.Horizontal; + break; + + case State.DockRight: + dockState = DockStyle.Right; + direction = Direction.Vertical; + break; + + case State.DockLeft: + default: + dockState = DockStyle.Left; + direction = Direction.Vertical; + break; + } + } + + 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(" Magic, The User Interface library for .NET (www.dotnetmagic.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("DockingConfig"); + xmlOut.WriteAttributeString("FormatVersion", "5"); + xmlOut.WriteAttributeString("InsideFill", _insideFill.ToString()); + xmlOut.WriteAttributeString("InnerMinimum", ConversionHelper.SizeToString(_innerMinimum)); + + // We need to hide all content during the saving process, but then restore + // them back again before leaving so the user does not see any change + _container.SuspendLayout(); + + // Store a list of those content hidden during processing + ContentCollection hideContent = new ContentCollection(); + + // Let create a copy of the current contents in current order, because + // we cannot 'foreach' a collection that is going to be altered during its + // processing by the 'HideContent'. + ContentCollection origContents = _contents.Copy(); + + // Do not generate hiding/hidden/shown events + _surpressVisibleEvents++; + + int count = origContents.Count; + + // Hide in reverse order so that a ShowAll in forward order gives accurate restore + for (int index = count - 1; index >= 0; index--) + { + Content c = origContents[index]; + + c.RecordRestore(); + c.SaveToXml(xmlOut); + + // If visible then need to hide so that subsequent attempts to + // RecordRestore will not take its position into account + if (c.Visible) + { + hideContent.Insert(0, c); + HideContent(c); + } + } + + // Allow an event handler a chance to add custom information after ours + OnSaveCustomConfig(xmlOut); + + // Put content we hide back again + foreach (Content c in hideContent) + ShowContent(c); + + // Enable generation of hiding/hidden/shown events + _surpressVisibleEvents--; + + // Reapply any fill style required + AddInnerFillStyle(); + + _container.ResumeLayout(); + + // Terminate the root element and document + xmlOut.WriteEndElement(); + xmlOut.WriteEndDocument(); + + // This should flush all actions and close the file + xmlOut.Close(); + } + + 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 != "DockingConfig") + throw new ArgumentException("Root element must be 'DockingConfig'"); + + // Load the format version number + string version = xmlIn.GetAttribute(0); + string insideFill = xmlIn.GetAttribute(1); + string innerSize = xmlIn.GetAttribute(2); + + // Convert format version from string to double + int formatVersion = (int)Convert.ToDouble(version); + + // We can only load 3 upward version formats + if (formatVersion < 3) + throw new ArgumentException("Can only load Version 3 and upwards Docking Configuration files"); + + // Convert from string to proper types + _insideFill = (bool)Convert.ToBoolean(insideFill); + _innerMinimum = ConversionHelper.StringToSize(innerSize); + + ContentCollection cc = new ContentCollection(); + + do + { + // Read the next Element + if (!xmlIn.Read()) + throw new ArgumentException("An element was expected but could not be read in"); + + // Have we reached the end of root element? + if ((xmlIn.NodeType == XmlNodeType.EndElement) && (xmlIn.Name == "DockingConfig")) + break; + + // Is the element name 'Content' + if (xmlIn.Name == "Content") + { + // Process this Content element + cc.Insert(0, new Content(xmlIn, formatVersion)); + } + else + { + // Must have reached end of our code, let the custom handler deal with this + OnLoadCustomConfig(xmlIn); + + // Ignore anything else that might be in the XML + xmlIn.Close(); + + // Exit + break; + } + } while (!xmlIn.EOF); + + xmlIn.Close(); + + // Reduce flicker during window operations + _container.SuspendLayout(); + + // Hide all the current content items + HideAllContents(); + + // Attempt to apply loaded settings + foreach (Content loaded in cc) + { + Content c = _contents[loaded.Title]; + + // Do we have any loaded information for this item? + if (c != null) + { + // Copy across the loaded values of interest + c.Docked = loaded.Docked; + c.AutoHidden = loaded.AutoHidden; + c.CaptionBar = loaded.CaptionBar; + c.CloseButton = loaded.CloseButton; + c.DisplaySize = loaded.DisplaySize; + c.DisplayLocation = loaded.DisplayLocation; + c.AutoHideSize = loaded.AutoHideSize; + c.FloatingSize = loaded.FloatingSize; + c.DefaultRestore = loaded.DefaultRestore; + c.AutoHideRestore = loaded.AutoHideRestore; + c.DockingRestore = loaded.DockingRestore; + c.FloatingRestore = loaded.FloatingRestore; + + // Allow the Restore objects a chance to rehook into object instances + c.ReconnectRestore(); + + // Was the loaded item visible? + if (loaded.Visible) + { + // Make it visible now + ShowContent(c); + } + } + } + + // Reapply any fill style required + AddInnerFillStyle(); + + // Reduce flicker during window operations + _container.ResumeLayout(); + + // If any AutoHostPanel's have become visible we need to force a repaint otherwise + // the area not occupied by the TabStub instances will be painted the correct color + _ahpLeft.Invalidate(); + _ahpRight.Invalidate(); + _ahpTop.Invalidate(); + _ahpBottom.Invalidate(); + } + + public void PropogateNameValue(PropogateName name, object value) + { + foreach (Control c in _container.Controls) + { + Zone z = c as Zone; + + // Only interested in our Zones + if (z != null) + z.PropogateNameValue(name, value); + } + + // If the docking manager is created for a Container that does not + // yet have a parent control then we need to double check before + // trying to enumerate the owned forms. + if (_container.FindForm() != null) + { + foreach (Form f in _container.FindForm().OwnedForms) + { + FloatingForm ff = f as FloatingForm; + + // Only interested in our FloatingForms + if (ff != null) + ff.PropogateNameValue(name, value); + } + } + + // Propogate into the AutoHidePanel objects + _ahpTop.PropogateNameValue(name, value); + _ahpLeft.PropogateNameValue(name, value); + _ahpRight.PropogateNameValue(name, value); + _ahpBottom.PropogateNameValue(name, value); + } + + public virtual bool OnContentHiding(Content c) + { + CancelEventArgs cea = new CancelEventArgs(); + + if (_surpressVisibleEvents == 0) + { + // Allow user to prevent hide operation + if (ContentHiding != null) + ContentHiding(c, cea); + } + + // Was action cancelled? + return cea.Cancel; + } + + public virtual void OnContentHidden(Content c) + { + if (_surpressVisibleEvents == 0) + { + // Notify operation has completed + if (ContentHidden != null) + ContentHidden(c, EventArgs.Empty); + } + } + + public virtual void OnContentShown(Content c) + { + if (_surpressVisibleEvents == 0) + { + // Notify operation has completed + if (ContentShown != null) + ContentShown(c, EventArgs.Empty); + } + } + + public virtual void OnTabControlCreated(Magic.Controls.TabControl tabControl) + { + // Notify interested parties about creation of a new TabControl instance + if (TabControlCreated != null) + TabControlCreated(tabControl); + } + + public virtual void OnSaveCustomConfig(XmlTextWriter xmlOut) + { + // Notify interested parties that they can add their own custom data + if (SaveCustomConfig != null) + SaveCustomConfig(xmlOut); + } + + public virtual void OnLoadCustomConfig(XmlTextReader xmlIn) + { + // Notify interested parties that they can add their own custom data + if (LoadCustomConfig != null) + LoadCustomConfig(xmlIn); + } + + protected virtual void OnContentsClearing() + { + _container.SuspendLayout(); + + // Hide them all will gracefully remove them from view + HideAllContents(); + + _container.ResumeLayout(); + } + + protected virtual void OnContentRemoved(int index, object value) + { + _container.SuspendLayout(); + + Content c = value as Content; + + // Hide the content will gracefully remove it from view + if (c != null) + HideContent(c, true, false); + + _container.ResumeLayout(); + } + + protected virtual void OnContentClose(object sender, EventArgs e) + { + WindowDetailCaption wdc = sender as WindowDetailCaption; + + // Was Close generated by a Caption detail? + if (wdc != null) + { + WindowContentTabbed wct = wdc.ParentWindow as WindowContentTabbed; + + // Is the Caption part of a WindowContentTabbed object? + if (wct != null) + { + // Find the Content object that is the target + Content c = wct.CurrentContent; + + if (c != null) + { + // Was action cancelled? + if (!OnContentHiding(c)) + wct.HideCurrentContent(); + } + } + } + } + + protected virtual void OnInvertAutoHide(object sender, EventArgs e) + { + WindowDetail detail = sender as WindowDetail; + + // Get access to Content that initiated AutoHide for its Window + WindowContent wc = detail.ParentWindow as WindowContent; + + // Make the window content auto hide + InvertAutoHideWindowContent(wc); + } + + protected virtual void InvertAutoHideWindowContent(WindowContent wc) + { + // Do not generate hiding/hidden/shown events + _surpressVisibleEvents++; + + // Create a collection of the Content in the same window + ContentCollection cc = new ContentCollection(); + + // Add all Content into collection + foreach (Content c in wc.Contents) + cc.Add(c); + + // Add to the correct AutoHidePanel + AutoHideContents(cc, wc.State); + + // Enable generate hiding/hidden/shown events + _surpressVisibleEvents--; + } + + internal AutoHidePanel AutoHidePanelForState(State state) + { + AutoHidePanel ahp = null; + + // Grab the correct hosting panel + switch (state) + { + case State.DockLeft: + ahp = _ahpLeft; + break; + + case State.DockRight: + ahp = _ahpRight; + break; + + case State.DockTop: + ahp = _ahpTop; + break; + + case State.DockBottom: + ahp = _ahpBottom; + break; + } + + return ahp; + } + + internal void AutoHideContents(ContentCollection cc, State state) + { + // Hide all the Content instances. This will cause the restore objects to be + // created and so remember the docking positions for when they are restored + foreach (Content c in cc) + HideContent(c); + + AutoHidePanel ahp = AutoHidePanelForState(state); + + // Pass management of Contents into the panel + ahp.AddContentsAsGroup(cc); + } + + internal AutoHidePanel AutoHidePanelForContent(Content c) + { + if (_ahpLeft.ContainsContent(c)) + return _ahpLeft; + + if (_ahpRight.ContainsContent(c)) + return _ahpRight; + + if (_ahpTop.ContainsContent(c)) + return _ahpTop; + + if (_ahpBottom.ContainsContent(c)) + return _ahpBottom; + + return null; + } + + internal int SurpressVisibleEvents + { + get { return _surpressVisibleEvents; } + set { _surpressVisibleEvents = value; } + } + + protected void AddAutoHidePanels() + { + // Create an instance for each container edge (they default to being hidden) + _ahpTop = new AutoHidePanel(this, DockStyle.Top); + _ahpLeft = new AutoHidePanel(this, DockStyle.Left); + _ahpBottom = new AutoHidePanel(this, DockStyle.Bottom); + _ahpRight = new AutoHidePanel(this, DockStyle.Right); + + _ahpTop.Name = "Top"; + _ahpLeft.Name = "Left"; + _ahpBottom.Name = "Bottom"; + _ahpRight.Name = "Right"; + + // Add to the end of the container we manage + _container.Controls.AddRange(new Control[] { _ahpBottom, _ahpTop, _ahpRight, _ahpLeft }); + } + + protected void RepositionControlBefore(Control target, Control source) + { + // Find indexs of the two controls + int targetPos = _container.Controls.IndexOf(target); + int sourcePos = _container.Controls.IndexOf(source); + + // If the source is being moved further up the list then we must decrement the target index + // as the move is carried out in two phases. First the source control is removed from the + // collection and then added at the given requested index. So when insertion point needs + // ahjusting to reflec the fact the control has been removed before being inserted. + if (targetPos >= sourcePos) + targetPos--; + + _container.Controls.SetChildIndex(source, targetPos); + } + + protected virtual void OnRestore(object sender, EventArgs e) + { + WindowDetailCaption wdc = sender as WindowDetailCaption; + + // Was Restore generated by a Caption detail? + if (wdc != null) + { + RemoveAnyFillStyle(); + + WindowContent wc = wdc.ParentWindow as WindowContent; + + // Is the Caption part of a WindowContent object? + if (wc != null) + { + ContentCollection copy = new ContentCollection(); + + // Make every Content of the WindowContent record its + // current position and remember it for when the future + foreach (Content c in wc.Contents) + { + c.RecordRestore(); + + // Invert docked status + c.Docked = (c.Docked == false); + + copy.Add(c); + } + + int copyCount = copy.Count; + + // Must have at least one! + if (copyCount >= 1) + { + // Remove from current WindowContent and restore its position + HideContent(copy[0], false, true); + ShowContent(copy[0]); + + // Any other content to be moved along with it? + if (copyCount >= 2) + { + WindowContent newWC = copy[0].ParentWindowContent; + + if (newWC != null) + { + // Transfer each one to its new location + for (int index = 1; index < copyCount; index++) + { + HideContent(copy[index], false, true); + newWC.Contents.Add(copy[index]); + } + } + } + } + } + + AddInnerFillStyle(); + } + } + + protected void AddInnerFillStyle() + { + if (_insideFill) + { + // Find the innermost Zone which must be the first one in the collection + foreach (Control c in _container.Controls) + { + Zone z = c as Zone; + + // Only interested in our Zones + if (z != null) + { + // Make it fill all remaining space + z.Dock = DockStyle.Fill; + + // Exit + break; + } + } + } + } + + protected void RemoveAnyFillStyle() + { + // Check each Zone in the container + foreach (Control c in _container.Controls) + { + Zone z = c as Zone; + + if (z != null) + { + // Only interested in ones with the Fill dock style + if (z.Dock == DockStyle.Fill) + { + DockStyle ds; + Direction direction; + + // Find relevant values dependant on required state + ValuesFromState(z.State, out ds, out direction); + + // Reassign its correct Dock style + z.Dock = ds; + } + } + } + } + + protected void OnFormLoaded(object sender, EventArgs e) + { + // A Form can cause the child controls to be reordered after the initialisation + // but before the Form.Load event. To handle this we reorder the auto hide panels + // on the Form.Load event to ensure they are correctly positioned. + ReorderAutoHidePanels(); + } + + protected void ReorderAutoHidePanels() + { + if (_outerControl == null) + { + int count = _container.Controls.Count; + + // Position the AutoHidePanel's at end of controls + _container.Controls.SetChildIndex(_ahpLeft, count - 1); + _container.Controls.SetChildIndex(_ahpRight, count - 1); + _container.Controls.SetChildIndex(_ahpTop, count - 1); + _container.Controls.SetChildIndex(_ahpBottom, count - 1); + } + else + { + // Position the AutoHidePanel's as last items before OuterControl + RepositionControlBefore(_outerControl, _ahpBottom); + RepositionControlBefore(_outerControl, _ahpTop); + RepositionControlBefore(_outerControl, _ahpRight); + RepositionControlBefore(_outerControl, _ahpLeft); + } + } + + protected void OnContainerResized(object sender, EventArgs e) + { + if (_autoResize) + { + Rectangle inner = InnerResizeRectangle(null); + + // Shrink by the minimum size + inner.Width -= _innerMinimum.Width; + inner.Height -= _innerMinimum.Height; + + Form f = _container as Form; + + // If the container is a Form then ignore resizing because of becoming Minimized + if ((f == null) || ((f != null) && (f.WindowState != FormWindowState.Minimized))) + { + if ((inner.Width < 0) || (inner.Height < 0)) + { + _container.SuspendLayout(); + + ZoneCollection zcLeft = new ZoneCollection(); + ZoneCollection zcRight = new ZoneCollection(); + ZoneCollection zcTop = new ZoneCollection(); + ZoneCollection zcBottom = new ZoneCollection(); + + // Construct a list of the docking windows on the left and right edges + foreach (Control c in _container.Controls) + { + Zone z = c as Zone; + + if (z != null) + { + switch (z.State) + { + case State.DockLeft: + zcLeft.Add(z); + break; + + case State.DockRight: + zcRight.Add(z); + break; + + case State.DockTop: + zcTop.Add(z); + break; + + case State.DockBottom: + zcBottom.Add(z); + break; + } + } + } + + if (inner.Width < 0) + ResizeDirection(-inner.Width, zcLeft, zcRight, Direction.Horizontal); + + if (inner.Height < 0) + ResizeDirection(-inner.Height, zcTop, zcBottom, Direction.Vertical); + + _container.ResumeLayout(); + } + } + } + } + + protected void ResizeDirection(int remainder, ZoneCollection zcAlpha, ZoneCollection zcBeta, Direction dir) + { + bool alter; + int available; + int half1, half2; + + // Keep going till all space found or nowhere to get it from + while ((remainder > 0) && ((zcAlpha.Count > 0) || (zcBeta.Count > 0))) + { + if (dir == Direction.Horizontal) + { + _firstHalfWidth = (_firstHalfWidth != true); + alter = _firstHalfWidth; + } + else + { + _firstHalfHeight = (_firstHalfHeight != true); + alter = _firstHalfHeight; + } + + // Alternate between left and right getting the remainder + if (alter) + { + half1 = (remainder / 2) + 1; + half2 = remainder - half1; + } + else + { + half2 = (remainder / 2) + 1; + half1 = remainder - half2; + } + + // Any Zone of the left to use? + if (zcAlpha.Count > 0) + { + Zone z = zcAlpha[0]; + + // Find how much space it can offer up + if (dir == Direction.Horizontal) + available = z.Width - z.MinimumWidth; + else + available = z.Height - z.MinimumHeight; + + if (available > 0) + { + // Only take away the maximum we need + if (available > half1) + available = half1; + else + zcAlpha.Remove(z); + + // Resize the control accordingly + if (dir == Direction.Horizontal) + z.Width = z.Width - available; + else + z.Height = z.Height - available; + + // Reduce total amount left to allocate + remainder -= available; + } + else + zcAlpha.Remove(z); + } + + // Any Zone of the left to use? + if (zcBeta.Count > 0) + { + Zone z = zcBeta[0]; + + // Find how much space it can offer up + if (dir == Direction.Horizontal) + available = z.Width - z.MinimumWidth; + else + available = z.Height - z.MinimumHeight; + + if (available > 0) + { + // Only take away the maximum we need + if (available > half2) + available = half2; + else + zcBeta.Remove(z); + + // Resize the control accordingly + if (dir == Direction.Horizontal) + z.Width = z.Width - available; + else + z.Height = z.Height - available; + + // Reduce total amount left to allocate + remainder -= available; + } + else + zcBeta.Remove(z); + } + } + } + + protected void OnPreferenceChanged(object sender, UserPreferenceChangedEventArgs e) + { + if (_defaultBackColor) + { + _backColor = SystemColors.Control; + PropogateNameValue(PropogateName.BackColor, (object)SystemColors.Control); + } + + if (_defaultActiveColor) + { + _activeColor = SystemColors.ActiveCaption; + PropogateNameValue(PropogateName.ActiveColor, (object)SystemColors.ActiveCaption); + } + + if (_defaultActiveTextColor) + { + _activeTextColor = SystemColors.ActiveCaptionText; + PropogateNameValue(PropogateName.ActiveTextColor, (object)SystemColors.ActiveCaptionText); + } + + if (_defaultInactiveTextColor) + { + _inactiveTextColor = SystemColors.ControlText; + PropogateNameValue(PropogateName.InactiveTextColor, (object)SystemColors.ControlText); + } + + if (_defaultResizeBarColor) + { + _resizeBarColor = SystemColors.Control; + PropogateNameValue(PropogateName.ResizeBarColor, (object)SystemColors.Control); + } + + if (_defaultCaptionFont) + { + _captionFont = SystemInformation.MenuFont; + PropogateNameValue(PropogateName.CaptionFont, (object)SystemInformation.MenuFont); + } + + if (_defaultTabControlFont) + { + _tabControlFont = SystemInformation.MenuFont; + PropogateNameValue(PropogateName.TabControlFont, (object)SystemInformation.MenuFont); + } + } + + public virtual void OnShowContextMenu(Point screenPos) + { + PopupMenu context = new PopupMenu(); + + // The order of Content displayed in the context menu is not the same as + // the order of Content in the _contents collection. The latter has its + // ordering changed to enable Restore functionality to work. + ContentCollection temp = new ContentCollection(); + + foreach (Content c in _contents) + { + int count = temp.Count; + int index = 0; + + // Find best place to add into the temp collection + for (; index < count; index++) + { + if (c.Order < temp[index].Order) + break; + } + + temp.Insert(index, c); + } + + // Create a context menu entry per Content + foreach (Content t in temp) + { + MenuCommand mc = new MenuCommand(t.Title, new EventHandler(OnToggleContentVisibility)); + mc.Checked = t.Visible; + mc.Tag = t; + + context.MenuCommands.Add(mc); + } + + // Add a separator + context.MenuCommands.Add(new MenuCommand("-")); + + // Add fixed entries to end to effect all content objects + context.MenuCommands.Add(new MenuCommand("Show All", new EventHandler(OnShowAll))); + context.MenuCommands.Add(new MenuCommand("Hide All", new EventHandler(OnHideAll))); + + // Ensure menu has same style as the docking windows + context.Style = _visualStyle; + + if (OnContextMenu(context)) + { + // Show it! + context.TrackPopup(screenPos); + } + } + + protected bool OnContextMenu(PopupMenu context) + { + CancelEventArgs cea = new CancelEventArgs(); + + if (ContextMenu != null) + ContextMenu(context, cea); + + return !cea.Cancel; + } + + protected void OnToggleContentVisibility(object sender, EventArgs e) + { + MenuCommand mc = sender as MenuCommand; + + if (mc != null) + { + Content c = mc.Tag as Content; + + if (c != null) + { + if (c.Visible) + HideContent(c); + else + ShowContent(c); + } + } + } + + protected void OnShowAll(object sender, EventArgs e) + { + ShowAllContents(); + } + + protected void OnHideAll(object sender, EventArgs e) + { + HideAllContents(); + } + } +} \ No newline at end of file diff --git a/Labyrinth3/Crownwood.Magic/Docking/FloatinglForm.cs b/Labyrinth3/Crownwood.Magic/Docking/FloatinglForm.cs new file mode 100644 index 0000000..2ac90e9 --- /dev/null +++ b/Labyrinth3/Crownwood.Magic/Docking/FloatinglForm.cs @@ -0,0 +1,529 @@ +// ***************************************************************************** +// +// (c) Crownwood Consulting Limited 2002-2003 +// All rights reserved. The software and associated documentation +// supplied hereunder are the proprietary information of Crownwood Consulting +// Limited, Crownwood, Bracknell, Berkshire, England and are supplied subject +// to licence terms. +// +// Magic Version 1.7.4.0 www.dotnetmagic.com +// ***************************************************************************** + +//using Crownwood.Magic.Win32; +using Crownwood.Magic.Collections; +using System; +using System.ComponentModel; +using System.Drawing; +using System.Windows.Forms; + +namespace Crownwood.Magic.Docking +{ + public class FloatingForm : Form, IHotZoneSource, IMessageFilter + { + // Class constants + private const int HITTEST_CAPTION = 2; + + // Instance variables + protected Zone _zone; + + protected bool _intercept; + protected RedockerContent _redocker; + protected DockingManager _dockingManager; + + // Instance events + public event ContextHandler Context; + + public FloatingForm(DockingManager dockingManager, Zone zone, ContextHandler contextHandler) + { + // The caller is responsible for setting our initial screen location + this.StartPosition = FormStartPosition.Manual; + + // Not in task bar to prevent clutter + this.ShowInTaskbar = false; + + // Make sure the main Form owns us + this.Owner = dockingManager.Container.FindForm(); + + // Need to know when the Zone is removed + this.ControlRemoved += new ControlEventHandler(OnZoneRemoved); + + // Add the Zone as the only content of the Form + Controls.Add(zone); + + // Default state + _redocker = null; + _intercept = false; + _zone = zone; + _dockingManager = dockingManager; + + // Assign any event handler for context menu + if (contextHandler != null) + this.Context += contextHandler; + + // Default color + this.BackColor = _dockingManager.BackColor; + this.ForeColor = _dockingManager.InactiveTextColor; + + // Monitor changes in the Zone content + _zone.Windows.Inserted += new CollectionChange(OnWindowInserted); + _zone.Windows.Removing += new CollectionChange(OnWindowRemoving); + _zone.Windows.Removed += new CollectionChange(OnWindowRemoved); + + if (_zone.Windows.Count == 1) + { + // The first Window to be added. Tell it to hide details + _zone.Windows[0].HideDetails(); + + // Monitor change in window title + _zone.Windows[0].FullTitleChanged += new EventHandler(OnFullTitleChanged); + + // Grab any existing title + this.Text = _zone.Windows[0].FullTitle; + } + + // Need to hook into message pump so that the ESCAPE key can be + // intercepted when in redocking mode + Application.AddMessageFilter(this); + } + + public DockingManager DockingManager + { + get { return _dockingManager; } + } + + public Zone Zone + { + get { return this.Controls[0] as Zone; } + } + + public void PropogateNameValue(PropogateName name, object value) + { + if (this.Zone != null) + this.Zone.PropogateNameValue(name, value); + } + + public void AddHotZones(Redocker redock, HotZoneCollection collection) + { + RedockerContent redocker = redock as RedockerContent; + + // Allow the contained Zone a chance to expose HotZones + foreach (Control c in this.Controls) + { + IHotZoneSource ag = c as IHotZoneSource; + + // Does this control expose an interface for its own HotZones? + if (ag != null) + ag.AddHotZones(redock, collection); + } + } + + protected void OnWindowInserted(int index, object value) + { + if (_zone.Windows.Count == 1) + { + // The first Window to be added. Tell it to hide details + _zone.Windows[0].HideDetails(); + + // Monitor change in window title + _zone.Windows[0].FullTitleChanged += new EventHandler(OnFullTitleChanged); + + // Grab any existing title + this.Text = _zone.Windows[0].FullTitle; + } + else if (_zone.Windows.Count == 2) + { + int pos = 0; + + // If the new Window is inserted at beginning then update the second Window + if (index == 0) + pos++; + + // The second Window to be added. Tell the first to now show details + _zone.Windows[pos].ShowDetails(); + + // Monitor change in window title + _zone.Windows[pos].FullTitleChanged -= new EventHandler(OnFullTitleChanged); + + // Remove any caption title + this.Text = ""; + } + } + + protected void OnWindowRemoving(int index, object value) + { + if (_zone.Windows.Count == 1) + { + // The first Window to be removed. Tell it to show details as we want + // to restore the Window state before it might be moved elsewhere + _zone.Windows[0].ShowDetails(); + + // Monitor change in window title + _zone.Windows[0].FullTitleChanged -= new EventHandler(OnFullTitleChanged); + + // Remove any existing title text + this.Text = ""; + } + } + + protected void OnWindowRemoved(int index, object value) + { + if (_zone.Windows.Count == 1) + { + // Window removed leaving just one left. Tell it to hide details + _zone.Windows[0].HideDetails(); + + // Monitor change in window title + _zone.Windows[0].FullTitleChanged += new EventHandler(OnFullTitleChanged); + + // Grab any existing title text + this.Text = _zone.Windows[0].FullTitle; + } + } + + protected void OnFullTitleChanged(object sender, EventArgs e) + { + // Unbox sent string + this.Text = (string)sender; + } + + protected void OnZoneRemoved(object sender, ControlEventArgs e) + { + // Is it the Zone being removed for a hidden button used to help + // remove controls without hitting the 'form refuses to close' bug + if (e.Control == _zone) + { + if (_zone.Windows.Count == 1) + { + // The first Window to be removed. Tell it to show details as we want + // to restore the Window state before it might be moved elsewhere + _zone.Windows[0].ShowDetails(); + + // Remove monitor change in window title + _zone.Windows[0].FullTitleChanged -= new EventHandler(OnFullTitleChanged); + } + + // Monitor changes in the Zone content + _zone.Windows.Inserted -= new CollectionChange(OnWindowInserted); + _zone.Windows.Removing -= new CollectionChange(OnWindowRemoving); + _zone.Windows.Removed -= new CollectionChange(OnWindowRemoved); + + // No longer required, commit suicide + this.Dispose(); + } + } + + protected override CreateParams CreateParams + { + get + { + // Let base class fill in structure first + CreateParams cp = base.CreateParams; + + // The only way to get a caption bar with only small + // close button is by providing this extended style + cp.ExStyle |= (int)Win32.WindowExStyles.WS_EX_TOOLWINDOW; + + return cp; + } + } + + public virtual void OnContext(Point screenPos) + { + // Any attached event handlers? + if (Context != null) + Context(screenPos); + } + + public void ExitFloating() + { + if (_zone != null) + { + ContentCollection cc = ZoneHelper.Contents(_zone); + + // Record restore object for each Content + foreach (Content c in cc) + { + c.RecordFloatingRestore(); + c.Docked = true; + } + } + } + + protected void Restore() + { + if (_zone != null) + { + ContentCollection cc = ZoneHelper.Contents(_zone); + + // Record restore object for each Content + foreach (Content c in cc) + { + c.RecordFloatingRestore(); + c.Docked = true; + } + + // Ensure each content is removed from any Parent + foreach (Content c in cc) + _dockingManager.HideContent(c, false, true); + + // Now restore each of the Content + foreach (Content c in cc) + _dockingManager.ShowContent(c); + + _dockingManager.UpdateInsideFill(); + } + + this.Close(); + } + + protected override void OnMove(EventArgs e) + { + Point newPos = this.Location; + + // Grab the aggregate collection of all Content objects in the Zone + ContentCollection cc = ZoneHelper.Contents(_zone); + + // Update each one with the new FloatingForm location + foreach (Content c in cc) + c.DisplayLocation = newPos; + + base.OnMove(e); + } + + protected override void OnClosing(CancelEventArgs e) + { + if (_zone != null) + { + ContentCollection cc = ZoneHelper.Contents(_zone); + + // Record restore object for each Content + foreach (Content c in cc) + c.RecordRestore(); + + // Ensure each content is removed from any Parent + foreach (Content c in cc) + { + // Is content allowed to be hidden? + if (!_dockingManager.OnContentHiding(c)) + { + // Hide the content always + _dockingManager.HideContent(c, false, true); + + // Do we also remove the content? + if (c.CloseOnHide) + { + // Remove the content from the collection + _dockingManager.Contents.Remove(c); + + // Dispose of the contained control/form + if (c.Control != null) + c.Control.Dispose(); + } + } + else + { + // At least one Content refuses to die, so do not + // let the whole floating form be closed down + e.Cancel = true; + } + } + } + + // Must set focus back to the main application Window + if (this.Owner != null) + this.Owner.Activate(); + + base.OnClosing(e); + } + + protected override void OnResize(System.EventArgs e) + { + // Grab the aggregate collection of all Content objects in the Zone + ContentCollection cc = ZoneHelper.Contents(_zone); + + // Do not include the caption height of the tool window in the saved height + Size newSize = new Size(this.Width, this.Height - SystemInformation.ToolWindowCaptionHeight); + + // Update each one with the new FloatingForm location + foreach (Content c in cc) + c.FloatingSize = newSize; + + base.OnResize(e); + } + + public bool PreFilterMessage(ref Message m) + { + // Has a key been pressed? + if (m.Msg == (int)Win32.Msgs.WM_KEYDOWN) + { + // Is it the ESCAPE key? + if ((int)m.WParam == (int)Win32.VirtualKeys.VK_ESCAPE) + { + // Are we in a redocking activity? + if (_intercept) + { + // Quite redocking + _redocker.QuitTrackingMode(null); + + // Release capture + this.Capture = false; + + // Reset state + _intercept = false; + + return true; + } + } + } + + return false; + } + + protected override void WndProc(ref Message m) + { + // Want to notice when the window is maximized + if (m.Msg == (int)Win32.Msgs.WM_NCLBUTTONDBLCLK) + { + // Redock and kill ourself + Restore(); + + // We do not want to let the base process the message as the + // restore might fail due to lack of permission to restore to + // old state. In that case we do not want to maximize the window + return; + } + else if (m.Msg == (int)Win32.Msgs.WM_NCLBUTTONDOWN) + { + if (!_intercept) + { + // Perform a hit test against our own window to determine + // which area the mouse press is over at the moment. + //#if !MONO + // uint result = User32.SendMessage(this.Handle, (int)Win32.Msgs.WM_NCHITTEST, 0, (uint)m.LParam); + //#else + Message msg = new Message(); + msg.HWnd = Handle; + msg.LParam = m.LParam; + msg.Msg = (int)Win32.Msgs.WM_NCHITTEST; + msg.WParam = IntPtr.Zero; + base.WndProc(ref msg); + uint result = (uint)msg.Result; + //#endif + + // Only want to override the behviour of moving the window via the caption box + if (result == HITTEST_CAPTION) + { + // Remember new state + _intercept = true; + + // Capture the mouse until the mouse us is received + this.Capture = true; + + // Ensure that we gain focus and look active + this.Activate(); + + // Get mouse position to inscreen coordinates + Win32.POINT mousePos; + mousePos.x = (short)((uint)m.LParam & 0x0000FFFFU); + mousePos.y = (short)(uint)(((uint)m.LParam & 0xFFFF0000U) >> 16); + + // Find adjustment to bring screen to client coordinates + Point topLeft = PointToScreen(new Point(0, 0)); + topLeft.Y -= SystemInformation.CaptionHeight; + topLeft.X -= SystemInformation.BorderSize.Width; + + // Begin a redocking activity + _redocker = new RedockerContent(this, new Point(mousePos.x - topLeft.X, + mousePos.y - topLeft.Y)); + + return; + } + } + } + else if (m.Msg == (int)Win32.Msgs.WM_MOUSEMOVE) + { + if (_intercept) + { + Win32.POINT mousePos; + mousePos.x = (short)((uint)m.LParam & 0x0000FFFFU); + mousePos.y = (short)(uint)(((uint)m.LParam & 0xFFFF0000U) >> 16); + + _redocker.OnMouseMove(new MouseEventArgs(MouseButtons.Left, + 0, mousePos.x, mousePos.y, 0)); + + return; + } + } + else if ((m.Msg == (int)Win32.Msgs.WM_RBUTTONDOWN) || + (m.Msg == (int)Win32.Msgs.WM_MBUTTONDOWN)) + { + if (_intercept) + { + Win32.POINT mousePos; + mousePos.x = (short)((uint)m.LParam & 0x0000FFFFU); + mousePos.y = (short)(uint)(((uint)m.LParam & 0xFFFF0000U) >> 16); + + _redocker.QuitTrackingMode(new MouseEventArgs(MouseButtons.Left, + 0, mousePos.x, mousePos.y, 0)); + + // Release capture + this.Capture = false; + + // Reset state + _intercept = false; + + return; + } + } + else if (m.Msg == (int)Win32.Msgs.WM_LBUTTONUP) + { + if (_intercept) + { + Win32.POINT mousePos; + mousePos.x = (short)((uint)m.LParam & 0x0000FFFFU); + mousePos.y = (short)(uint)(((uint)m.LParam & 0xFFFF0000U) >> 16); + + _redocker.OnMouseUp(new MouseEventArgs(MouseButtons.Left, 0, + mousePos.x, mousePos.y, 0)); + + // Release capture + this.Capture = false; + + // Reset state + _intercept = false; + + return; + } + } + else if ((m.Msg == (int)Win32.Msgs.WM_NCRBUTTONUP) || + (m.Msg == (int)Win32.Msgs.WM_NCMBUTTONDOWN) || + (m.Msg == (int)Win32.Msgs.WM_NCMBUTTONUP) || + (m.Msg == (int)Win32.Msgs.WM_RBUTTONDOWN) || + (m.Msg == (int)Win32.Msgs.WM_RBUTTONUP) || + (m.Msg == (int)Win32.Msgs.WM_MBUTTONDOWN) || + (m.Msg == (int)Win32.Msgs.WM_MBUTTONUP)) + { + // Prevent middle and right mouse buttons from interrupting + // the correct operation of left mouse dragging + return; + } + else if (m.Msg == (int)Win32.Msgs.WM_NCRBUTTONDOWN) + { + if (!_intercept) + { + // Get screen coordinates of the mouse + Win32.POINT mousePos; + mousePos.x = (short)((uint)m.LParam & 0x0000FFFFU); + mousePos.y = (short)(uint)(((uint)m.LParam & 0xFFFF0000U) >> 16); + + // Box to transfer as parameter + OnContext(new Point(mousePos.x, mousePos.y)); + + return; + } + } + + base.WndProc(ref m); + } + } +} \ No newline at end of file diff --git a/Labyrinth3/Crownwood.Magic/Docking/FloatinglForm.resx b/Labyrinth3/Crownwood.Magic/Docking/FloatinglForm.resx new file mode 100644 index 0000000..7e32396 --- /dev/null +++ b/Labyrinth3/Crownwood.Magic/Docking/FloatinglForm.resx @@ -0,0 +1,42 @@ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + text/microsoft-resx + + + 1.0.0.0 + + + System.Resources.ResXResourceReader, System.Windows.Forms, Version=1.0.3102.0, Culture=neutral, PublicKeyToken=b77a5c561934e089 + + + System.Resources.ResXResourceWriter, System.Windows.Forms, Version=1.0.3102.0, Culture=neutral, PublicKeyToken=b77a5c561934e089 + + diff --git a/Labyrinth3/Crownwood.Magic/Docking/HotZone.cs b/Labyrinth3/Crownwood.Magic/Docking/HotZone.cs new file mode 100644 index 0000000..26adcb1 --- /dev/null +++ b/Labyrinth3/Crownwood.Magic/Docking/HotZone.cs @@ -0,0 +1,68 @@ +// ***************************************************************************** +// +// (c) Crownwood Consulting Limited 2002-2003 +// All rights reserved. The software and associated documentation +// supplied hereunder are the proprietary information of Crownwood Consulting +// Limited, Crownwood, Bracknell, Berkshire, England and are supplied subject +// to licence terms. +// +// Magic Version 1.7.4.0 www.dotnetmagic.com +// ***************************************************************************** + +using Crownwood.Magic.Common; +using System.Drawing; + +namespace Crownwood.Magic.Docking +{ + public class HotZone + { + // Class constants + protected static int _dragWidth = 4; + + // Instance fields + protected Rectangle _hotArea; + + protected Rectangle _newSize; + + public HotZone(Rectangle hotArea, Rectangle newSize) + { + // Store initial state + _hotArea = hotArea; + _newSize = newSize; + } + + public Rectangle HotArea + { + get { return _hotArea; } + } + + public Rectangle NewSize + { + get { return _newSize; } + } + + public virtual bool ApplyChange(Point screenPos, Redocker parent) + { + return false; + } + + public virtual void UpdateForMousePosition(Point screenPos, Redocker parent) + { + } + + public virtual void DrawIndicator(Point mousePos) + { + DrawReversible(_newSize); + } + + public virtual void RemoveIndicator(Point mousePos) + { + DrawReversible(_newSize); + } + + public virtual void DrawReversible(Rectangle rect) + { + DrawHelper.DrawDragRectangle(rect, _dragWidth); + } + } +} \ No newline at end of file diff --git a/Labyrinth3/Crownwood.Magic/Docking/HotZoneFloating.cs b/Labyrinth3/Crownwood.Magic/Docking/HotZoneFloating.cs new file mode 100644 index 0000000..170b44c --- /dev/null +++ b/Labyrinth3/Crownwood.Magic/Docking/HotZoneFloating.cs @@ -0,0 +1,234 @@ +// ***************************************************************************** +// +// (c) Crownwood Consulting Limited 2002-2003 +// All rights reserved. The software and associated documentation +// supplied hereunder are the proprietary information of Crownwood Consulting +// Limited, Crownwood, Bracknell, Berkshire, England and are supplied subject +// to licence terms. +// +// Magic Version 1.7.4.0 www.dotnetmagic.com +// ***************************************************************************** + +using Crownwood.Magic.Common; +using System.Drawing; +using System.Windows.Forms; + +namespace Crownwood.Magic.Docking +{ + public class HotZoneFloating : HotZone + { + // Instance fields + protected Point _offset; + + protected Point _drawPos; + protected Rectangle _drawRect; + protected RedockerContent _redocker; + + public HotZoneFloating(Rectangle hotArea, Rectangle newSize, Point offset, RedockerContent redocker) + : base(hotArea, newSize) + { + // Store initial state + _offset = offset; + _redocker = redocker; + + Size floatSize = CalculateFloatingSize(); + float widthPercentage = (float)floatSize.Width / (float)_newSize.Width; + float heightPercentage = (float)floatSize.Height / (float)_newSize.Height; + + _newSize.Width = floatSize.Width; + _newSize.Height = floatSize.Height + SystemInformation.ToolWindowCaptionHeight; + + _offset.X = (int)((float)_offset.X * widthPercentage); + _offset.Y = (int)((float)_offset.Y * heightPercentage); + + // We do not want the indicator to be too far away from the cursor, so limit check the offset + if (_offset.X > newSize.Width) + _offset.X = newSize.Width; + + if (_offset.Y > newSize.Height) + _offset.Y = newSize.Height; + } + + public override bool ApplyChange(Point screenPos, Redocker parent) + { + // Should always be the appropriate type + RedockerContent redock = parent as RedockerContent; + + DockingManager dockingManager = redock.DockingManager; + + Zone newZone = null; + + // Manageing Zones should remove display AutoHide windows + dockingManager.RemoveShowingAutoHideWindows(); + + switch (redock.DockingSource) + { + case RedockerContent.Source.RawContent: + { + // Perform State specific Restore actions + redock.Content.ContentBecomesFloating(); + + // Create a new Window to host Content + Window w = dockingManager.CreateWindowForContent(redock.Content); + + // We need to create a Zone for containing the transfered content + newZone = dockingManager.CreateZoneForContent(State.Floating); + + // Add into Zone + newZone.Windows.Add(w); + } + break; + + case RedockerContent.Source.WindowContent: + // Perform State specific Restore actions + foreach (Content c in redock.WindowContent.Contents) + c.ContentBecomesFloating(); + + // Remove WindowContent from old Zone + if (redock.WindowContent.ParentZone != null) + redock.WindowContent.ParentZone.Windows.Remove(redock.WindowContent); + + // We need to create a Zone for containing the transfered content + newZone = dockingManager.CreateZoneForContent(State.Floating); + + // Add into new Zone + newZone.Windows.Add(redock.WindowContent); + break; + + case RedockerContent.Source.ContentInsideWindow: + { + // Perform State specific Restore actions + redock.Content.ContentBecomesFloating(); + + // Remove Content from existing WindowContent + if (redock.Content.ParentWindowContent != null) + redock.Content.ParentWindowContent.Contents.Remove(redock.Content); + + // Create a new Window to host Content + Window w = dockingManager.CreateWindowForContent(redock.Content); + + // We need to create a Zone for containing the transfered content + newZone = dockingManager.CreateZoneForContent(State.Floating); + + // Add into Zone + newZone.Windows.Add(w); + } + break; + + case RedockerContent.Source.FloatingForm: + redock.FloatingForm.Location = new Point(screenPos.X - _offset.X, + screenPos.Y - _offset.Y); + + return false; + } + + dockingManager.UpdateInsideFill(); + + // Create a new floating form + FloatingForm floating = new FloatingForm(redock.DockingManager, newZone, + new ContextHandler(dockingManager.OnShowContextMenu)); + + // Find screen location/size + _drawRect = new Rectangle(screenPos.X, screenPos.Y, _newSize.Width, _newSize.Height); + + // Adjust for mouse starting position relative to source control + _drawRect.X -= _offset.X; + _drawRect.Y -= _offset.Y; + + // Define its location/size + floating.Location = new Point(_drawRect.Left, _drawRect.Top); + floating.Size = new Size(_drawRect.Width, _drawRect.Height); + + // Show it! + floating.Show(); + + return true; + } + + public override void UpdateForMousePosition(Point screenPos, Redocker parent) + { + // Remember the current mouse pos + Point newPos = screenPos; + + // Calculate the new drawing rectangle + Rectangle newRect = new Rectangle(newPos.X, newPos.Y, _newSize.Width, _newSize.Height); + + // Adjust for mouse starting position relative to source control + newRect.X -= _offset.X; + newRect.Y -= _offset.Y; + + // Draw both the old rectangle and the new one, that will remove flicker as the + // draw method will only actually draw areas that differ between the two rectangles + DrawHelper.DrawDragRectangles(new Rectangle[] { _drawRect, newRect }, _dragWidth); + + // Remember new values + _drawPos = newPos; + _drawRect = newRect; + } + + public override void DrawIndicator(Point mousePos) + { + // Remember the current mouse pos + _drawPos = mousePos; + + // Calculate the new drawing rectangle + _drawRect = new Rectangle(_drawPos.X, _drawPos.Y, _newSize.Width, _newSize.Height); + + // Adjust for mouse starting position relative to source control + _drawRect.X -= _offset.X; + _drawRect.Y -= _offset.Y; + + DrawReversible(_drawRect); + } + + public override void RemoveIndicator(Point mousePos) + { + DrawReversible(_drawRect); + } + + protected Size CalculateFloatingSize() + { + Size floatingSize = new Size(0, 0); + + // Get specific redocker type + RedockerContent redock = _redocker as RedockerContent; + + switch (redock.DockingSource) + { + case RedockerContent.Source.RawContent: + // Whole Form is size requested by single Content + floatingSize = redock.Content.FloatingSize; + break; + + case RedockerContent.Source.WindowContent: + // Find the largest requested floating size + foreach (Content c in redock.WindowContent.Contents) + { + if (c.FloatingSize.Width > floatingSize.Width) + floatingSize.Width = c.FloatingSize.Width; + + if (c.FloatingSize.Height > floatingSize.Height) + floatingSize.Height = c.FloatingSize.Height; + } + + // Apply same size to all Content objects + foreach (Content c in redock.WindowContent.Contents) + c.FloatingSize = floatingSize; + break; + + case RedockerContent.Source.ContentInsideWindow: + // Whole Form is size requested by single Content + floatingSize = redock.Content.FloatingSize; + break; + + case RedockerContent.Source.FloatingForm: + // Use the requested size + floatingSize.Width = _newSize.Width; + floatingSize.Height = _newSize.Height; + break; + } + + return floatingSize; + } + } +} \ No newline at end of file diff --git a/Labyrinth3/Crownwood.Magic/Docking/HotZoneNull.cs b/Labyrinth3/Crownwood.Magic/Docking/HotZoneNull.cs new file mode 100644 index 0000000..98b9b6e --- /dev/null +++ b/Labyrinth3/Crownwood.Magic/Docking/HotZoneNull.cs @@ -0,0 +1,31 @@ +// ***************************************************************************** +// +// (c) Crownwood Consulting Limited 2002-2003 +// All rights reserved. The software and associated documentation +// supplied hereunder are the proprietary information of Crownwood Consulting +// Limited, Crownwood, Bracknell, Berkshire, England and are supplied subject +// to licence terms. +// +// Magic Version 1.7.4.0 www.dotnetmagic.com +// ***************************************************************************** + +using System.Drawing; + +namespace Crownwood.Magic.Docking +{ + public class HotZoneNull : HotZone + { + public HotZoneNull(Rectangle hotArea) + : base(hotArea, hotArea) + { + } + + public override void DrawIndicator(Point mousePos) + { + } + + public override void RemoveIndicator(Point mousePos) + { + } + } +} \ No newline at end of file diff --git a/Labyrinth3/Crownwood.Magic/Docking/HotZoneReposition.cs b/Labyrinth3/Crownwood.Magic/Docking/HotZoneReposition.cs new file mode 100644 index 0000000..e0906cb --- /dev/null +++ b/Labyrinth3/Crownwood.Magic/Docking/HotZoneReposition.cs @@ -0,0 +1,193 @@ +// ***************************************************************************** +// +// (c) Crownwood Consulting Limited 2002-2003 +// All rights reserved. The software and associated documentation +// supplied hereunder are the proprietary information of Crownwood Consulting +// Limited, Crownwood, Bracknell, Berkshire, England and are supplied subject +// to licence terms. +// +// Magic Version 1.7.4.0 www.dotnetmagic.com +// ***************************************************************************** + +using Crownwood.Magic.Common; +using System.Drawing; +using System.Windows.Forms; + +namespace Crownwood.Magic.Docking +{ + public class HotZoneReposition : HotZone + { + protected enum Position + { + Inner, + Index, + Outer + } + + // Instance fields + protected int _newIndex; + + protected Position _position; + protected State _state; + + public HotZoneReposition(Rectangle hotArea, Rectangle newSize, State state, bool inner) + : base(hotArea, newSize) + { + // Minus one means create at the innermost position + InternalConstruct((inner ? Position.Inner : Position.Outer), state, -1); + } + + public HotZoneReposition(Rectangle hotArea, Rectangle newSize, State state, int newIndex) + : base(hotArea, newSize) + { + InternalConstruct(Position.Index, state, newIndex); + } + + protected void InternalConstruct(Position position, State state, int newIndex) + { + // Store initial state + _position = position; + _newIndex = newIndex; + _state = state; + } + + public override bool ApplyChange(Point screenPos, Redocker parent) + { + // We are only called from the RedockerContent class + RedockerContent redock = parent as RedockerContent; + + DockingManager dockingManager = redock.DockingManager; + + // Reduce flicker during transition + dockingManager.Container.SuspendLayout(); + + // Need to create a new Zone + Zone zone; + + if (redock.DockingSource == RedockerContent.Source.FloatingForm) + { + // Make every Content object in the Floating Zone + // record its current state as the Floating state + redock.FloatingForm.ExitFloating(); + + zone = redock.FloatingForm.Zone; + } + else + zone = dockingManager.CreateZoneForContent(_state); + + // Insert Zone at end of Controls collection + dockingManager.Container.Controls.Add(zone); + + // Adjust ordering + switch (_position) + { + case Position.Inner: + dockingManager.ReorderZoneToInnerMost(zone); + break; + + case Position.Index: + // Manageing Zones should remove display AutoHide windows + dockingManager.RemoveShowingAutoHideWindows(); + + // Place new Zone AFTER the one given, so need to increase index by one + dockingManager.Container.Controls.SetChildIndex(zone, _newIndex + 1); + break; + + case Position.Outer: + dockingManager.ReorderZoneToOuterMost(zone); + break; + } + + switch (redock.DockingSource) + { + case RedockerContent.Source.RawContent: + { + // Create a new Window to host Content + Window w = dockingManager.CreateWindowForContent(redock.Content); + + // Add into Zone + zone.Windows.Add(w); + } + break; + + case RedockerContent.Source.WindowContent: + // Remove WindowContent from old Zone + if (redock.WindowContent.ParentZone != null) + { + // If the source is leaving the Floating state then need to record Restore positions + if (redock.WindowContent.State == State.Floating) + { + foreach (Content c in redock.WindowContent.Contents) + c.ContentLeavesFloating(); + } + + redock.WindowContent.ParentZone.Windows.Remove(redock.WindowContent); + } + + // Add into new Zone + zone.Windows.Add(redock.WindowContent); + break; + + case RedockerContent.Source.ContentInsideWindow: + { + // Remove Content from existing WindowContent + if (redock.Content.ParentWindowContent != null) + { + // If the source is leaving the Floating state then need to record Restore position + if (redock.Content.ParentWindowContent.State == State.Floating) + redock.Content.ContentLeavesFloating(); + + redock.Content.ParentWindowContent.Contents.Remove(redock.Content); + } + + // Create a new WindowContent to host Content + Window w = dockingManager.CreateWindowForContent(redock.Content); + + // Add into Zone + zone.Windows.Add(w); + } + break; + + case RedockerContent.Source.FloatingForm: + DockStyle ds; + Direction direction; + + dockingManager.ValuesFromState(_state, out ds, out direction); + + // Define correct docking style to match state + zone.Dock = ds; + + ZoneSequence zs = zone as ZoneSequence; + + // Define correct display direction to match state + if (zs != null) + zs.Direction = direction; + + // Ensure the Zone recalculates contents according to new state + zone.State = _state; + break; + } + + // Define correct size of the new Zone + switch (_state) + { + case State.DockLeft: + case State.DockRight: + zone.Width = _newSize.Width; + break; + + case State.DockTop: + case State.DockBottom: + zone.Height = _newSize.Height; + break; + } + + dockingManager.UpdateInsideFill(); + + // Reduce flicker during transition + dockingManager.Container.ResumeLayout(); + + return true; + } + } +} \ No newline at end of file diff --git a/Labyrinth3/Crownwood.Magic/Docking/HotZoneSequence.cs b/Labyrinth3/Crownwood.Magic/Docking/HotZoneSequence.cs new file mode 100644 index 0000000..be46bb9 --- /dev/null +++ b/Labyrinth3/Crownwood.Magic/Docking/HotZoneSequence.cs @@ -0,0 +1,192 @@ +// ***************************************************************************** +// +// (c) Crownwood Consulting Limited 2002-2003 +// All rights reserved. The software and associated documentation +// supplied hereunder are the proprietary information of Crownwood Consulting +// Limited, Crownwood, Bracknell, Berkshire, England and are supplied subject +// to licence terms. +// +// Magic Version 1.7.4.0 www.dotnetmagic.com +// ***************************************************************************** + +using System.Drawing; + +//using Crownwood.Magic.Win32; + +namespace Crownwood.Magic.Docking +{ + public class HotZoneSequence : HotZone + { + // Instance fields + protected int _index; + + protected ZoneSequence _zs; + + public HotZoneSequence(Rectangle hotArea, Rectangle newSize, ZoneSequence zs, int index) + : base(hotArea, newSize) + { + _index = index; + _zs = zs; + } + + public override bool ApplyChange(Point screenPos, Redocker parent) + { + // We are only called from the RedockerContent class + RedockerContent redock = parent as RedockerContent; + + DockingManager dockingManager = redock.DockingManager; + + bool becomeFloating = (_zs.State == State.Floating); + + // Reduce flicker during transition + dockingManager.Container.SuspendLayout(); + + // Manageing Zones should remove display AutoHide windows + dockingManager.RemoveShowingAutoHideWindows(); + + switch (redock.DockingSource) + { + case RedockerContent.Source.RawContent: + { + // Perform State specific Restore actions + if (becomeFloating) + redock.Content.ContentBecomesFloating(); + + // Create a new Window to host Content + Window w = dockingManager.CreateWindowForContent(redock.Content); + + // Add into Zone + _zs.Windows.Insert(_index, w); + } + break; + + case RedockerContent.Source.WindowContent: + { + // Is the destination Zone in the Floating state? + if (becomeFloating) + { + foreach (Content c in redock.WindowContent.Contents) + c.ContentBecomesFloating(); + } + else + { + if (redock.WindowContent.State == State.Floating) + { + foreach (Content c in redock.WindowContent.Contents) + c.ContentLeavesFloating(); + } + } + + // Check if the WindowContent source is in same Zone + if (redock.WindowContent.ParentZone == _zs) + { + // Find current position of source WindowContent + int currPos = _zs.Windows.IndexOf(redock.WindowContent); + + // If current window is before the new position then the current + // window will disappear before the new one is inserted,so need to + // adjust down the new insertion point + if (currPos < _index) + _index--; + } + + // Create a new Window to host Content + WindowContent wc = dockingManager.CreateWindowForContent(null) as WindowContent; + + // Transfer content across + int count = redock.WindowContent.Contents.Count; + + for (int index = 0; index < count; index++) + { + Content c = redock.WindowContent.Contents[0]; + + // Remove from existing location + redock.WindowContent.Contents.RemoveAt(0); + + // Add into new WindowContent host + wc.Contents.Add(c); + } + + // Add into host into Zone + _zs.Windows.Insert(_index, wc); + } + break; + + case RedockerContent.Source.ContentInsideWindow: + { + // Perform State specific Restore actions + if (becomeFloating) + redock.Content.ContentBecomesFloating(); + else + { + if (redock.Content.ParentWindowContent.State == State.Floating) + redock.Content.ContentLeavesFloating(); + } + + // Remove Content from existing WindowContent + if (redock.Content.ParentWindowContent != null) + { + // Will removing the Content cause the WindowContent to die? + if (redock.Content.ParentWindowContent.Contents.Count == 1) + { + // Check if the WindowContent source is in same Zone + if (redock.Content.ParentWindowContent.ParentZone == _zs) + { + // Find current position of source WindowContent + int currPos = _zs.Windows.IndexOf(redock.Content.ParentWindowContent); + + // If current window is before the new position then the current + // window will disappear before the new one is inserted,so need to + // adjust down the new insertion point + if (currPos < _index) + _index--; + } + } + + redock.Content.ParentWindowContent.Contents.Remove(redock.Content); + } + + // Create a new Window to host Content + Window w = dockingManager.CreateWindowForContent(redock.Content); + + // Add into Zone + _zs.Windows.Insert(_index, w); + } + break; + + case RedockerContent.Source.FloatingForm: + { + // Perform State specific Restore actions + if (!becomeFloating) + { + // Make every Content object in the Floating Zone + // record its current state as the Floating state + redock.FloatingForm.ExitFloating(); + } + + int count = redock.FloatingForm.Zone.Windows.Count; + + for (int index = count - 1; index >= 0; index--) + { + // Remember the Window reference + Window w = redock.FloatingForm.Zone.Windows[index]; + + // Remove from floating collection + redock.FloatingForm.Zone.Windows.RemoveAt(index); + + // Add into new ZoneSequence destination + _zs.Windows.Insert(_index, w); + } + } + break; + } + + dockingManager.UpdateInsideFill(); + + // Reduce flicker during transition + dockingManager.Container.ResumeLayout(); + + return true; + } + } +} \ No newline at end of file diff --git a/Labyrinth3/Crownwood.Magic/Docking/HotZoneTabbed.cs b/Labyrinth3/Crownwood.Magic/Docking/HotZoneTabbed.cs new file mode 100644 index 0000000..0a607fd --- /dev/null +++ b/Labyrinth3/Crownwood.Magic/Docking/HotZoneTabbed.cs @@ -0,0 +1,204 @@ +// ***************************************************************************** +// +// (c) Crownwood Consulting Limited 2002-2003 +// All rights reserved. The software and associated documentation +// supplied hereunder are the proprietary information of Crownwood Consulting +// Limited, Crownwood, Bracknell, Berkshire, England and are supplied subject +// to licence terms. +// +// Magic Version 1.7.4.0 www.dotnetmagic.com +// ***************************************************************************** + +using Crownwood.Magic.Common; +using System.Drawing; + +namespace Crownwood.Magic.Docking +{ + public class HotZoneTabbed : HotZone + { + // Class constants + protected static int _tabPageLeft = 9; + + protected static int _tabPageHeight = 25; + protected static int _tabPageWidth = 45; + + // Instance fields + protected bool _itself; + + protected Rectangle _tabRect; + protected Rectangle _tabRectTL; + protected Rectangle _tabRectTR; + protected WindowContentTabbed _wct; + + public HotZoneTabbed(Rectangle hotArea, Rectangle newSize, WindowContentTabbed wct, bool itself) + : base(hotArea, newSize) + { + // Remember state + _wct = wct; + _itself = itself; + + // Instead of a single rectangle for the dragging indicator we want to provide + // two rectangles. One for the main area and another to show a tab extending + // below it. This ensures the user can tell that it will be added as a new tab + // page of the control. + + int tabHeight = _tabPageHeight; + + // Make sure the tab rectangle does not extend past end of control + if (newSize.Height < (tabHeight + _dragWidth)) + tabHeight = newSize.Height - _dragWidth * 3; + + // Create the tab page extension + _tabRect = new Rectangle(newSize.X + _tabPageLeft, + newSize.Bottom - tabHeight, + _tabPageWidth, + tabHeight); + + // Make sure tab rectangle does not draw off right side of control + if (_tabRect.Right > newSize.Right) + _tabRect.Width -= _tabRect.Right - newSize.Right; + + // We want the intersection between the top left and top right corners to be displayed + _tabRectTL = new Rectangle(_tabRect.X, _tabRect.Y, _dragWidth, _dragWidth); + _tabRectTR = new Rectangle(_tabRect.Right - _dragWidth, _tabRect.Y, _dragWidth, _dragWidth); + + // Reduce the main area by the height of the above item + _newSize.Height -= tabHeight - _dragWidth; + } + + public override bool ApplyChange(Point screenPos, Redocker parent) + { + // If docking back to itself then refuse to apply the change, this will cause the + // WindowContentTabbed object to put back the content which is the desired effect + if (_itself) + return false; + + // We are only called from the RedockerContent class + RedockerContent redock = parent as RedockerContent; + + DockingManager dockingManager = redock.DockingManager; + + bool becomeFloating = (_wct.ParentZone.State == State.Floating); + + // Reduce flicker during transition + dockingManager.Container.SuspendLayout(); + + // Manageing Zones should remove display AutoHide windows + dockingManager.RemoveShowingAutoHideWindows(); + + switch (redock.DockingSource) + { + case RedockerContent.Source.RawContent: + { + // Perform State specific Restore actions + if (becomeFloating) + redock.Content.ContentBecomesFloating(); + + _wct.Contents.Add(redock.Content); + } + break; + + case RedockerContent.Source.WindowContent: + { + // Perform State specific Restore actions + if (becomeFloating) + { + foreach (Content c in redock.WindowContent.Contents) + c.ContentBecomesFloating(); + } + else + { + // If the source is leaving the Floating state then need to record Restore positions + if (redock.WindowContent.State == State.Floating) + { + foreach (Content c in redock.WindowContent.Contents) + c.ContentLeavesFloating(); + } + } + + int count = redock.WindowContent.Contents.Count; + + for (int index = 0; index < count; index++) + { + Content c = redock.WindowContent.Contents[0]; + + // Remove Content from previous WindowContent + redock.WindowContent.Contents.RemoveAt(0); + + // Add into new WindowContent + _wct.Contents.Add(c); + } + } + break; + + case RedockerContent.Source.ContentInsideWindow: + { + // Perform State specific Restore actions + if (becomeFloating) + redock.Content.ContentBecomesFloating(); + else + { + // If the source is leaving the Floating state then need to record Restore position + if (redock.Content.ParentWindowContent.State == State.Floating) + redock.Content.ContentLeavesFloating(); + } + + // Remove Content from existing WindowContent + if (redock.Content.ParentWindowContent != null) + redock.Content.ParentWindowContent.Contents.Remove(redock.Content); + + _wct.Contents.Add(redock.Content); + } + break; + + case RedockerContent.Source.FloatingForm: + { + // Perform State specific Restore actions + if (!becomeFloating) + { + // Make every Content object in the Floating Zone + // record its current state as the Floating state + redock.FloatingForm.ExitFloating(); + } + + int wCount = redock.FloatingForm.Zone.Windows.Count; + + for (int wIndex = 0; wIndex < wCount; wIndex++) + { + WindowContent wc = redock.FloatingForm.Zone.Windows[0] as WindowContent; + + if (wc != null) + { + int cCount = wc.Contents.Count; + + for (int cIndex = 0; cIndex < cCount; cIndex++) + { + // Get reference to first content in collection + Content c = wc.Contents[0]; + + // Remove from old WindowContent + wc.Contents.RemoveAt(0); + + // Add into new WindowContentTabbed + _wct.Contents.Add(c); + } + } + } + } + break; + } + + dockingManager.UpdateInsideFill(); + + // Reduce flicker during transition + dockingManager.Container.ResumeLayout(); + + return true; + } + + public override void DrawReversible(Rectangle rect) + { + DrawHelper.DrawDragRectangles(new Rectangle[] { rect, _tabRect, _tabRectTL, _tabRectTR }, _dragWidth); + } + } +} \ No newline at end of file diff --git a/Labyrinth3/Crownwood.Magic/Docking/Redocker.cs b/Labyrinth3/Crownwood.Magic/Docking/Redocker.cs new file mode 100644 index 0000000..548e354 --- /dev/null +++ b/Labyrinth3/Crownwood.Magic/Docking/Redocker.cs @@ -0,0 +1,69 @@ +// ***************************************************************************** +// +// (c) Crownwood Consulting Limited 2002-2003 +// All rights reserved. The software and associated documentation +// supplied hereunder are the proprietary information of Crownwood Consulting +// Limited, Crownwood, Bracknell, Berkshire, England and are supplied subject +// to licence terms. +// +// Magic Version 1.7.4.0 www.dotnetmagic.com +// ***************************************************************************** + +using System.Windows.Forms; + +namespace Crownwood.Magic.Docking +{ + public class Redocker + { + // Instance fields + protected bool _tracking; + + public Redocker() + { + // Default the state + _tracking = false; + } + + public bool Tracking + { + get { return _tracking; } + } + + public virtual void EnterTrackingMode() + { + if (!_tracking) + _tracking = true; + } + + public virtual bool ExitTrackingMode(MouseEventArgs e) + { + if (_tracking) + _tracking = false; + + return false; + } + + public virtual void QuitTrackingMode(MouseEventArgs e) + { + if (_tracking) + _tracking = false; + } + + public virtual void OnMouseMove(MouseEventArgs e) + { + } + + public virtual bool OnMouseUp(MouseEventArgs e) + { + if (_tracking) + { + if (e.Button == MouseButtons.Left) + return ExitTrackingMode(e); + else + QuitTrackingMode(e); + } + + return false; + } + } +} \ No newline at end of file diff --git a/Labyrinth3/Crownwood.Magic/Docking/RedockerContent.cs b/Labyrinth3/Crownwood.Magic/Docking/RedockerContent.cs new file mode 100644 index 0000000..d1e7b0e --- /dev/null +++ b/Labyrinth3/Crownwood.Magic/Docking/RedockerContent.cs @@ -0,0 +1,708 @@ +// ***************************************************************************** +// +// (c) Crownwood Consulting Limited 2002-2003 +// All rights reserved. The software and associated documentation +// supplied hereunder are the proprietary information of Crownwood Consulting +// Limited, Crownwood, Bracknell, Berkshire, England and are supplied subject +// to licence terms. +// +// Magic Version 1.7.4.0 www.dotnetmagic.com +// ***************************************************************************** + +using Crownwood.Magic.Collections; +using System; +using System.Collections; +using System.Drawing; +using System.Windows.Forms; + +namespace Crownwood.Magic.Docking +{ + public class RedockerContent : Redocker + { + public enum Source + { + RawContent, + ContentInsideWindow, + WindowContent, + FloatingForm + } + + // Class constants + protected static int _hotVectorFromEdge = 2; + + protected static int _hotVectorBeforeControl = 5; + + // Instance fields + protected ContainerControl _container; + + protected Source _source; + protected Content _content; + protected HotZone _currentHotZone; + protected Control _callingControl; + protected FloatingForm _floatingForm; + protected HotZoneCollection _hotZones; + protected WindowContent _windowContent; + protected DockingManager _dockingManager; + protected Rectangle _insideRect; + protected Rectangle _outsideRect; + protected Point _offset; + + public RedockerContent(Control callingControl, Content c, Point offset) + { + InternalConstruct(callingControl, Source.RawContent, c, null, null, c.DockingManager, offset); + } + + public RedockerContent(Control callingControl, Content c, WindowContent wc, Point offset) + { + InternalConstruct(callingControl, Source.ContentInsideWindow, c, wc, null, c.DockingManager, offset); + } + + public RedockerContent(Control callingControl, WindowContent wc, Point offset) + { + InternalConstruct(callingControl, Source.WindowContent, null, wc, null, wc.DockingManager, offset); + } + + public RedockerContent(FloatingForm ff, Point offset) + { + InternalConstruct(ff, Source.FloatingForm, null, null, ff, ff.DockingManager, offset); + } + + protected void InternalConstruct(Control callingControl, + Source source, + Content c, + WindowContent wc, + FloatingForm ff, + DockingManager dm, + Point offset) + { + // Store the starting state + _callingControl = callingControl; + _source = source; + _content = c; + _windowContent = wc; + _dockingManager = dm; + _container = _dockingManager.Container; + _floatingForm = ff; + _hotZones = null; + _currentHotZone = null; + _insideRect = new Rectangle(); + _outsideRect = new Rectangle(); + _offset = offset; + + // Begin tracking straight away + EnterTrackingMode(); + } + + public override void EnterTrackingMode() + { + // Have we entered tracking mode? + if (!_tracking) + { + base.EnterTrackingMode(); + + // Source must provide a valid manager instance + if (_dockingManager == null) + throw new ArgumentNullException("DockingManager"); + + // Generate the hot spots that represent actions + GenerateHotZones(); + } + } + + public override bool ExitTrackingMode(MouseEventArgs e) + { + // Have we exited tracking mode? + if (_tracking) + { + base.ExitTrackingMode(e); + + // Is there a current HotZone active? + if (_currentHotZone != null) + { + // Convert from Control coordinates to screen coordinates + Point mousePos = _callingControl.PointToScreen(new Point(e.X, e.Y)); + + // Let the zone apply whatever change it represents + return _currentHotZone.ApplyChange(mousePos, this); + } + } + + return false; + } + + public override void QuitTrackingMode(MouseEventArgs e) + { + // Have we quit tracking mode? + if (_tracking) + { + if (_callingControl.Handle != IntPtr.Zero) + { + // Remove any visible tracking indicator + if (_currentHotZone != null) + _currentHotZone.RemoveIndicator(new Point(0, 0)); + } + + base.QuitTrackingMode(e); + } + } + + public override void OnMouseMove(MouseEventArgs e) + { + if (_callingControl.Handle != IntPtr.Zero) + { + // Convert from Control coordinates to screen coordinates + Point mousePos = _callingControl.PointToScreen(new Point(e.X, e.Y)); + + // Find HotZone this position is inside + HotZone hz = _hotZones.Contains(mousePos); + + if (hz != _currentHotZone) + { + if (_currentHotZone != null) + _currentHotZone.RemoveIndicator(mousePos); + + _currentHotZone = hz; + + if (_currentHotZone != null) + _currentHotZone.DrawIndicator(mousePos); + } + else + { + if (_currentHotZone != null) + _currentHotZone.UpdateForMousePosition(mousePos, this); + } + } + + base.OnMouseMove(e); + } + + public override bool OnMouseUp(MouseEventArgs e) + { + if (_callingControl.Handle != IntPtr.Zero) + { + if (_currentHotZone != null) + _currentHotZone.RemoveIndicator(_callingControl.PointToScreen(new Point(e.X, e.Y))); + } + + return base.OnMouseUp(e); + } + + public Source DockingSource + { + get { return _source; } + } + + public Content Content + { + get { return _content; } + } + + public WindowContent WindowContent + { + get { return _windowContent; } + } + + public DockingManager DockingManager + { + get { return _dockingManager; } + } + + public FloatingForm FloatingForm + { + get { return _floatingForm; } + } + + protected void GenerateHotZones() + { + // Need the client rectangle for the whole Form + Rectangle formClient = _container.RectangleToScreen(_container.ClientRectangle); + + // Create a fresh collection for HotZones + _hotZones = new HotZoneCollection(); + + // We do not allow docking in front of the outer index entry + int outerIndex = FindOuterIndex(); + + // Create lists of Controls which are docked against each edge + ArrayList topList = new ArrayList(); + ArrayList leftList = new ArrayList(); + ArrayList rightList = new ArrayList(); + ArrayList bottomList = new ArrayList(); + ArrayList fillList = new ArrayList(); + + PreProcessControlsCollection(topList, leftList, rightList, bottomList, fillList, outerIndex); + + int vectorH; + int vectorV; + + // Find the vectors required for calculating new sizes + VectorDependsOnSourceAndState(out vectorH, out vectorV); + + GenerateHotZonesForTop(topList, formClient, vectorV, outerIndex); + GenerateHotZonesForLeft(leftList, formClient, vectorH, outerIndex); + GenerateHotZonesForRight(rightList, formClient, vectorH, outerIndex); + GenerateHotZonesForBottom(bottomList, formClient, vectorV, outerIndex); + GenerateHotZonesForFill(fillList, outerIndex); + GenerateHotZonesForFloating(SizeDependsOnSource()); + } + + protected void PreProcessControlsCollection(ArrayList topList, ArrayList leftList, ArrayList rightList, ArrayList bottomList, ArrayList fillList, int outerIndex) + { + // Find space left after all docking windows has been positioned + _insideRect = _container.ClientRectangle; + _outsideRect = _insideRect; + + // We want lists of docked controls grouped by docking style + foreach (Control item in _container.Controls) + { + bool ignoreType = (item is AutoHidePanel); + + int controlIndex = _container.Controls.IndexOf(item); + + bool outer = (controlIndex >= outerIndex); + + if (item.Visible) + { + if (item.Dock == DockStyle.Top) + { + topList.Insert(0, item); + + if (_insideRect.Y < item.Bottom) + { + _insideRect.Height -= item.Bottom - _insideRect.Y; + _insideRect.Y = item.Bottom; + } + + if (outer || ignoreType) + { + if (_outsideRect.Y < item.Bottom) + { + _outsideRect.Height -= item.Bottom - _outsideRect.Y; + _outsideRect.Y = item.Bottom; + } + } + } + + if (item.Dock == DockStyle.Left) + { + leftList.Insert(0, item); + + if (_insideRect.X < item.Right) + { + _insideRect.Width -= item.Right - _insideRect.X; + _insideRect.X = item.Right; + } + + if (outer || ignoreType) + { + if (_outsideRect.X < item.Right) + { + _outsideRect.Width -= item.Right - _outsideRect.X; + _outsideRect.X = item.Right; + } + } + } + + if (item.Dock == DockStyle.Bottom) + { + bottomList.Insert(0, item); + + if (_insideRect.Bottom > item.Top) + _insideRect.Height -= _insideRect.Bottom - item.Top; + + if (outer || ignoreType) + { + if (_outsideRect.Bottom > item.Top) + _outsideRect.Height -= _outsideRect.Bottom - item.Top; + } + } + + if (item.Dock == DockStyle.Right) + { + rightList.Insert(0, item); + + if (_insideRect.Right > item.Left) + _insideRect.Width -= _insideRect.Right - item.Left; + + if (outer || ignoreType) + { + if (_outsideRect.Right > item.Left) + _outsideRect.Width -= _outsideRect.Right - item.Left; + } + } + + if (item.Dock == DockStyle.Fill) + fillList.Insert(0, item); + } + } + + // Convert to screen coordinates + _insideRect = _container.RectangleToScreen(_insideRect); + _outsideRect = _container.RectangleToScreen(_outsideRect); + } + + protected int FindOuterIndex() + { + // We do not allow docking in front of the outer index entry + int outerIndex = _container.Controls.Count; + + Control outerControl = _dockingManager.OuterControl; + + // If an outer control has been specified then use this as the limit + if (outerControl != null) + outerIndex = _container.Controls.IndexOf(outerControl); + + return outerIndex; + } + + protected void GenerateHotZonesForLeft(ArrayList leftList, Rectangle formClient, int vector, int outerIndex) + { + foreach (Control c in leftList) + { + bool ignoreType = (c is AutoHidePanel); + + int controlIndex = _container.Controls.IndexOf(c); + + if (!ignoreType && (controlIndex < outerIndex)) + { + // Grab the screen rectangle of the Control being processed + Rectangle hotArea = c.RectangleToScreen(c.ClientRectangle); + + // Create the rectangle for the hot area + hotArea.Width = _hotVectorBeforeControl; + + // Create the rectangle for the insertion indicator + Rectangle newSize = new Rectangle(hotArea.X, hotArea.Y, vector, hotArea.Height); + + hotArea.X += _hotVectorFromEdge; + + // Create the new HotZone used to reposition a docking content/windowcontent + _hotZones.Add(new HotZoneReposition(hotArea, newSize, State.DockLeft, controlIndex)); + + IHotZoneSource ag = c as IHotZoneSource; + + // Does this control expose an interface for its own HotZones? + if (ag != null) + ag.AddHotZones(this, _hotZones); + } + } + + // Grab the screen rectangle of the Control being processed + Rectangle fullArea = _outsideRect; + + // Create the rectangle for the hot area + fullArea.Width = _hotVectorFromEdge; + + // Create the rectangle for the insertion indicator + Rectangle fillSize = new Rectangle(fullArea.X, fullArea.Y, vector, fullArea.Height); + + _hotZones.Add(new HotZoneReposition(fullArea, fillSize, State.DockLeft, false)); + + // If performing our own InsideFill then do not dock at inner positions + if (!_dockingManager.InsideFill) + { + // Create the HotArea at the left side of the inner rectangle + Rectangle innerHotArea = new Rectangle(_insideRect.X, _insideRect.Y, _hotVectorBeforeControl, _insideRect.Height); + + // Create the rectangle for tgqhe insertion indicator + Rectangle innerNewSize = new Rectangle(innerHotArea.X, innerHotArea.Y, vector, innerHotArea.Height); + + // Create a HotZone for docking to the Left at the innermost position + _hotZones.Add(new HotZoneReposition(innerHotArea, innerNewSize, State.DockLeft, true)); + } + } + + protected void GenerateHotZonesForRight(ArrayList rightList, Rectangle formClient, int vector, int outerIndex) + { + foreach (Control c in rightList) + { + bool ignoreType = (c is AutoHidePanel); + + int controlIndex = _container.Controls.IndexOf(c); + + if (!ignoreType && (controlIndex < outerIndex)) + { + // Grab the screen rectangle of the Control being processed + Rectangle hotArea = c.RectangleToScreen(c.ClientRectangle); + + // Create the rectangle for the hot area + hotArea.X = hotArea.Right - _hotVectorBeforeControl; + hotArea.Width = _hotVectorBeforeControl; + + // Create the rectangle for the insertion indicator + Rectangle newSize = new Rectangle(hotArea.Right - vector, hotArea.Y, vector, hotArea.Height); + + hotArea.X -= _hotVectorFromEdge; + + // Create the new HotZone used to reposition a docking content/windowcontent + _hotZones.Add(new HotZoneReposition(hotArea, newSize, State.DockRight, controlIndex)); + + IHotZoneSource ag = c as IHotZoneSource; + + // Does this control expose an interface for its own HotZones? + if (ag != null) + ag.AddHotZones(this, _hotZones); + } + } + + // Grab the screen rectangle of the Control being processed + Rectangle fullArea = _outsideRect; + + // Create the rectangle for the hot area + fullArea.X = fullArea.Right - _hotVectorFromEdge; + fullArea.Width = _hotVectorFromEdge; + + // Create the rectangle for the insertion indicator + Rectangle fillSize = new Rectangle(fullArea.Right - vector, fullArea.Y, vector, fullArea.Height); + + _hotZones.Add(new HotZoneReposition(fullArea, fillSize, State.DockRight, false)); + + // If performing our own InsideFill then do not dock at inner positions + if (!_dockingManager.InsideFill) + { + // Create the HotArea at the right side of the inner rectangle + Rectangle innerHotArea = new Rectangle(_insideRect.Right - _hotVectorBeforeControl, _insideRect.Y, _hotVectorBeforeControl, _insideRect.Height); + + // Create the rectangle for the insertion indicator + Rectangle innerNewSize = new Rectangle(innerHotArea.Right - vector, innerHotArea.Y, vector, innerHotArea.Height); + + // Create a HotZone for docking to the Left at the innermost position + _hotZones.Add(new HotZoneReposition(innerHotArea, innerNewSize, State.DockRight, true)); + } + } + + protected void GenerateHotZonesForTop(ArrayList topList, Rectangle formClient, int vector, int outerIndex) + { + foreach (Control c in topList) + { + bool ignoreType = (c is AutoHidePanel); + + int controlIndex = _container.Controls.IndexOf(c); + + if (!ignoreType && (controlIndex < outerIndex)) + { + // Grab the screen rectangle of the Control being processed + Rectangle hotArea = c.RectangleToScreen(c.ClientRectangle); + + // Create the rectangle for the hot area + hotArea.Height = _hotVectorBeforeControl; + + // Create the rectangle for the insertion indicator + Rectangle newSize = new Rectangle(hotArea.X, hotArea.Y, hotArea.Width, vector); + + hotArea.Y += _hotVectorFromEdge; + + // Create the new HotZone used to reposition a docking content/windowcontent + _hotZones.Add(new HotZoneReposition(hotArea, newSize, State.DockTop, controlIndex)); + + IHotZoneSource ag = c as IHotZoneSource; + + // Does this control expose an interface for its own HotZones? + if (ag != null) + ag.AddHotZones(this, _hotZones); + } + } + + // Grab the screen rectangle of the Control being processed + Rectangle fullArea = _outsideRect; + + // Create the rectangle for the hot area + fullArea.Height = _hotVectorFromEdge; + + // Create the rectangle for the insertion indicator + Rectangle fillSize = new Rectangle(fullArea.X, fullArea.Y, fullArea.Width, vector); + + _hotZones.Add(new HotZoneReposition(fullArea, fillSize, State.DockTop, false)); + + // If performing our own InsideFill then do not dock at inner positions + if (!_dockingManager.InsideFill) + { + // Create the HotArea at the left side of the inner rectangle + Rectangle innerHotArea = new Rectangle(_insideRect.X, _insideRect.Y, _insideRect.Width, _hotVectorBeforeControl); + + // Create the rectangle for the insertion indicator + Rectangle innerNewSize = new Rectangle(innerHotArea.X, innerHotArea.Y, innerHotArea.Width, vector); + + // Create a HotZone for docking to the Left at the innermost position + _hotZones.Add(new HotZoneReposition(innerHotArea, innerNewSize, State.DockTop, true)); + } + } + + protected void GenerateHotZonesForBottom(ArrayList bottomList, Rectangle formClient, int vector, int outerIndex) + { + foreach (Control c in bottomList) + { + bool ignoreType = (c is AutoHidePanel); + + int controlIndex = _container.Controls.IndexOf(c); + + if (!ignoreType && (controlIndex < outerIndex)) + { + // Grab the screen rectangle of the Control being processed + Rectangle hotArea = c.RectangleToScreen(c.ClientRectangle); + + // Create the rectangle for the hot area + hotArea.Y = hotArea.Bottom - _hotVectorBeforeControl; + hotArea.Height = _hotVectorBeforeControl; + + // Create the rectangle for the insertion indicator + Rectangle newSize = new Rectangle(hotArea.X, hotArea.Bottom - vector, hotArea.Width, vector); + + hotArea.Y -= _hotVectorFromEdge; + + // Create the new HotZone used to reposition a docking content/windowcontent + _hotZones.Add(new HotZoneReposition(hotArea, newSize, State.DockBottom, controlIndex)); + + IHotZoneSource ag = c as IHotZoneSource; + + // Does this control expose an interface for its own HotZones? + if (ag != null) + ag.AddHotZones(this, _hotZones); + } + } + + // Grab the screen rectangle of the Control being processed + Rectangle fullArea = _outsideRect; + + // Create the rectangle for the hot area + fullArea.Y = fullArea.Bottom - _hotVectorFromEdge; + fullArea.Height = _hotVectorFromEdge; + + // Create the rectangle for the insertion indicator + Rectangle fillSize = new Rectangle(fullArea.X, fullArea.Bottom - vector, fullArea.Width, vector); + + _hotZones.Add(new HotZoneReposition(fullArea, fillSize, State.DockBottom, false)); + + // If performing our own InsideFill then do not dock at inner positions + if (!_dockingManager.InsideFill) + { + // Create the HotArea at the bottom of the inner rectangle + Rectangle innerHotArea = new Rectangle(_insideRect.X, _insideRect.Bottom - _hotVectorBeforeControl, _insideRect.Width, _hotVectorBeforeControl); + + // Create the rectangle for the insertion indicator + Rectangle innerNewSize = new Rectangle(innerHotArea.X, innerHotArea.Bottom - vector, innerHotArea.Width, vector); + + // Create a HotZone for docking to the Left at the innermost position + _hotZones.Add(new HotZoneReposition(innerHotArea, innerNewSize, State.DockBottom, true)); + } + } + + protected void GenerateHotZonesForFill(ArrayList fillList, int outerIndex) + { + foreach (Control c in fillList) + { + bool ignoreType = (c is AutoHidePanel); + + int controlIndex = _container.Controls.IndexOf(c); + + if (controlIndex < outerIndex) + { + IHotZoneSource ag = c as IHotZoneSource; + + // Does this control expose an interface for its own HotZones? + if (ag != null) + ag.AddHotZones(this, _hotZones); + } + } + } + + protected void GenerateHotZonesForFloating(Size sourceSize) + { + ContainerControl main = _dockingManager.Container; + + // Double check we have a defined container + if (main != null) + { + Form mainForm = main.FindForm(); + + // Double check we are part of a larger Form + if (mainForm != null) + { + foreach (Form f in mainForm.OwnedForms) + { + // Cannot redock entire Floatin form onto itself + if (f != _floatingForm) + { + IHotZoneSource ag = f as IHotZoneSource; + + // Does this Form expose an interface for its own HotZones? + if (ag != null) + ag.AddHotZones(this, _hotZones); + } + } + } + } + + // Applies to the entire desktop area + Rectangle hotArea = SystemInformation.VirtualScreen; + + // Position is determined by HotZone dynamically but the size is defined now + Rectangle newSize = new Rectangle(0, 0, sourceSize.Width, sourceSize.Height); + + // Generate a catch all HotZone for floating a Content + _hotZones.Add(new HotZoneFloating(hotArea, newSize, _offset, this)); + } + + protected void VectorDependsOnSourceAndState(out int vectorH, out int vectorV) + { + Size sourceSize = SizeDependsOnSource(); + + switch (_source) + { + case Source.FloatingForm: + // Make sure the vector is the smaller of the two dimensions + if (sourceSize.Width > sourceSize.Height) + sourceSize.Width = sourceSize.Height; + + if (sourceSize.Height > sourceSize.Width) + sourceSize.Height = sourceSize.Width; + + // Do not let the new vector extend beyond halfway + if (sourceSize.Width > (_container.Width / 2)) + sourceSize.Width = _container.Width / 2; + + if (sourceSize.Height > (_container.Height / 2)) + sourceSize.Height = _container.Height / 2; + break; + + case Source.WindowContent: + case Source.ContentInsideWindow: + switch (_windowContent.State) + { + case State.DockLeft: + case State.DockRight: + vectorH = sourceSize.Width; + vectorV = vectorH; + return; + + case State.DockTop: + case State.DockBottom: + vectorH = sourceSize.Height; + vectorV = vectorH; + return; + } + break; + } + + vectorV = sourceSize.Height; + vectorH = sourceSize.Width; + } + + protected Size SizeDependsOnSource() + { + switch (_source) + { + case Source.WindowContent: + return _windowContent.Size; + + case Source.FloatingForm: + return _floatingForm.Size; + + case Source.RawContent: + case Source.ContentInsideWindow: + default: + return _content.DisplaySize; + } + } + } +} \ No newline at end of file diff --git a/Labyrinth3/Crownwood.Magic/Docking/Restore.cs b/Labyrinth3/Crownwood.Magic/Docking/Restore.cs new file mode 100644 index 0000000..eaded79 --- /dev/null +++ b/Labyrinth3/Crownwood.Magic/Docking/Restore.cs @@ -0,0 +1,970 @@ +// ***************************************************************************** +// +// (c) Crownwood Consulting Limited 2002-2003 +// All rights reserved. The software and associated documentation +// supplied hereunder are the proprietary information of Crownwood Consulting +// Limited, Crownwood, Bracknell, Berkshire, England and are supplied subject +// to licence terms. +// +// Magic Version 1.7.4.0 www.dotnetmagic.com +// ***************************************************************************** + +using Crownwood.Magic.Collections; +using Crownwood.Magic.Common; +using System; +using System.Drawing; +using System.Windows.Forms; +using System.Xml; + +namespace Crownwood.Magic.Docking +{ + public class Restore + { + // Instance fields + protected Restore _child; + + public Restore() + { + // Default state + _child = null; + } + + public Restore(Restore child) + { + // Remember parameter + _child = child; + } + + public Restore Child + { + get { return _child; } + set { _child = value; } + } + + public virtual void PerformRestore(DockingManager dm) + { + } + + public virtual void PerformRestore(Window w) + { + } + + public virtual void PerformRestore(Zone z) + { + } + + public virtual void PerformRestore() + { + } + + public virtual void Reconnect(DockingManager dm) + { + if (_child != null) + _child.Reconnect(dm); + } + + public virtual void SaveToXml(XmlTextWriter xmlOut) + { + // Must define my type so loading can recreate my instance + xmlOut.WriteAttributeString("Type", this.GetType().ToString()); + + SaveInternalToXml(xmlOut); + + // Output the child object + xmlOut.WriteStartElement("Child"); + + if (_child == null) + xmlOut.WriteAttributeString("Type", "null"); + else + _child.SaveToXml(xmlOut); + + xmlOut.WriteEndElement(); + } + + public virtual void LoadFromXml(XmlTextReader xmlIn, int formatVersion) + { + LoadInternalFromXml(xmlIn, formatVersion); + + // Move to next xml node + if (!xmlIn.Read()) + throw new ArgumentException("Could not read in next expected node"); + + // Check it has the expected name + if (xmlIn.Name != "Child") + throw new ArgumentException("Node 'Child' expected but not found"); + + string type = xmlIn.GetAttribute(0); + + if (type != "null") + _child = CreateFromXml(xmlIn, false, formatVersion); + + // 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"); + } + + public virtual void SaveInternalToXml(XmlTextWriter xmlOut) + { + } + + public virtual void LoadInternalFromXml(XmlTextReader xmlIn, int formatVersion) + { + } + + public static Restore CreateFromXml(XmlTextReader xmlIn, bool readIn, int formatVersion) + { + if (readIn) + { + // Move to next xml node + if (!xmlIn.Read()) + throw new ArgumentException("Could not read in next expected node"); + } + + // Grab type name of the object to create + string attrType = xmlIn.GetAttribute(0); + + // Convert from string to a Type description object + Type newType = Type.GetType(attrType); + + // Create an instance of this object which must derive from Restore base class + Restore newRestore = newType.Assembly.CreateInstance(attrType) as Restore; + + // Ask the object to load itself + newRestore.LoadFromXml(xmlIn, formatVersion); + + return newRestore; + } + } + + public class RestoreContent : Restore + { + // Instance fields + protected String _title; + + protected Content _content; + + public RestoreContent() + : base() + { + // Default state + _title = ""; + _content = null; + } + + public RestoreContent(Content content) + : base() + { + // Remember parameter + _title = content.Title; + _content = content; + } + + public RestoreContent(Restore child, Content content) + : base(child) + { + // Remember parameter + _title = content.Title; + _content = content; + } + + public override void Reconnect(DockingManager dm) + { + // Connect to the current instance of required content object + _content = dm.Contents[_title]; + + base.Reconnect(dm); + } + + public override void SaveInternalToXml(XmlTextWriter xmlOut) + { + base.SaveInternalToXml(xmlOut); + xmlOut.WriteStartElement("Content"); + xmlOut.WriteAttributeString("Name", _content.Title); + xmlOut.WriteEndElement(); + } + + public override void LoadInternalFromXml(XmlTextReader xmlIn, int formatVersion) + { + base.LoadInternalFromXml(xmlIn, formatVersion); + + // Move to next xml node + if (!xmlIn.Read()) + throw new ArgumentException("Could not read in next expected node"); + + // Check it has the expected name + if (xmlIn.Name != "Content") + throw new ArgumentException("Node 'Content' expected but not found"); + + // Grab type name of the object to create + _title = xmlIn.GetAttribute(0); + } + } + + public class RestoreContentState : RestoreContent + { + // Instance fields + protected State _state; + + public RestoreContentState() + : base() + { + } + + public RestoreContentState(State state, Content content) + : base(content) + { + // Remember parameter + _state = state; + } + + public RestoreContentState(Restore child, State state, Content content) + : base(child, content) + { + // Remember parameter + _state = state; + } + + public override void PerformRestore(DockingManager dm) + { + // Use the existing DockingManager method that will create a Window appropriate for + // this Content and then add a new Zone for hosting the Window. It will always place + // the Zone at the inner most level + dm.AddContentWithState(_content, _state); + } + + public override void SaveInternalToXml(XmlTextWriter xmlOut) + { + base.SaveInternalToXml(xmlOut); + xmlOut.WriteStartElement("State"); + xmlOut.WriteAttributeString("Value", _state.ToString()); + xmlOut.WriteEndElement(); + } + + public override void LoadInternalFromXml(XmlTextReader xmlIn, int formatVersion) + { + base.LoadInternalFromXml(xmlIn, formatVersion); + + // Move to next xml node + if (!xmlIn.Read()) + throw new ArgumentException("Could not read in next expected node"); + + // Check it has the expected name + if (xmlIn.Name != "State") + throw new ArgumentException("Node 'State' expected but not found"); + + // Grab type state of the object to create + string attrState = xmlIn.GetAttribute(0); + + // Convert from string to enumeration value + _state = (State)Enum.Parse(typeof(State), attrState); + } + } + + public class RestoreAutoHideState : RestoreContentState + { + // Instance fields + + public RestoreAutoHideState() + : base() + { + } + + public RestoreAutoHideState(State state, Content content) + : base(state, content) + { + } + + public RestoreAutoHideState(Restore child, State state, Content content) + : base(child, state, content) + { + } + + public override void PerformRestore(DockingManager dm) + { + // Create collection of Contents to auto hide + ContentCollection cc = new ContentCollection(); + + // In this case, there is only one + cc.Add(_content); + + // Add to appropriate AutoHidePanel based on _state + dm.AutoHideContents(cc, _state); + } + } + + public class RestoreAutoHideAffinity : RestoreAutoHideState + { + // Instance fields + protected StringCollection _next; + + protected StringCollection _previous; + protected StringCollection _nextAll; + protected StringCollection _previousAll; + + public RestoreAutoHideAffinity() + : base() + { + // Must always point to valid reference + _next = new StringCollection(); + _previous = new StringCollection(); + _nextAll = new StringCollection(); + _previousAll = new StringCollection(); + } + + public RestoreAutoHideAffinity(Restore child, + State state, + Content content, + StringCollection next, + StringCollection previous, + StringCollection nextAll, + StringCollection previousAll) + : base(child, state, content) + { + // Remember parameters + _next = next; + _previous = previous; + _nextAll = nextAll; + _previousAll = previousAll; + } + + public override void PerformRestore(DockingManager dm) + { + // Get the correct target panel from state + AutoHidePanel ahp = dm.AutoHidePanelForState(_state); + + ahp.AddContent(_content, _next, _previous, _nextAll, _previousAll); + } + + public override void SaveInternalToXml(XmlTextWriter xmlOut) + { + base.SaveInternalToXml(xmlOut); + _next.SaveToXml("Next", xmlOut); + _previous.SaveToXml("Previous", xmlOut); + _nextAll.SaveToXml("NextAll", xmlOut); + _previousAll.SaveToXml("PreviousAll", xmlOut); + } + + public override void LoadInternalFromXml(XmlTextReader xmlIn, int formatVersion) + { + base.LoadInternalFromXml(xmlIn, formatVersion); + _next.LoadFromXml("Next", xmlIn); + _previous.LoadFromXml("Previous", xmlIn); + _nextAll.LoadFromXml("NextAll", xmlIn); + _previousAll.LoadFromXml("PreviousAll", xmlIn); + } + } + + public class RestoreContentDockingAffinity : RestoreContentState + { + // Instance fields + protected Size _size; + + protected Point _location; + protected StringCollection _best; + protected StringCollection _next; + protected StringCollection _previous; + protected StringCollection _nextAll; + protected StringCollection _previousAll; + + public RestoreContentDockingAffinity() + : base() + { + // Must always point to valid reference + _best = new StringCollection(); + _next = new StringCollection(); + _previous = new StringCollection(); + _nextAll = new StringCollection(); + _previousAll = new StringCollection(); + } + + public RestoreContentDockingAffinity(Restore child, + State state, + Content content, + StringCollection best, + StringCollection next, + StringCollection previous, + StringCollection nextAll, + StringCollection previousAll) + : base(child, state, content) + { + // Remember parameters + _best = best; + _next = next; + _previous = previous; + _nextAll = nextAll; + _previousAll = previousAll; + _size = content.DisplaySize; + _location = content.DisplayLocation; + } + + public override void PerformRestore(DockingManager dm) + { + int count = dm.Container.Controls.Count; + + int min = -1; + int max = count; + + if (dm.InnerControl != null) + min = dm.Container.Controls.IndexOf(dm.InnerControl); + + if (dm.OuterControl != null) + max = dm.OuterControlIndex(); + + int beforeIndex = -1; + int afterIndex = max; + int beforeAllIndex = -1; + int afterAllIndex = max; + + // Create a collection of the Zones in the appropriate direction + for (int index = 0; index < count; index++) + { + Zone z = dm.Container.Controls[index] as Zone; + + if (z != null) + { + StringCollection sc = ZoneHelper.ContentNames(z); + + if (_state == z.State) + { + if (sc.Contains(_best)) + { + // Can we delegate to a child Restore object + if (_child != null) + _child.PerformRestore(z); + else + { + // Just add an appropriate Window to start of the Zone + dm.AddContentToZone(_content, z, 0); + } + return; + } + + // If the WindowContent contains a Content previous to the target + if (sc.Contains(_previous)) + { + if (index > beforeIndex) + beforeIndex = index; + } + + // If the WindowContent contains a Content next to the target + if (sc.Contains(_next)) + { + if (index < afterIndex) + afterIndex = index; + } + } + else + { + // If the WindowContent contains a Content previous to the target + if (sc.Contains(_previousAll)) + { + if (index > beforeAllIndex) + beforeAllIndex = index; + } + + // If the WindowContent contains a Content next to the target + if (sc.Contains(_nextAll)) + { + if (index < afterAllIndex) + afterAllIndex = index; + } + } + } + } + + dm.Container.SuspendLayout(); + + // Create a new Zone with correct State + Zone newZ = dm.CreateZoneForContent(_state); + + // Restore the correct content size/location values + _content.DisplaySize = _size; + _content.DisplayLocation = _location; + + // Add an appropriate Window to start of the Zone + dm.AddContentToZone(_content, newZ, 0); + + // Did we find a valid 'before' Zone? + if (beforeIndex != -1) + { + // Try and place more accurately according to other edge Zones + if (beforeAllIndex > beforeIndex) + beforeIndex = beforeAllIndex; + + // Check against limits + if (beforeIndex >= max) + beforeIndex = max - 1; + + dm.Container.Controls.SetChildIndex(newZ, beforeIndex + 1); + } + else + { + // Try and place more accurately according to other edge Zones + if (afterAllIndex < afterIndex) + afterIndex = afterAllIndex; + + // Check against limits + if (afterIndex <= min) + afterIndex = min + 1; + + if (afterIndex > min) + dm.Container.Controls.SetChildIndex(newZ, afterIndex); + else + { + // Set the Zone to be the least important of our Zones + dm.ReorderZoneToInnerMost(newZ); + } + } + + dm.Container.ResumeLayout(); + } + + public override void SaveInternalToXml(XmlTextWriter xmlOut) + { + base.SaveInternalToXml(xmlOut); + xmlOut.WriteStartElement("Position"); + xmlOut.WriteAttributeString("Size", ConversionHelper.SizeToString(_size)); + xmlOut.WriteAttributeString("Location", ConversionHelper.PointToString(_location)); + xmlOut.WriteEndElement(); + _best.SaveToXml("Best", xmlOut); + _next.SaveToXml("Next", xmlOut); + _previous.SaveToXml("Previous", xmlOut); + _nextAll.SaveToXml("NextAll", xmlOut); + _previousAll.SaveToXml("PreviousAll", xmlOut); + } + + public override void LoadInternalFromXml(XmlTextReader xmlIn, int formatVersion) + { + base.LoadInternalFromXml(xmlIn, formatVersion); + + // Move to next xml node + if (!xmlIn.Read()) + throw new ArgumentException("Could not read in next expected node"); + + // Check it has the expected name + if (xmlIn.Name != "Position") + throw new ArgumentException("Node 'Position' expected but not found"); + + // Grab raw position information + string attrSize = xmlIn.GetAttribute(0); + string attrLocation = xmlIn.GetAttribute(1); + + // Convert from string to proper types + _size = ConversionHelper.StringToSize(attrSize); + _location = ConversionHelper.StringToPoint(attrLocation); + + _best.LoadFromXml("Best", xmlIn); + _next.LoadFromXml("Next", xmlIn); + _previous.LoadFromXml("Previous", xmlIn); + _nextAll.LoadFromXml("NextAll", xmlIn); + _previousAll.LoadFromXml("PreviousAll", xmlIn); + } + } + + public class RestoreContentFloatingAffinity : RestoreContentState + { + // Instance fields + protected Size _size; + + protected Point _location; + protected StringCollection _best; + protected StringCollection _associates; + + public RestoreContentFloatingAffinity() + : base() + { + // Must always point to valid reference + _best = new StringCollection(); + _associates = new StringCollection(); + } + + public RestoreContentFloatingAffinity(Restore child, + State state, + Content content, + StringCollection best, + StringCollection associates) + : base(child, state, content) + { + // Remember parameters + _best = best; + _associates = associates; + _size = content.DisplaySize; + _location = content.DisplayLocation; + + // Remove target from collection of friends + if (_best.Contains(content.Title)) + _best.Remove(content.Title); + + // Remove target from collection of associates + if (_associates.Contains(content.Title)) + _associates.Remove(content.Title); + } + + public override void PerformRestore(DockingManager dm) + { + // Grab a list of all floating forms + Form[] owned = dm.Container.FindForm().OwnedForms; + + FloatingForm target = null; + + // Find the match to one of our best friends + foreach (Form f in owned) + { + FloatingForm ff = f as FloatingForm; + + if (ff != null) + { + if (ZoneHelper.ContentNames(ff.Zone).Contains(_best)) + { + target = ff; + break; + } + } + } + + // If no friends then try associates as second best option + if (target == null) + { + // Find the match to one of our best friends + foreach (Form f in owned) + { + FloatingForm ff = f as FloatingForm; + + if (ff != null) + { + if (ZoneHelper.ContentNames(ff.Zone).Contains(_associates)) + { + target = ff; + break; + } + } + } + } + + // If we found a friend/associate, then restore to it + if (target != null) + { + // We should have a child and be able to restore to its Zone + _child.PerformRestore(target.Zone); + } + else + { + // Restore its location/size + _content.DisplayLocation = _location; + _content.DisplaySize = _size; + + // Use the docking manage method to create us a new Floating Window at correct size/location + dm.AddContentWithState(_content, State.Floating); + } + } + + public override void SaveInternalToXml(XmlTextWriter xmlOut) + { + base.SaveInternalToXml(xmlOut); + xmlOut.WriteStartElement("Position"); + xmlOut.WriteAttributeString("Size", ConversionHelper.SizeToString(_size)); + xmlOut.WriteAttributeString("Location", ConversionHelper.PointToString(_location)); + xmlOut.WriteEndElement(); + _best.SaveToXml("Best", xmlOut); + _associates.SaveToXml("Associates", xmlOut); + } + + public override void LoadInternalFromXml(XmlTextReader xmlIn, int formatVersion) + { + base.LoadInternalFromXml(xmlIn, formatVersion); + + // Move to next xml node + if (!xmlIn.Read()) + throw new ArgumentException("Could not read in next expected node"); + + // Check it has the expected name + if (xmlIn.Name != "Position") + throw new ArgumentException("Node 'Position' expected but not found"); + + // Grab raw position information + string attrSize = xmlIn.GetAttribute(0); + string attrLocation = xmlIn.GetAttribute(1); + + // Convert from string to proper types + _size = ConversionHelper.StringToSize(attrSize); + _location = ConversionHelper.StringToPoint(attrLocation); + + _best.LoadFromXml("Best", xmlIn); + _associates.LoadFromXml("Associates", xmlIn); + } + } + + public class RestoreZoneAffinity : RestoreContent + { + // Instance fields + protected Decimal _space; + + protected StringCollection _best; + protected StringCollection _next; + protected StringCollection _previous; + + public RestoreZoneAffinity() + : base() + { + // Default state + _space = 50m; + + // Must always point to valid reference + _best = new StringCollection(); + _next = new StringCollection(); + _previous = new StringCollection(); + } + + public RestoreZoneAffinity(Restore child, + Content content, + StringCollection best, + StringCollection next, + StringCollection previous) + : base(child, content) + { + // Remember parameters + _best = best; + _next = next; + _previous = previous; + + if (content.Visible) + _space = content.ParentWindowContent.ZoneArea; + else + _space = 50m; + } + + public override void PerformRestore(Zone z) + { + int count = z.Windows.Count; + int beforeIndex = -1; + int afterIndex = count; + + // Find the match to one of our best friends + for (int index = 0; index < count; index++) + { + WindowContent wc = z.Windows[index] as WindowContent; + + if (wc != null) + { + // If this WindowContent contains a best friend, then add ourself here as well + if (wc.Contents.Contains(_best)) + { + if (_child == null) + { + // If we do not have a Restore object for the Window then just add + // into the WindowContent at the end of the existing Contents + wc.Contents.Add(_content); + } + else + { + // Get the child to restore as best as possible inside WindowContent + _child.PerformRestore(wc); + } + + return; + } + + // If the WindowContent contains a Content previous to the target + if (wc.Contents.Contains(_previous)) + { + if (index > beforeIndex) + beforeIndex = index; + } + + // If the WindowContent contains a Content next to the target + if (wc.Contents.Contains(_next)) + { + if (index < afterIndex) + afterIndex = index; + } + } + } + + // If we get here then we did not find any best friends, this + // means we need to create a new WindowContent to host the Content. + Window newW = z.DockingManager.CreateWindowForContent(_content); + + ZoneSequence zs = z as ZoneSequence; + + // If this is inside a ZoneSequence instance + if (zs != null) + { + // Do not reposition the Windows on the .Insert but instead ignore the + // reposition and let it happen in the .ModifyWindowSpace. This reduces + // the flicker that would occur otherwise + zs.SuppressReposition(); + } + + // Need to find the best place in the order for the Content, start by + // looking for the last 'previous' content and place immediately after it + if (beforeIndex >= 0) + { + // Great, insert after it + z.Windows.Insert(beforeIndex + 1, newW); + } + else + { + // No joy, so find the first 'next' content and place just before it, if + // none are found then just add to the end of the collection. + z.Windows.Insert(afterIndex, newW); + } + + // If this is inside a ZoneSequence instance + if (zs != null) + { + // We want to try and allocate the correct Zone space + zs.ModifyWindowSpace(newW, _space); + } + } + + public override void SaveInternalToXml(XmlTextWriter xmlOut) + { + base.SaveInternalToXml(xmlOut); + xmlOut.WriteStartElement("Space"); + xmlOut.WriteAttributeString("Value", _space.ToString()); + xmlOut.WriteEndElement(); + _best.SaveToXml("Best", xmlOut); + _next.SaveToXml("Next", xmlOut); + _previous.SaveToXml("Previous", xmlOut); + } + + public override void LoadInternalFromXml(XmlTextReader xmlIn, int formatVersion) + { + base.LoadInternalFromXml(xmlIn, formatVersion); + + // Move to next xml node + if (!xmlIn.Read()) + throw new ArgumentException("Could not read in next expected node"); + + // Check it has the expected name + if (xmlIn.Name != "Space") + throw new ArgumentException("Node 'Space' expected but not found"); + + // Grab raw position information + string attrSpace = xmlIn.GetAttribute(0); + + // Convert from string to proper type + _space = Decimal.Parse(attrSpace); + + _best.LoadFromXml("Best", xmlIn); + _next.LoadFromXml("Next", xmlIn); + _previous.LoadFromXml("Previous", xmlIn); + } + } + + public class RestoreWindowContent : RestoreContent + { + // Instance fields + protected bool _selected; + + protected StringCollection _next; + protected StringCollection _previous; + + public RestoreWindowContent() + : base() + { + // Must always point to valid reference + _selected = false; + _next = new StringCollection(); + _previous = new StringCollection(); + } + + public RestoreWindowContent(Restore child, + Content content, + StringCollection next, + StringCollection previous, + bool selected) + : base(child, content) + { + // Remember parameters + _selected = selected; + _next = next; + _previous = previous; + } + + public override void PerformRestore(Window w) + { + // We are only ever called for a WindowContent object + WindowContent wc = w as WindowContent; + + int bestIndex = -1; + + foreach (String s in _previous) + { + if (wc.Contents.Contains(s)) + { + int previousIndex = wc.Contents.IndexOf(wc.Contents[s]); + + if (previousIndex > bestIndex) + bestIndex = previousIndex; + } + } + + // Did we find a previous Content? + if (bestIndex >= 0) + { + // Great, insert after it + wc.Contents.Insert(bestIndex + 1, _content); + } + else + { + bestIndex = wc.Contents.Count; + + foreach (String s in _next) + { + if (wc.Contents.Contains(s)) + { + int nextIndex = wc.Contents.IndexOf(wc.Contents[s]); + + if (nextIndex < bestIndex) + bestIndex = nextIndex; + } + } + + // Insert before the found entry (or at end if non found) + wc.Contents.Insert(bestIndex, _content); + } + + // Should this content become selected? + if (_selected) + _content.BringToFront(); + } + + public override void SaveInternalToXml(XmlTextWriter xmlOut) + { + base.SaveInternalToXml(xmlOut); + _next.SaveToXml("Next", xmlOut); + _previous.SaveToXml("Previous", xmlOut); + + xmlOut.WriteStartElement("Selected"); + xmlOut.WriteAttributeString("Value", _selected.ToString()); + xmlOut.WriteEndElement(); + } + + public override void LoadInternalFromXml(XmlTextReader xmlIn, int formatVersion) + { + base.LoadInternalFromXml(xmlIn, formatVersion); + _next.LoadFromXml("Next", xmlIn); + _previous.LoadFromXml("Previous", xmlIn); + + // _selected added in version 4 format + if (formatVersion >= 4) + { + // Move to next xml node + if (!xmlIn.Read()) + throw new ArgumentException("Could not read in next expected node"); + + // Check it has the expected name + if (xmlIn.Name != "Selected") + throw new ArgumentException("Node 'Selected' expected but not found"); + + // Convert attribute value to boolean value + _selected = Convert.ToBoolean(xmlIn.GetAttribute(0)); + } + } + } +} \ No newline at end of file diff --git a/Labyrinth3/Crownwood.Magic/Docking/TabStub.cs b/Labyrinth3/Crownwood.Magic/Docking/TabStub.cs new file mode 100644 index 0000000..4330052 --- /dev/null +++ b/Labyrinth3/Crownwood.Magic/Docking/TabStub.cs @@ -0,0 +1,984 @@ +// ***************************************************************************** +// +// (c) Crownwood Consulting Limited 2002-2003 +// All rights reserved. The software and associated documentation +// supplied hereunder are the proprietary information of Crownwood Consulting +// Limited, Crownwood, Bracknell, Berkshire, England and are supplied subject +// to licence terms. +// +// Magic Version 1.7.4.0 www.dotnetmagic.com +// ***************************************************************************** + +using Crownwood.Magic.Collections; + +//using Crownwood.Magic.Win32; +using Crownwood.Magic.Common; +using Microsoft.Win32; +using System; +using System.Collections; +using System.ComponentModel; +using System.Drawing; +using System.Windows.Forms; + +namespace Crownwood.Magic.Docking +{ + [ToolboxItem(false)] + public class TabStub : UserControl + { + private class DrawTab + { + protected int _index; + protected Rectangle _drawRect; + protected Crownwood.Magic.Controls.TabPage _tabPage; + + public DrawTab(Crownwood.Magic.Controls.TabPage tabPage, Rectangle drawRect, int index) + { + _index = index; + _tabPage = tabPage; + _drawRect = drawRect; + } + + public Crownwood.Magic.Controls.TabPage TabPage { get { return _tabPage; } } + public Rectangle DrawRect { get { return _drawRect; } } + public int Index { get { return _index; } } + } + + // Class constants + protected static int _imageGap = 3; + + protected static int _imageGaps = 6; + protected static int _imageVector = 16; + protected static int _beginGap = 2; + protected static int _endGap = 8; + protected static int _sideGap = 2; + protected static int _hoverInterval = 500; + + // Instance fields + protected Edge _edge; + + protected int _hoverOver; + protected int _hoverItem; + protected int _selectedIndex; + protected bool _defaultFont; + protected bool _defaultColor; + protected Color _backIDE; + protected Timer _hoverTimer; + protected TabPageCollection _tabPages; + protected WindowContentTabbed _wct; + protected ArrayList _drawTabs; + protected VisualStyle _style; + + public delegate void TabStubIndexHandler(TabStub sender, int pageIndex); + + public delegate void TabStubHandler(TabStub sender); + + // Exposed events + public event TabStubIndexHandler PageClicked; + + public event TabStubIndexHandler PageOver; + + public event TabStubHandler PagesLeave; + + public TabStub(VisualStyle style) + { + // Default state + _wct = null; + _style = style; + _hoverOver = -1; + _hoverItem = -1; + _selectedIndex = -1; + _defaultFont = true; + _defaultColor = true; + _edge = Edge.None; + _drawTabs = new ArrayList(); + _tabPages = new TabPageCollection(); + base.Font = SystemInformation.MenuFont; + + // Hookup to collection events + _tabPages.Cleared += new CollectionClear(OnClearedPages); + _tabPages.Inserted += new CollectionChange(OnInsertedPage); + _tabPages.Removing += new CollectionChange(OnRemovingPage); + _tabPages.Removed += new CollectionChange(OnRemovedPage); + + // Need notification when the MenuFont is changed + Microsoft.Win32.SystemEvents.UserPreferenceChanged += new + UserPreferenceChangedEventHandler(OnPreferenceChanged); + + // Default default colors + DefineBackColor(SystemColors.Control); + + // Create the Timer for handling hovering over items + _hoverTimer = new Timer(); + _hoverTimer.Interval = _hoverInterval; + _hoverTimer.Tick += new EventHandler(OnTimerExpire); + } + + protected override void Dispose(bool disposing) + { + if (disposing) + { + // Remove notifications + Microsoft.Win32.SystemEvents.UserPreferenceChanged -= new + UserPreferenceChangedEventHandler(OnPreferenceChanged); + } + base.Dispose(disposing); + } + + public TabPageCollection TabPages + { + get { return _tabPages; } + + set + { + _tabPages.Clear(); + _tabPages = value; + } + } + + public Edge Edging + { + get { return _edge; } + + set + { + if (value != _edge) + { + _edge = value; + ResizeControl(); + Recalculate(); + Invalidate(); + } + } + } + + public int SelectedIndex + { + get { return _selectedIndex; } + + set + { + if (value != _selectedIndex) + { + _selectedIndex = value; + Recalculate(); + Invalidate(); + } + } + } + + public override Font Font + { + get { return base.Font; } + + set + { + if (value != null) + { + if (value != base.Font) + { + _defaultFont = (value == SystemInformation.MenuFont); + + base.Font = value; + ResizeControl(); + Recalculate(); + Invalidate(); + } + } + } + } + + public override Color BackColor + { + get { return base.BackColor; } + + set + { + if (this.BackColor != value) + { + _defaultColor = (value == SystemColors.Control); + DefineBackColor(value); + Invalidate(); + } + } + } + + public WindowContentTabbed WindowContentTabbed + { + get { return _wct; } + set { _wct = value; } + } + + public virtual void OnPageClicked(int pageIndex) + { + // Has anyone registered for the event? + if (PageClicked != null) + PageClicked(this, pageIndex); + } + + public virtual void OnPageOver(int pageIndex) + { + // Has anyone registered for the event? + if (PageOver != null) + PageOver(this, pageIndex); + } + + public virtual void OnPagesLeave() + { + // Has anyone registered for the event? + if (PagesLeave != null) + PagesLeave(this); + } + + public void PropogateNameValue(PropogateName name, object value) + { + switch (name) + { + case PropogateName.BackColor: + this.BackColor = (Color)value; + Invalidate(); + break; + + case PropogateName.InactiveTextColor: + this.ForeColor = (Color)value; + Invalidate(); + break; + + case PropogateName.CaptionFont: + this.Font = (Font)value; + break; + } + + // Pass onto the contained WCT + _wct.PropogateNameValue(name, value); + } + + protected void DefineBackColor(Color backColor) + { + base.BackColor = backColor; + + _backIDE = ColorHelper.TabBackgroundFromBaseColor(backColor); + } + + protected void OnPreferenceChanged(object sender, UserPreferenceChangedEventArgs e) + { + // Are we using the default menu or a user defined value? + if (_defaultFont) + { + base.Font = SystemInformation.MenuFont; + ResizeControl(); + Recalculate(); + Invalidate(); + } + } + + protected override void OnSystemColorsChanged(EventArgs e) + { + // If still using the Default color when we were created + if (_defaultColor) + { + this.BackColor = SystemColors.Control; + Invalidate(); + } + + base.OnSystemColorsChanged(e); + } + + protected void OnClearedPages() + { + // Cancel any hover selection + CancelHoverItem(); + + // Cancel any current selection + _selectedIndex = -1; + + ResizeControl(); + Recalculate(); + Invalidate(); + } + + protected void OnInsertedPage(int index, object value) + { + // If no page is currently selected + if (_selectedIndex == -1) + { + // Then make the inserted page selected + _selectedIndex = index; + } + + // Cast to correct type + Crownwood.Magic.Controls.TabPage page = value as Crownwood.Magic.Controls.TabPage; + + // Grab the content instance of the page + Content c = page.Tag as Content; + + // Hook into change in its properties + c.PropertyChanged += new Content.PropChangeHandler(OnContentChanged); + + ResizeControl(); + Recalculate(); + Invalidate(); + } + + protected void OnRemovingPage(int index, object value) + { + // Removed page involved in hover calculations? + if ((_hoverOver == index) || (_hoverItem == index)) + CancelHoverItem(); + + // Removing the last page? + if (_tabPages.Count == 1) + { + // Get rid of any selection + _selectedIndex = -1; + } + else + { + // If removing a page before the selected one... + if (index < _selectedIndex) + { + // ...then the selected index must be decremented to match + _selectedIndex--; + } + else + { + // If the selected page is the last one then... + if (_selectedIndex == (_tabPages.Count - 1)) + { + // Must reduce selected index + _selectedIndex--; + } + } + } + } + + protected void OnRemovedPage(int index, object value) + { + // Cast to correct type + Crownwood.Magic.Controls.TabPage page = value as Crownwood.Magic.Controls.TabPage; + + // Grab the content instance of the page + Content c = page.Tag as Content; + + // Unhook from change in its properties + c.PropertyChanged -= new Content.PropChangeHandler(OnContentChanged); + + ResizeControl(); + Recalculate(); + Invalidate(); + } + + protected void OnContentChanged(Content obj, Content.Property prop) + { + bool update = false; + + // Scan each tab page in turn + foreach (Crownwood.Magic.Controls.TabPage page in _tabPages) + { + // Is this the page for the changed content? + if (page.Tag == obj) + { + // Property specific processing + switch (prop) + { + case Content.Property.Title: + page.Title = obj.Title; + update = true; + break; + + case Content.Property.ImageList: + page.ImageList = obj.ImageList; + update = true; + break; + + case Content.Property.ImageIndex: + page.ImageIndex = obj.ImageIndex; + update = true; + break; + + case Content.Property.Icon: + page.Icon = obj.Icon; + update = true; + break; + } + } + + // Only interested in a single change + if (update) + break; + } + + // Any update required? + if (update) + { + ResizeControl(); + Recalculate(); + Invalidate(); + } + } + + protected void CancelHoverItem() + { + // Currently timing a hover change? + if (_hoverOver != -1) + { + // Prevent timer from expiring + _hoverTimer.Stop(); + + // No item being timed + _hoverOver = -1; + } + + // Any current hover item? + if (_hoverItem != -1) + { + // No item is being hovered + _hoverItem = -1; + + // Generate event for end of hover + OnPagesLeave(); + } + } + + protected override void OnMouseMove(MouseEventArgs e) + { + // Create a point representing current mouse position + Point mousePos = new Point(e.X, e.Y); + + int index = 0; + int count = _drawTabs.Count; + + // Search each draw cell + for (; index < count; index++) + { + DrawTab dt = _drawTabs[index] as DrawTab; + + // Is mouse over this cell? + if (dt.DrawRect.Contains(mousePos)) + { + // If the mouse is not over the hover item + if (_hoverItem != dt.Index) + { + // And we are not already timing this change in hover + if (_hoverOver != dt.Index) + { + // Start timing the hover change + _hoverTimer.Start(); + + // Remember which item we are timing + _hoverOver = dt.Index; + } + } + + break; + } + } + + // Failed to find an item? + if (index == count) + { + // If we have a hover item or timing a hover change + if ((_hoverOver != -1) || (_hoverItem != -1)) + { + // Stop any timing + CancelHoverItem(); + } + } + + base.OnMouseMove(e); + } + + protected override void OnMouseLeave(EventArgs e) + { + // Remove any hover state + CancelHoverItem(); + + base.OnMouseLeave(e); + } + + protected void OnTimerExpire(object sender, EventArgs e) + { + // Prevent the timer from firing again + _hoverTimer.Stop(); + + // A change in hover still valid? + if (_hoverItem != _hoverOver) + { + // This item becomes the current hover item + _hoverItem = _hoverOver; + + // No longer in a timing state + _hoverOver = -1; + + // Do we need a change in selection? + if (_selectedIndex != _hoverItem) + { + // Change selection and redraw + _selectedIndex = _hoverItem; + + Recalculate(); + Invalidate(); + } + + // Generate event to notify where mouse is now hovering + OnPageOver(_selectedIndex); + } + } + + protected override void OnMouseDown(MouseEventArgs e) + { + // Only select a button or page when using left mouse button + if (e.Button == MouseButtons.Left) + { + // Create a point representing current mouse position + Point mousePos = new Point(e.X, e.Y); + + int count = _drawTabs.Count; + + // Search each draw cell + for (int index = 0; index < count; index++) + { + DrawTab dt = _drawTabs[index] as DrawTab; + + // Is mouse pressed in this draw cell? + if (dt.DrawRect.Contains(mousePos)) + { + // Prevent any hover timer expiring + _hoverTimer.Stop(); + + // This becomes the current hover item + _hoverItem = _selectedIndex; + + // Not timing a hover change + _hoverOver = _hoverItem; + + // Will this cause a change in selection? + if (_selectedIndex != dt.Index) + { + // Change selection and redraw + _selectedIndex = dt.Index; + + Recalculate(); + Invalidate(); + } + + // Generate event to notify a click occured on the selection + OnPageClicked(_selectedIndex); + + break; + } + } + } + } + + public static int TabStubVector(Font font) + { + int fixedVector = _imageVector + _imageGaps; + + int minFontVector = font.Height + _imageGaps; + + // Make sure at least bit enough for the provided font + if (fixedVector < minFontVector) + fixedVector = minFontVector; + + return fixedVector + _sideGap; + } + + protected void ResizeControl() + { + int textMax = 0; + + // Find largest space needed for drawing page text + using (Graphics g = this.CreateGraphics()) + { + foreach (Crownwood.Magic.Controls.TabPage page in _tabPages) + { + // Find width of the requested text + SizeF dimension = g.MeasureString(page.Title, this.Font); + + if ((int)dimension.Width > textMax) + textMax = (int)dimension.Width; + } + } + + // Calculate total width/height needed + int variableVector = _tabPages.Count * (_imageVector + _imageGaps) + textMax + _imageGap; + + // Calculate the fixed direction value + int fixedVector = TabStubVector(this.Font); + + // Resize the control as appropriate + switch (_edge) + { + case Edge.Left: + case Edge.Right: + this.Size = new Size(fixedVector, variableVector + _beginGap + _endGap); + break; + + case Edge.Top: + case Edge.Bottom: + case Edge.None: + default: + this.Size = new Size(variableVector + _beginGap + _endGap, fixedVector); + break; + } + } + + protected void Recalculate() + { + // Create a fresh colleciton for drawing objects + _drawTabs = new ArrayList(); + + // Need start and end position markers + int posEnd; + int cellVector = _imageVector + _imageGaps; + int posStart = _beginGap; + + switch (_edge) + { + case Edge.Left: + case Edge.Right: + posEnd = this.Height - _endGap; + break; + + case Edge.Top: + case Edge.Bottom: + case Edge.None: + default: + posEnd = this.Width - _endGap; + break; + } + + int count = _tabPages.Count; + + // Process from start of list until we find the selected one + for (int index = 0; (index < count) && (index != _selectedIndex); index++) + { + Rectangle drawRect; + + // Drawing rectangle depends on direction + switch (_edge) + { + case Edge.Left: + drawRect = new Rectangle(0, posStart, this.Width - _sideGap - 1, cellVector); + break; + + case Edge.Right: + drawRect = new Rectangle(_sideGap, posStart, this.Width - _sideGap, cellVector); + break; + + case Edge.Bottom: + drawRect = new Rectangle(posStart, _sideGap, cellVector, this.Height - _sideGap); + break; + + case Edge.Top: + case Edge.None: + default: + drawRect = new Rectangle(posStart, 0, cellVector, this.Height - _sideGap - 1); + break; + } + + // Move starting position + posStart += cellVector; + + // Generate new drawing object for this tab + _drawTabs.Add(new DrawTab(_tabPages[index], drawRect, index)); + } + + // Process from end of list until we find the selected one + for (int index = count - 1; (index >= 0) && (index != _selectedIndex); index--) + { + Rectangle drawRect; + + // Drawing rectangle depends on direction + switch (_edge) + { + case Edge.Left: + drawRect = new Rectangle(0, posEnd - cellVector, this.Width - _sideGap - 1, cellVector); + break; + + case Edge.Right: + drawRect = new Rectangle(_sideGap, posEnd - cellVector, this.Width - _sideGap, cellVector); + break; + + case Edge.Bottom: + drawRect = new Rectangle(posEnd - cellVector, _sideGap, cellVector, this.Height - _sideGap); + break; + + case Edge.Top: + case Edge.None: + default: + drawRect = new Rectangle(posEnd - cellVector, 0, cellVector, this.Height - _sideGap - 1); + break; + } + + // Move starting position + posEnd -= cellVector; + + // Generate new drawing object for this tab + _drawTabs.Add(new DrawTab(_tabPages[index], drawRect, index)); + } + + if (_selectedIndex != -1) + { + Rectangle drawRect; + + // Drawing rectangle depends on direction + switch (_edge) + { + case Edge.Left: + drawRect = new Rectangle(0, posStart, this.Width - _sideGap - 1, posEnd - posStart); + break; + + case Edge.Right: + drawRect = new Rectangle(_sideGap, posStart, this.Width - _sideGap, posEnd - posStart); + break; + + case Edge.Bottom: + drawRect = new Rectangle(posStart, _sideGap, posEnd - posStart, this.Height - _sideGap); + break; + + case Edge.Top: + case Edge.None: + default: + drawRect = new Rectangle(posStart, 0, posEnd - posStart, this.Height - _sideGap - 1); + break; + } + + // Generate new drawing object for this tab + _drawTabs.Add(new DrawTab(_tabPages[_selectedIndex], drawRect, _selectedIndex)); + } + } + + protected void AdjustRectForEdge(ref Rectangle rect) + { + // Adjust rectangle to exclude desired edge + switch (_edge) + { + case Edge.Left: + rect.X--; + rect.Width++; + break; + + case Edge.Right: + rect.Width++; + break; + + case Edge.Bottom: + rect.Height++; + break; + + case Edge.Top: + case Edge.None: + default: + rect.Y--; + rect.Height++; + break; + } + } + + protected void DrawOutline(Graphics g, bool pre) + { + Rectangle borderRect = new Rectangle(0, 0, this.Width - 1, this.Height - 1); + + // Adjust for drawing area + switch (_edge) + { + case Edge.Left: + borderRect.Y += _beginGap; + borderRect.Height -= _beginGap + _endGap - 1; + borderRect.Width -= _sideGap; + break; + + case Edge.Right: + borderRect.Y += _beginGap; + borderRect.Height -= _beginGap + _endGap - 1; + borderRect.X += _sideGap; + borderRect.Width -= _sideGap; + break; + + case Edge.Bottom: + borderRect.Y += _sideGap; + borderRect.Height -= _sideGap; + borderRect.X += _beginGap; + borderRect.Width -= _beginGap + _endGap - 1; + break; + + case Edge.Top: + case Edge.None: + default: + borderRect.Height -= _sideGap; + borderRect.X += _beginGap; + borderRect.Width -= _beginGap + _endGap - 1; + break; + } + + // Remove unwated drawing edge + AdjustRectForEdge(ref borderRect); + + if (pre) + { + if (_style == VisualStyle.IDE) + { + // Fill tab area in required color + using (SolidBrush fillBrush = new SolidBrush(this.BackColor)) + g.FillRectangle(fillBrush, borderRect); + } + } + else + { + if (_style == VisualStyle.Plain) + { + using (Pen penL = new Pen(ControlPaint.LightLight(this.BackColor)), + penD = new Pen(ControlPaint.Dark(this.BackColor))) + { + g.DrawLine(penL, borderRect.Left, borderRect.Top, borderRect.Right, borderRect.Top); + g.DrawLine(penL, borderRect.Left, borderRect.Top, borderRect.Left, borderRect.Bottom); + g.DrawLine(penD, borderRect.Right, borderRect.Top, borderRect.Right, borderRect.Bottom); + g.DrawLine(penD, borderRect.Right, borderRect.Bottom, borderRect.Left, borderRect.Bottom); + } + } + } + } + + protected void DrawOutlineForCell(Graphics g, Pen pen, Rectangle rect) + { + // Draw border around the tab cell + if (_style == VisualStyle.IDE) + g.DrawRectangle(pen, rect); + else + { + switch (_edge) + { + case Edge.Left: + case Edge.Right: + g.DrawLine(pen, rect.Left + 1, rect.Bottom, rect.Right, rect.Bottom); + break; + + case Edge.Top: + case Edge.Bottom: + g.DrawLine(pen, rect.Right, rect.Top + 1, rect.Right, rect.Bottom); + break; + } + } + } + + protected override void OnPaintBackground(PaintEventArgs e) + { + } + + protected override void OnPaint(PaintEventArgs e) + { + // Fill background in required color + if (_style == VisualStyle.IDE) + using (SolidBrush fillBrush = new SolidBrush(_backIDE)) + e.Graphics.FillRectangle(fillBrush, this.ClientRectangle); + else + using (SolidBrush fillBrush = new SolidBrush(this.BackColor)) + e.Graphics.FillRectangle(fillBrush, this.ClientRectangle); + + // Style specific outline drawing + DrawOutline(e.Graphics, true); + + // Draw border around area + using (Pen borderPen = new Pen(ControlPaint.LightLight(this.ForeColor))) + { + // Draw each of the draw objects + foreach (DrawTab dt in _drawTabs) + { + Rectangle drawRect = dt.DrawRect; + + AdjustRectForEdge(ref drawRect); + + // Style specific cell outline drawing + DrawOutlineForCell(e.Graphics, borderPen, drawRect); + + // Draw the image in the left/top of the cell + Crownwood.Magic.Controls.TabPage page = dt.TabPage; + + int xDraw; + int yDraw; + + switch (_edge) + { + case Edge.Left: + case Edge.Right: + xDraw = drawRect.Left + (drawRect.Width - _imageVector) / 2; + yDraw = drawRect.Top + _imageGap; + break; + + case Edge.Top: + case Edge.Bottom: + case Edge.None: + default: + xDraw = drawRect.Left + _imageGap; + yDraw = drawRect.Top + (drawRect.Height - _imageVector) / 2; + break; + } + + if ((page.Icon != null) || ((page.ImageIndex != -1) && (page.ImageList != null))) + { + if (page.Icon != null) + { + // Draw the actual icon + e.Graphics.DrawIcon(page.Icon, new Rectangle(xDraw, yDraw, _imageVector, _imageVector)); + } + else + { + // Draw the actual image + e.Graphics.DrawImage(page.ImageList.Images[page.ImageIndex], + new Rectangle(xDraw, yDraw, _imageVector, _imageVector)); + } + } + + // Is anything currently selected + if (_selectedIndex != -1) + { + // Is this page selected? + + if (page == _tabPages[_selectedIndex]) + { + Rectangle textRect; + + StringFormat drawFormat = new StringFormat(); + drawFormat.FormatFlags = StringFormatFlags.NoClip | StringFormatFlags.NoWrap; + drawFormat.Alignment = StringAlignment.Center; + drawFormat.LineAlignment = StringAlignment.Center; + + // Create text drawing rectangle + switch (_edge) + { + case Edge.Left: + case Edge.Right: + textRect = new Rectangle(drawRect.Left, yDraw + _imageVector + _imageGap, + drawRect.Width, drawRect.Height - _imageVector - _imageGap * 2); + drawFormat.FormatFlags |= StringFormatFlags.DirectionVertical; + break; + + case Edge.Top: + case Edge.Bottom: + case Edge.None: + default: + textRect = new Rectangle(xDraw + _imageVector + _imageGap, drawRect.Top, + drawRect.Width - _imageVector - _imageGap * 2, drawRect.Height); + break; + } + + Color brushColor = this.ForeColor; + + if (_style == VisualStyle.IDE) + brushColor = ControlPaint.Light(brushColor); + + using (SolidBrush drawBrush = new SolidBrush(brushColor)) + e.Graphics.DrawString(page.Title, this.Font, drawBrush, textRect, drawFormat); + } + } + } + } + + // Style specific outline drawing + DrawOutline(e.Graphics, false); + + base.OnPaint(e); + } + } +} \ No newline at end of file diff --git a/Labyrinth3/Crownwood.Magic/Docking/Window.cs b/Labyrinth3/Crownwood.Magic/Docking/Window.cs new file mode 100644 index 0000000..e050693 --- /dev/null +++ b/Labyrinth3/Crownwood.Magic/Docking/Window.cs @@ -0,0 +1,308 @@ +// ***************************************************************************** +// +// (c) Crownwood Consulting Limited 2002-2003 +// All rights reserved. The software and associated documentation +// supplied hereunder are the proprietary information of Crownwood Consulting +// Limited, Crownwood, Bracknell, Berkshire, England and are supplied subject +// to licence terms. +// +// Magic Version 1.7.4.0 www.dotnetmagic.com +// ***************************************************************************** + +using Crownwood.Magic.Collections; +using System; +using System.ComponentModel; +using System.Drawing; +using System.Windows.Forms; + +namespace Crownwood.Magic.Docking +{ + [ToolboxItem(false)] + public class Window : ContainerControl + { + // Instance fields + protected State _state; + + protected Zone _parentZone; + protected WindowDetailCollection _windowDetails; + protected Decimal _zoneArea; + protected Size _minimalSize; + protected DockingManager _manager; + protected bool _autoDispose; + protected bool _redockAllowed; + protected bool _floatingCaption; + protected bool _contentCaption; + protected string _fullTitle; + + // Instance events + public event EventHandler FullTitleChanged; + + public Window(DockingManager manager) + { + // Must provide a valid manager instance + if (manager == null) + throw new ArgumentNullException("DockingManager"); + + // Default object state + _state = State.Floating; + _parentZone = null; + _zoneArea = 100m; + _minimalSize = new Size(0, 0); + _manager = manager; + _autoDispose = true; + _fullTitle = ""; + _redockAllowed = true; + _floatingCaption = true; + _contentCaption = true; + + // Create collection of window details + _windowDetails = new WindowDetailCollection(); + + // We want notification when window details are added/removed/cleared + _windowDetails.Clearing += new CollectionClear(OnDetailsClearing); + _windowDetails.Inserted += new CollectionChange(OnDetailInserted); + _windowDetails.Removing += new CollectionChange(OnDetailRemoving); + } + + public DockingManager DockingManager + { + get { return _manager; } + } + + public State State + { + get { return _state; } + + set + { + if (_state != value) + { + _state = value; + + // Inform each window detail of the change in state + foreach (WindowDetail wd in _windowDetails) + wd.ParentStateChanged(_state); + } + } + } + + public Zone ParentZone + { + get { return _parentZone; } + + set + { + if (_parentZone != value) + { + _parentZone = value; + + // Inform each window detail of the change in zone + foreach (WindowDetail wd in _windowDetails) + wd.ParentZone = _parentZone; + } + } + } + + public WindowDetailCollection WindowDetails + { + get { return _windowDetails; } + + set + { + _windowDetails.Clear(); + _windowDetails = value; + } + } + + public Decimal ZoneArea + { + get { return _zoneArea; } + set { _zoneArea = value; } + } + + public Size MinimalSize + { + get { return _minimalSize; } + set { _minimalSize = value; } + } + + public bool AutoDispose + { + get { return _autoDispose; } + set { _autoDispose = value; } + } + + public string FullTitle + { + get { return _fullTitle; } + } + + public bool RedockAllowed + { + get { return _redockAllowed; } + set { _redockAllowed = value; } + } + + protected void OnDetailsClearing() + { + // Inform each detail it no longer has a parent + foreach (WindowDetail wd in _windowDetails) + { + // Inform each detail it no longer has a parent + wd.ParentWindow = null; + + // Inform object that it is no longer in a Zone + wd.ParentZone = null; + } + } + + protected void OnDetailInserted(int index, object value) + { + WindowDetail wd = value as WindowDetail; + + // Inform object we are the new parent + wd.ParentWindow = this; + + // Inform object that it is in a Zone + wd.ParentZone = _parentZone; + } + + protected void OnDetailRemoving(int index, object value) + { + WindowDetail wd = value as WindowDetail; + + // Inform object it no longer has a parent + wd.ParentWindow = null; + + // Inform object that it is no longer in a Zone + wd.ParentZone = null; + } + + public virtual void NotifyFullTitleText(string title) + { + // Inform each detail of change in focus + foreach (WindowDetail wd in _windowDetails) + wd.NotifyFullTitleText(title); + + OnFullTitleChanged(title); + } + + public virtual void NotifyAutoHideImage(bool autoHidden) + { + // Inform each detail of change in caption bar + foreach (WindowDetail wd in _windowDetails) + wd.NotifyAutoHideImage(autoHidden); + } + + public virtual void NotifyShowCaptionBar(bool show) + { + // Remember the per-content requested caption + _contentCaption = show; + + // If priority value always showing then we can let the + // individual content decide on visibility. Otherwise + // the priority forces it to remain hidden + if (_floatingCaption) + { + // Inform each detail of change in caption bar + foreach (WindowDetail wd in _windowDetails) + wd.NotifyShowCaptionBar(show); + } + } + + public virtual void NotifyCloseButton(bool show) + { + // Inform each detail of change close button + foreach (WindowDetail wd in _windowDetails) + wd.NotifyCloseButton(show); + } + + public virtual void NotifyHideButton(bool show) + { + // Inform each detail of change close button + foreach (WindowDetail wd in _windowDetails) + wd.NotifyHideButton(show); + } + + public virtual void NotifyContentGotFocus() + { + // Inform each detail of change in focus + foreach (WindowDetail wd in _windowDetails) + wd.WindowGotFocus(); + } + + public virtual void NotifyContentLostFocus() + { + // Inform each detail of change in focus + foreach (WindowDetail wd in _windowDetails) + wd.WindowLostFocus(); + } + + public virtual void WindowDetailGotFocus(WindowDetail wd) + { + NotifyContentGotFocus(); + } + + public virtual void WindowDetailLostFocus(WindowDetail wd) + { + NotifyContentLostFocus(); + } + + public void HideDetails() + { + // Inform each detail of change in visibility + foreach (WindowDetail wd in _windowDetails) + wd.Hide(); + + // Remember priority state for caption + _floatingCaption = false; + } + + public void ShowDetails() + { + // Inform each detail of change in visibility + foreach (WindowDetail wd in _windowDetails) + wd.Show(); + + // Remember priority state for caption + _floatingCaption = true; + + // If the content requested the caption be hidden + if (!_contentCaption) + NotifyShowCaptionBar(_contentCaption); + } + + public virtual void OnFullTitleChanged(String fullTitle) + { + _fullTitle = fullTitle; + + if (FullTitleChanged != null) + FullTitleChanged((object)fullTitle, EventArgs.Empty); + } + + public virtual Restore RecordRestore(object child) + { + // Do we have a Zone as our parent? + if (_parentZone != null) + { + // Delegate to the Zone as we cannot help out + return _parentZone.RecordRestore(this, child, null); + } + + return null; + } + + public virtual void PropogateNameValue(PropogateName name, object value) + { + if (name == PropogateName.BackColor) + { + this.BackColor = (Color)value; + Invalidate(); + } + + // Pass onto each of our child Windows + foreach (WindowDetail wd in _windowDetails) + wd.PropogateNameValue(name, value); + } + } +} \ No newline at end of file diff --git a/Labyrinth3/Crownwood.Magic/Docking/Window.resx b/Labyrinth3/Crownwood.Magic/Docking/Window.resx new file mode 100644 index 0000000..7e32396 --- /dev/null +++ b/Labyrinth3/Crownwood.Magic/Docking/Window.resx @@ -0,0 +1,42 @@ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + text/microsoft-resx + + + 1.0.0.0 + + + System.Resources.ResXResourceReader, System.Windows.Forms, Version=1.0.3102.0, Culture=neutral, PublicKeyToken=b77a5c561934e089 + + + System.Resources.ResXResourceWriter, System.Windows.Forms, Version=1.0.3102.0, Culture=neutral, PublicKeyToken=b77a5c561934e089 + + diff --git a/Labyrinth3/Crownwood.Magic/Docking/WindowContent.cs b/Labyrinth3/Crownwood.Magic/Docking/WindowContent.cs new file mode 100644 index 0000000..6e0bfb4 --- /dev/null +++ b/Labyrinth3/Crownwood.Magic/Docking/WindowContent.cs @@ -0,0 +1,132 @@ +// ***************************************************************************** +// +// (c) Crownwood Consulting Limited 2002-2003 +// All rights reserved. The software and associated documentation +// supplied hereunder are the proprietary information of Crownwood Consulting +// Limited, Crownwood, Bracknell, Berkshire, England and are supplied subject +// to licence terms. +// +// Magic Version 1.7.4.0 www.dotnetmagic.com +// ***************************************************************************** + +using Crownwood.Magic.Collections; +using Crownwood.Magic.Common; +using System.ComponentModel; + +namespace Crownwood.Magic.Docking +{ + [ToolboxItem(false)] + public class WindowContent : Window + { + // Instance fields + protected ContentCollection _contents; + + protected VisualStyle _style; + + public WindowContent(DockingManager manager, VisualStyle vs) + : base(manager) + { + // Remember state + _style = vs; + + // Create collection of window details + _contents = new ContentCollection(); + + // We want notification when contents are added/removed/cleared + _contents.Clearing += new CollectionClear(OnContentsClearing); + _contents.Inserted += new CollectionChange(OnContentInserted); + _contents.Removing += new CollectionChange(OnContentRemoving); + _contents.Removed += new CollectionChange(OnContentRemoved); + } + + public ContentCollection Contents + { + get { return _contents; } + + set + { + _contents.Clear(); + _contents = value; + } + } + + public virtual void BringContentToFront(Content c) + { + } + + protected virtual void OnContentsClearing() + { + foreach (Content c in _contents) + { + // Inform content of new parent content window + c.ParentWindowContent = null; + + // Unhook from property change notification + c.PropertyChanged -= new Content.PropChangeHandler(OnContentChanged); + } + + // Should we kill ourself? + if (this.AutoDispose) + Suicide(); + } + + protected virtual void OnContentInserted(int index, object value) + { + Content content = value as Content; + + // Is this the first Content added? + if (_contents.Count == 1) + { + // Use size of the Content to determine our size + this.Size = content.DisplaySize; + } + + // Inform content where it now resides + content.ParentWindowContent = this; + + // Monitor changes in Content properties + content.PropertyChanged += new Content.PropChangeHandler(OnContentChanged); + } + + protected virtual void OnContentRemoving(int index, object value) + { + Content content = value as Content; + + // Inform content of new parent content window + content.ParentWindowContent = null; + + // Unhook from monitoring changes in Content properties + content.PropertyChanged -= new Content.PropChangeHandler(OnContentChanged); + } + + protected virtual void OnContentRemoved(int index, object value) + { + // Removed the last entry? + if (_contents.Count == 0) + { + // Should we kill ourself? + if (this.AutoDispose) + Suicide(); + } + } + + protected virtual void OnContentChanged(Content obj, Content.Property prop) + { + } + + protected void Suicide() + { + // Are we inside a Zone object? + if (this.ParentZone != null) + this.ParentZone.Windows.Remove(this); + + // Remover monitoring of events + _contents.Clearing -= new CollectionClear(OnContentsClearing); + _contents.Inserted -= new CollectionChange(OnContentInserted); + _contents.Removing -= new CollectionChange(OnContentRemoving); + _contents.Removed -= new CollectionChange(OnContentRemoved); + + this.Dispose(); + } + } +} \ No newline at end of file diff --git a/Labyrinth3/Crownwood.Magic/Docking/WindowContentTabbed.cs b/Labyrinth3/Crownwood.Magic/Docking/WindowContentTabbed.cs new file mode 100644 index 0000000..98e8b8c --- /dev/null +++ b/Labyrinth3/Crownwood.Magic/Docking/WindowContentTabbed.cs @@ -0,0 +1,648 @@ +// ***************************************************************************** +// +// (c) Crownwood Consulting Limited 2002-2003 +// All rights reserved. The software and associated documentation +// supplied hereunder are the proprietary information of Crownwood Consulting +// Limited, Crownwood, Bracknell, Berkshire, England and are supplied subject +// to licence terms. +// +// Magic Version 1.7.4.0 www.dotnetmagic.com +// ***************************************************************************** + +using Crownwood.Magic.Collections; +using Crownwood.Magic.Common; +using Crownwood.Magic.Controls; +using System; +using System.ComponentModel; +using System.Drawing; +using System.Windows.Forms; + +namespace Crownwood.Magic.Docking +{ + [ToolboxItem(false)] + public class WindowContentTabbed : WindowContent, IHotZoneSource, IMessageFilter + { + // Class constants + protected static int _plainBorder = 3; + + protected static int _hotAreaInflate = -3; + + // Instance fields + protected int _dragPageIndex; + + protected Content _activeContent; + protected RedockerContent _redocker; + protected Magic.Controls.TabControl _tabControl; + + public WindowContentTabbed(DockingManager manager, VisualStyle vs) + : base(manager, vs) + { + _redocker = null; + _activeContent = null; + + // Create the TabControl used for viewing the Content windows + _tabControl = new Magic.Controls.TabControl(); + + // It should always occupy the remaining space after all details + _tabControl.Dock = DockStyle.Fill; + + // Show tabs only if two or more tab pages exist + _tabControl.HideTabsMode = Magic.Controls.TabControl.HideTabsModes.HideUsingLogic; + + // Hook into the TabControl notifications + _tabControl.GotFocus += new EventHandler(OnTabControlGotFocus); + _tabControl.LostFocus += new EventHandler(OnTabControlLostFocus); + _tabControl.PageGotFocus += new EventHandler(OnTabControlGotFocus); + _tabControl.PageLostFocus += new EventHandler(OnTabControlLostFocus); + _tabControl.SelectionChanged += new EventHandler(OnSelectionChanged); + _tabControl.PageDragStart += new MouseEventHandler(OnPageDragStart); + _tabControl.PageDragMove += new MouseEventHandler(OnPageDragMove); + _tabControl.PageDragEnd += new MouseEventHandler(OnPageDragEnd); + _tabControl.PageDragQuit += new MouseEventHandler(OnPageDragQuit); + _tabControl.DoubleClickTab += new Magic.Controls.TabControl.DoubleClickTabHandler(OnDoubleClickTab); + _tabControl.Font = manager.TabControlFont; + _tabControl.BackColor = manager.BackColor; + _tabControl.ForeColor = manager.InactiveTextColor; + + // Define the visual style required + _tabControl.Style = vs; + + // Allow developers a chance to override default settings + manager.OnTabControlCreated(_tabControl); + + switch (vs) + { + case VisualStyle.IDE: + Controls.Add(_tabControl); + break; + + case VisualStyle.Plain: + // Only the border at the pages edge and not around the whole control + _tabControl.InsetBorderPagesOnly = !_manager.PlainTabBorder; + + // We want a border around the TabControl so it is indented and looks consistent + // with the Plain look and feel, so use the helper Control 'BorderForControl' + BorderForControl bfc = new BorderForControl(_tabControl, _plainBorder); + + // It should always occupy the remaining space after all details + bfc.Dock = DockStyle.Fill; + + // Define the default border border + bfc.BackColor = _manager.BackColor; + + // When in 'VisualStyle.Plain' we need to + Controls.Add(bfc); + break; + } + + // Need to hook into message pump so that the ESCAPE key can be + // intercepted when in redocking mode + Application.AddMessageFilter(this); + } + + public Content CurrentContent + { + get + { + Magic.Controls.TabPage tp = _tabControl.SelectedTab; + + if (tp != null) + return (Content)tp.Tag; + else + return null; + } + } + + public Magic.Controls.TabControl TabControl + { + get { return _tabControl; } + } + + public void HideCurrentContent() + { + Magic.Controls.TabPage tp = _tabControl.SelectedTab; + + int count = _tabControl.TabPages.Count; + + // Find currently selected tab + int index = _tabControl.SelectedIndex; + + // Decide which other tab to make selected instead + if (count > 1) + { + // Move to the next control along + int newSelect = index + 1; + + // Wrap around to first tab if at end + if (newSelect == count) + newSelect = 0; + + // Change selection + _tabControl.SelectedIndex = newSelect; + } + else + { + // Hide myself as am about to die + this.Hide(); + + // Ensure the focus goes somewhere else + _manager.Container.Focus(); + } + + if (tp != null) + { + Content c = tp.Tag as Content; + + // Have the manager perform the Hide operation for us + _manager.HideContent(c); + + // Do we also remove the content? + if (c.CloseOnHide) + { + // Remove the content from the collection + _manager.Contents.Remove(c); + + // Dispose of the contained control/form + if (c.Control != null) + c.Control.Dispose(); + } + } + } + + public override void BringContentToFront(Content c) + { + // Find the matching Page and select it + foreach (Magic.Controls.TabPage page in _tabControl.TabPages) + if (page.Tag == c) + { + _tabControl.SelectedTab = page; + break; + } + } + + public override void PropogateNameValue(PropogateName name, object value) + { + base.PropogateNameValue(name, value); + + switch (name) + { + case PropogateName.BackColor: + Color newColor = (Color)value; + + // In Plain style we need to color the intermidiate window as well + if (_style == VisualStyle.Plain) + { + BorderForControl bfc = this.Controls[0] as BorderForControl; + bfc.BackColor = newColor; + } + + _tabControl.BackColor = newColor; + this.BackColor = newColor; + + Invalidate(); + break; + + case PropogateName.InactiveTextColor: + _tabControl.ForeColor = (Color)value; + break; + + case PropogateName.PlainTabBorder: + _tabControl.InsetBorderPagesOnly = !(bool)value; + break; + + case PropogateName.TabControlFont: + _tabControl.Font = (Font)value; + break; + } + } + + protected override void OnContentsClearing() + { + _tabControl.TabPages.Clear(); + + base.OnContentsClearing(); + + if (!this.AutoDispose) + { + // Inform each detail of the change in title text + NotifyFullTitleText(""); + } + } + + protected override void OnContentInserted(int index, object value) + { + base.OnContentInserted(index, value); + + Content content = value as Content; + + // Create TabPage to represent the Content + Magic.Controls.TabPage newPage = new Magic.Controls.TabPage(); + + // Reflect the Content properties int the TabPage + newPage.Title = content.Title; + newPage.ImageList = content.ImageList; + newPage.ImageIndex = content.ImageIndex; + newPage.Icon = content.Icon; + newPage.Control = content.Control; + newPage.Tag = content; + + // Reflect same order in TabPages collection as Content collection + _tabControl.TabPages.Insert(index, newPage); + } + + protected override void OnContentRemoving(int index, object value) + { + base.OnContentRemoving(index, value); + + Content c = value as Content; + + // Find the matching Page and remove it + foreach (Magic.Controls.TabPage page in _tabControl.TabPages) + if (page.Tag == c) + { + _tabControl.TabPages.Remove(page); + break; + } + } + + public override void WindowDetailGotFocus(WindowDetail wd) + { + // Transfer focus from WindowDetail to the TabControl + _tabControl.Focus(); + } + + protected void OnSelectionChanged(object sender, EventArgs e) + { + if (_tabControl.TabPages.Count == 0) + { + // Inform each detail of the change in title text + NotifyFullTitleText(""); + } + else + { + // Inform each detail of the new title text + if (_tabControl.SelectedIndex != -1) + { + Content selectedContent = _tabControl.SelectedTab.Tag as Content; + + NotifyAutoHideImage(selectedContent.AutoHidden); + NotifyCloseButton(selectedContent.CloseButton); + NotifyHideButton(selectedContent.HideButton); + NotifyFullTitleText(selectedContent.FullTitle); + NotifyShowCaptionBar(selectedContent.CaptionBar); + } + } + } + + protected void OnTabControlGotFocus(object sender, EventArgs e) + { + NotifyContentGotFocus(); + } + + protected void OnTabControlLostFocus(object sender, EventArgs e) + { + NotifyContentLostFocus(); + } + + public void AddHotZones(Redocker redock, HotZoneCollection collection) + { + RedockerContent redocker = redock as RedockerContent; + + bool itself = false; + bool nullZone = false; + + // We process differently for WindowContent to redock into itself! + if ((redocker.WindowContent != null) && (redocker.WindowContent == this)) + itself = true; + + // We do not allow a Content to redock into its existing container + if (itself && !_contents.Contains(redocker.Content)) + nullZone = true; + + Rectangle newSize = this.RectangleToScreen(this.ClientRectangle); + Rectangle hotArea = _tabControl.RectangleToScreen(_tabControl.ClientRectangle); ; + + // Find any caption detail and use that area as the hot area + foreach (WindowDetail wd in _windowDetails) + { + WindowDetailCaption wdc = wd as WindowDetailCaption; + + if (wdc != null) + { + hotArea = wdc.RectangleToScreen(wdc.ClientRectangle); + hotArea.Inflate(_hotAreaInflate, _hotAreaInflate); + break; + } + } + + if (nullZone) + collection.Add(new HotZoneNull(hotArea)); + else + collection.Add(new HotZoneTabbed(hotArea, newSize, this, itself)); + } + + protected void OnDoubleClickTab(Magic.Controls.TabControl tc, Magic.Controls.TabPage page) + { + Content c = (Content)page.Tag; + + // Make Content record its current position and remember it for the future + c.RecordRestore(); + + // Invert docked status + c.Docked = (c.Docked == false); + + // Remove from current WindowContent and restore its position + _manager.HideContent(c, false, true); + _manager.ShowContent(c); + } + + protected void OnPageDragStart(object sender, MouseEventArgs e) + { + if (this.RedockAllowed) + { + // There must be a selected page for this event to occur + Magic.Controls.TabPage page = _tabControl.SelectedTab; + + // Event page must specify its Content object + Content c = page.Tag as Content; + + // Remember the position of the tab before it is removed + _dragPageIndex = _tabControl.TabPages.IndexOf(page); + + // Remove page from TabControl + _tabControl.TabPages.Remove(page); + + // Force the entire window to redraw to ensure the Redocker does not start drawing + // the XOR indicator before the window repaints itself. Otherwise the repainted + // control will interfere with the XOR indicator. + this.Refresh(); + + // Start redocking activity for the single Content of this WindowContent + _redocker = new RedockerContent(_tabControl, c, this, new Point(e.X, e.Y)); + } + } + + protected void OnPageDragMove(object sender, MouseEventArgs e) + { + // Redocker object needs mouse movements + if (_redocker != null) + _redocker.OnMouseMove(e); + } + + protected void OnPageDragEnd(object sender, MouseEventArgs e) + { + // Are we currently in a redocking state? + if (_redocker != null) + { + // Let the redocker finish off + bool moved = _redocker.OnMouseUp(e); + + // If the tab was not positioned somewhere else + if (!moved) + { + // Put back the page that was removed when dragging started + RestoreDraggingPage(); + } + + // No longer need the object + _redocker = null; + } + } + + protected void OnPageDragQuit(object sender, MouseEventArgs e) + { + // Are we currently in a redocking state? + if (_redocker != null) + { + // Get redocker to quit + _redocker.QuitTrackingMode(e); + + // Put back the page that was removed when dragging started + RestoreDraggingPage(); + + // No longer need the object + _redocker = null; + } + } + + protected override void OnContentChanged(Content obj, Content.Property prop) + { + // Find the matching TabPage entry + foreach (Magic.Controls.TabPage page in _tabControl.TabPages) + { + // Does this page manage our Content? + if (page.Tag == obj) + { + // Property specific processing + switch (prop) + { + case Content.Property.Control: + page.Control = obj.Control; + break; + + case Content.Property.Title: + page.Title = obj.Title; + break; + + case Content.Property.FullTitle: + // Title changed for the current page? + if (_tabControl.SelectedTab == page) + { + // Update displayed caption text + NotifyFullTitleText(obj.FullTitle); + } + break; + + case Content.Property.ImageList: + page.ImageList = obj.ImageList; + break; + + case Content.Property.ImageIndex: + page.ImageIndex = obj.ImageIndex; + break; + + case Content.Property.Icon: + page.Icon = obj.Icon; + break; + + case Content.Property.CaptionBar: + // Property changed for the current page? + if (_tabControl.SelectedTab == page) + { + Content target = page.Tag as Content; + + // TODO + NotifyShowCaptionBar(target.CaptionBar); + } + break; + + case Content.Property.CloseButton: + // Property changed for the current page? + if (_tabControl.SelectedTab == page) + { + Content target = page.Tag as Content; + + NotifyCloseButton(target.CloseButton); + } + break; + + case Content.Property.HideButton: + // Property changed for the current page? + if (_tabControl.SelectedTab == page) + { + Content target = page.Tag as Content; + + NotifyHideButton(target.HideButton); + } + break; + } + + break; + } + } + } + + protected override void OnResize(EventArgs e) + { + // Inform each Content of its actual displayed size + foreach (Content c in _contents) + { + switch (_state) + { + case State.DockLeft: + case State.DockRight: + if (this.Dock != DockStyle.Fill) + { + // Only update the remembered width + c.DisplaySize = new Size(this.ClientSize.Width, c.DisplaySize.Height); + } + break; + + case State.DockTop: + case State.DockBottom: + if (this.Dock != DockStyle.Fill) + { + // Only update the remembered height + c.DisplaySize = new Size(c.DisplaySize.Width, this.ClientSize.Height); + } + break; + + case State.Floating: + { + Form f = this.FindForm(); + + // Update width and height + if (f == null) + c.DisplaySize = this.ClientSize; + else + c.DisplaySize = f.Size; + } + break; + } + } + + base.OnResize(e); + } + + public override Restore RecordRestore(object child) + { + // Child of a WindowContent must be a Content object + Content c = child as Content; + + StringCollection next = new StringCollection(); + StringCollection previous = new StringCollection(); + + bool before = true; + + // Fill collections with list of Content before and after parameter + foreach (Content content in _contents) + { + if (content == c) + before = false; + else + { + if (before) + previous.Add(content.Title); + else + next.Add(content.Title); + } + } + + bool selected = false; + + // Is there a selected tab? + if (_tabControl.SelectedIndex != -1) + { + // Get access to the selected Content + Content selectedContent = _tabControl.SelectedTab.Tag as Content; + + // Need to record if it is selected + selected = (selectedContent == c); + } + + // Create a Restore object to handle this WindowContent + Restore thisRestore = new RestoreWindowContent(null, c, next, previous, selected); + + // Do we have a Zone as our parent? + if (_parentZone != null) + { + // Get the Zone to prepend its own Restore knowledge + thisRestore = _parentZone.RecordRestore(this, child, thisRestore); + } + + return thisRestore; + } + + public bool PreFilterMessage(ref Message m) + { + // Has a key been pressed? + if (m.Msg == (int)Win32.Msgs.WM_KEYDOWN) + { + // Is it the ESCAPE key? + if ((int)m.WParam == (int)Win32.VirtualKeys.VK_ESCAPE) + { + // Are we in redocking mode? + if (_redocker != null) + { + // Cancel the redocking activity + _redocker.QuitTrackingMode(null); + + // Put back the page that was removed when dragging started + RestoreDraggingPage(); + + // No longer need the object + _redocker = null; + + return true; + } + } + } + + return false; + } + + protected void RestoreDraggingPage() + { + // Create TabPage to represent the Content + Magic.Controls.TabPage newPage = new Magic.Controls.TabPage(); + + Content content = _redocker.Content; + + // Reflect the Content properties int the TabPage + newPage.Title = content.Title; + + newPage.ImageList = content.ImageList; + newPage.ImageIndex = content.ImageIndex; + newPage.Icon = content.Icon; + newPage.Control = content.Control; + newPage.Tag = content; + newPage.Selected = true; + + // Put it back where it came from + _tabControl.TabPages.Insert(_dragPageIndex, newPage); + + // Update the title displayed + NotifyFullTitleText(content.FullTitle); + } + } +} \ No newline at end of file diff --git a/Labyrinth3/Crownwood.Magic/Docking/WindowDetail.cs b/Labyrinth3/Crownwood.Magic/Docking/WindowDetail.cs new file mode 100644 index 0000000..30be4e4 --- /dev/null +++ b/Labyrinth3/Crownwood.Magic/Docking/WindowDetail.cs @@ -0,0 +1,168 @@ +// ***************************************************************************** +// +// (c) Crownwood Consulting Limited 2002-2003 +// All rights reserved. The software and associated documentation +// supplied hereunder are the proprietary information of Crownwood Consulting +// Limited, Crownwood, Bracknell, Berkshire, England and are supplied subject +// to licence terms. +// +// Magic Version 1.7.4.0 www.dotnetmagic.com +// ***************************************************************************** + +using Crownwood.Magic.Common; +using System; +using System.ComponentModel; +using System.Drawing; +using System.Windows.Forms; + +namespace Crownwood.Magic.Docking +{ + [ToolboxItem(false)] + public class WindowDetail : Control + { + // Instance fields + protected Zone _parentZone; + + protected Window _parentWindow; + protected DockingManager _manager; + + public WindowDetail(DockingManager manager) + { + // Default the state + _parentZone = null; + _parentWindow = null; + _manager = manager; + + // Get correct starting state from manager + this.BackColor = _manager.BackColor; + this.ForeColor = _manager.InactiveTextColor; + } + + public virtual Zone ParentZone + { + get { return _parentZone; } + set { _parentZone = value; } + } + + public Window ParentWindow + { + get { return _parentWindow; } + + set + { + // Call virtual function for derived classes to override + RemovedFromParent(_parentWindow); + + if (value == null) + { + if (_parentWindow != null) + { + // Remove ourself from old parent window + + // Use helper method to circumvent form Close bug + ControlHelper.Remove(_parentWindow.Controls, this); + } + } + else + { + if ((_parentWindow != null) && (_parentWindow != value)) + { + // Call virtual function for derived classes to override + RemovedFromParent(_parentWindow); + + // Remove ourself from old parent window + + // Use helper method to circumvent form Close bug + ControlHelper.Remove(_parentWindow.Controls, this); + } + + // Add ourself to the new parent window + value.Controls.Add(this); + } + + // Remember the new parent identity + _parentWindow = value; + + // Call virtual function for derived classes to override + AddedToParent(_parentWindow); + + if (_parentWindow != null) + { + // Update to reflect new parent window state + ParentStateChanged(_parentWindow.State); + } + } + } + + public virtual void WindowGotFocus() + { + } + + public virtual void WindowLostFocus() + { + } + + public virtual void NotifyRedockAllowed(bool redockAllowed) + { + } + + public virtual void NotifyAutoHideImage(bool autoHidden) + { + } + + public virtual void NotifyCloseButton(bool show) + { + } + + public virtual void NotifyHideButton(bool show) + { + } + + public virtual void NotifyShowCaptionBar(bool show) + { + } + + public virtual void NotifyFullTitleText(string title) + { + } + + public virtual void ParentStateChanged(State newState) + { + } + + public virtual void RemovedFromParent(Window parent) + { + } + + public virtual void AddedToParent(Window parent) + { + } + + public virtual void PropogateNameValue(PropogateName name, object value) + { + if (name == PropogateName.BackColor) + { + this.BackColor = (Color)value; + Invalidate(); + } + } + + protected override void OnGotFocus(EventArgs e) + { + // Inform parent window we have the focus + if (_parentWindow != null) + _parentWindow.WindowDetailGotFocus(this); + + base.OnGotFocus(e); + } + + protected override void OnLostFocus(EventArgs e) + { + // Inform parent window we have lost focus + if (_parentWindow != null) + _parentWindow.WindowDetailLostFocus(this); + + base.OnLostFocus(e); + } + } +} \ No newline at end of file diff --git a/Labyrinth3/Crownwood.Magic/Docking/WindowDetail.resx b/Labyrinth3/Crownwood.Magic/Docking/WindowDetail.resx new file mode 100644 index 0000000..7e32396 --- /dev/null +++ b/Labyrinth3/Crownwood.Magic/Docking/WindowDetail.resx @@ -0,0 +1,42 @@ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + text/microsoft-resx + + + 1.0.0.0 + + + System.Resources.ResXResourceReader, System.Windows.Forms, Version=1.0.3102.0, Culture=neutral, PublicKeyToken=b77a5c561934e089 + + + System.Resources.ResXResourceWriter, System.Windows.Forms, Version=1.0.3102.0, Culture=neutral, PublicKeyToken=b77a5c561934e089 + + diff --git a/Labyrinth3/Crownwood.Magic/Docking/WindowDetailCaption.cs b/Labyrinth3/Crownwood.Magic/Docking/WindowDetailCaption.cs new file mode 100644 index 0000000..c461f38 --- /dev/null +++ b/Labyrinth3/Crownwood.Magic/Docking/WindowDetailCaption.cs @@ -0,0 +1,1343 @@ +// ***************************************************************************** +// +// (c) Crownwood Consulting Limited 2002-2003 +// All rights reserved. The software and associated documentation +// supplied hereunder are the proprietary information of Crownwood Consulting +// Limited, Crownwood, Bracknell, Berkshire, England and are supplied subject +// to licence terms. +// +// Magic Version 1.7.4.0 www.dotnetmagic.com +// ***************************************************************************** + +using Crownwood.Magic.Common; +using Crownwood.Magic.Controls; +using System; +using System.ComponentModel; +using System.Drawing; +using System.Drawing.Imaging; +using System.Windows.Forms; + +namespace Crownwood.Magic.Docking +{ + [ToolboxItem(false)] + public class WindowDetailCaption : WindowDetail, IMessageFilter + { + // Class fields + protected static ImageList _images; + + // Instance events + public event EventHandler Close; + + public event EventHandler Restore; + + public event EventHandler InvertAutoHide; + + public event ContextHandler Context; + + // Instance fields + protected InertButton _maxButton; + + protected InertButton _closeButton; + protected InertButton _hideButton; + protected RedockerContent _redocker; + protected IZoneMaximizeWindow _maxInterface; + protected bool _showCloseButton; + protected bool _showHideButton; + protected bool _ignoreHideButton; + protected bool _pinnedImage; + + // Class fields + protected static ImageAttributes _activeAttr = new ImageAttributes(); + + protected static ImageAttributes _inactiveAttr = new ImageAttributes(); + + public WindowDetailCaption(DockingManager manager, + Size fixedSize, + EventHandler closeHandler, + EventHandler restoreHandler, + EventHandler invertAutoHideHandler, + ContextHandler contextHandler) + : base(manager) + { + // Setup correct color remapping depending on initial colors + DefineButtonRemapping(); + + // Default state + _maxButton = null; + _hideButton = null; + _maxInterface = null; + _redocker = null; + _showCloseButton = true; + _showHideButton = true; + _ignoreHideButton = false; + _pinnedImage = false; + + // Prevent flicker with double buffering and all painting inside WM_PAINT + SetStyle(ControlStyles.DoubleBuffer | + ControlStyles.AllPaintingInWmPaint | + ControlStyles.UserPaint, true); + + // Our size is always fixed at the required length in both directions + // as one of the sizes will be provided for us because of our docking + this.Size = fixedSize; + + if (closeHandler != null) + this.Close += closeHandler; + + if (restoreHandler != null) + this.Restore += restoreHandler; + + if (invertAutoHideHandler != null) + this.InvertAutoHide += invertAutoHideHandler; + + if (contextHandler != null) + this.Context += contextHandler; + + // Let derived classes override the button creation + CreateButtons(); + + // Need to hook into message pump so that the ESCAPE key can be + // intercepted when in redocking mode + Application.AddMessageFilter(this); + } + + public override Zone ParentZone + { + set + { + base.ParentZone = value; + + RecalculateMaximizeButton(); + RecalculateButtons(); + } + } + + public virtual void OnClose() + { + // Any attached event handlers? + if (Close != null) + Close(this, EventArgs.Empty); + } + + public virtual void OnInvertAutoHide() + { + // Any attached event handlers? + if (InvertAutoHide != null) + InvertAutoHide(this, EventArgs.Empty); + } + + public virtual void OnRestore() + { + // Any attached event handlers? + if (Restore != null) + Restore(this, EventArgs.Empty); + } + + public virtual void OnContext(Point screenPos) + { + // Any attached event handlers? + if (Context != null) + Context(screenPos); + } + + protected override void Dispose(bool disposing) + { + if (disposing) + { + if (_closeButton != null) + { + _closeButton.Click -= new EventHandler(OnButtonClose); + _closeButton.GotFocus -= new EventHandler(OnButtonGotFocus); + } + + if (_hideButton != null) + { + _hideButton.Click -= new EventHandler(OnButtonHide); + _hideButton.GotFocus -= new EventHandler(OnButtonGotFocus); + } + + if (_maxButton != null) + { + _maxButton.Click -= new EventHandler(OnButtonMax); + _maxButton.GotFocus -= new EventHandler(OnButtonGotFocus); + } + } + base.Dispose(disposing); + } + + public override void NotifyAutoHideImage(bool autoHidden) + { + _pinnedImage = autoHidden; + UpdateAutoHideImage(); + } + + public override void NotifyCloseButton(bool show) + { + _showCloseButton = show; + RecalculateButtons(); + } + + public override void NotifyHideButton(bool show) + { + // Ignore the AutoHide feature when in floating form + _ignoreHideButton = (_parentWindow.State == State.Floating); + + _showHideButton = show; + RecalculateButtons(); + } + + public override void NotifyShowCaptionBar(bool show) + { + this.Visible = show; + } + + protected void RecalculateMaximizeButton() + { + // Are we inside a Zone? + if (this.ParentZone != null) + { + // Does the Zone support the maximizing of a Window? + IZoneMaximizeWindow zmw = this.ParentZone as IZoneMaximizeWindow; + + if (zmw != null) + { + AddMaximizeInterface(zmw); + return; + } + } + + RemoveMaximizeInterface(); + } + + protected void AddMaximizeInterface(IZoneMaximizeWindow zmw) + { + // Has the maximize button already been created? + if (_maxInterface == null) + { + // Create the InertButton + _maxButton = new InertButton(_images, 0); + + // Hook into button events + _maxButton.Click += new EventHandler(OnButtonMax); + _maxButton.GotFocus += new EventHandler(OnButtonGotFocus); + + // Define the default remapping + _maxButton.ImageAttributes = _inactiveAttr; + + OnAddMaximizeInterface(); + + Controls.Add(_maxButton); + + // Remember the interface reference + _maxInterface = zmw; + + // Hook into the interface change events + _maxInterface.RefreshMaximize += new EventHandler(OnRefreshMaximize); + + RecalculateButtons(); + } + } + + protected void RemoveMaximizeInterface() + { + if (_maxInterface != null) + { + // Unhook from the interface change events + _maxInterface.RefreshMaximize -= new EventHandler(OnRefreshMaximize); + + // Remove the interface reference + _maxInterface = null; + + // Use helper method to circumvent form Close bug + ControlHelper.Remove(this.Controls, _maxButton); + + OnRemoveMaximizeInterface(); + + // Unhook into button events + _maxButton.Click -= new EventHandler(OnButtonMax); + _maxButton.GotFocus -= new EventHandler(OnButtonGotFocus); + + // Kill the button which is no longer needed + _maxButton.Dispose(); + _maxButton = null; + + RecalculateButtons(); + } + } + + protected void OnRefreshMaximize(object sender, EventArgs e) + { + UpdateMaximizeImage(); + } + + protected void OnButtonMax(object sender, EventArgs e) + { + if (this.ParentWindow != null) + { + if (_maxInterface.IsMaximizeAvailable()) + { + // Are we already maximized? + if (_maxInterface.IsWindowMaximized(this.ParentWindow)) + _maxInterface.RestoreWindow(); + else + _maxInterface.MaximizeWindow(this.ParentWindow); + } + } + } + + protected void OnButtonClose(Object sender, EventArgs e) + { + if (_showCloseButton) + OnClose(); + } + + protected void OnButtonHide(Object sender, EventArgs e) + { + // Plain button can still be pressed when disabled, so double check + // that an event should actually be generated + if (_showHideButton && !_ignoreHideButton) + OnInvertAutoHide(); + } + + protected void OnButtonGotFocus(Object sender, EventArgs e) + { + // Inform parent window we have now got the focus + if (this.ParentWindow != null) + this.ParentWindow.WindowDetailGotFocus(this); + } + + protected override void OnDoubleClick(EventArgs e) + { + // The double click event will cause the control to be destroyed as + // the Contents are restored to their alternative positions, so need to + // double check the control is not already dead + if (!IsDisposed) + { + // Are we currently in a redocking state? + if (_redocker != null) + { + // No longer need the object + _redocker = null; + } + } + + // Fire attached event handlers + OnRestore(); + } + + protected override void OnMouseDown(MouseEventArgs e) + { + // The double click event will cause the control to be destroyed as + // the Contents are restored to their alternative positions, so need to + // double check the control is not already dead + if (!IsDisposed) + { + // Always quit when new another button pressed and already docking + if (_redocker != null) + { + _redocker.QuitTrackingMode(e); + + // No longer need the object + _redocker = null; + } + else + { + // Left mouse down begins a redocking action + if (e.Button == MouseButtons.Left) + { + if (this.ParentWindow.RedockAllowed) + { + WindowContent wc = this.ParentWindow as WindowContent; + + // Is our parent a WindowContent instance? + if (wc != null) + { + // Start redocking activity for the whole WindowContent + _redocker = new RedockerContent(this, wc, new Point(e.X, e.Y)); + } + } + } + + this.Focus(); + } + } + + base.OnMouseDown(e); + } + + protected override void OnMouseMove(MouseEventArgs e) + { + // The double click event will cause the control to be destroyed as + // the Contents are restored to their alternative positions, so need to + // double check the control is not already dead + if (!IsDisposed) + { + // Redocker object needs mouse movements + if (_redocker != null) + _redocker.OnMouseMove(e); + } + + base.OnMouseMove(e); + } + + protected override void OnMouseUp(MouseEventArgs e) + { + // The double click event will cause the control to be destroyed as + // the Contents are restored to their alternative positions, so need to + // double check the control is not already dead + if (!IsDisposed) + { + // Are we currently in a redocking state? + if (_redocker != null) + { + // Let the redocker finish off + _redocker.OnMouseUp(e); + + // No longer need the object + _redocker = null; + } + + // Right mouse button can generate a Context event + if (e.Button == MouseButtons.Right) + { + // Get screen coordinates of the mouse + Point pt = this.PointToScreen(new Point(e.X, e.Y)); + + // Box to transfer as parameter + OnContext(pt); + } + } + + base.OnMouseUp(e); + } + + protected override void OnResize(EventArgs e) + { + // Any resize of control should redraw all of it + Invalidate(); + base.OnResize(e); + } + + protected virtual void DefineButtonRemapping() + { + } + + protected virtual void OnAddMaximizeInterface() + { + } + + protected virtual void OnRemoveMaximizeInterface() + { + } + + protected virtual void UpdateMaximizeImage() + { + } + + protected virtual void UpdateAutoHideImage() + { + } + + protected virtual void RecalculateButtons() + { + } + + protected virtual void CreateButtons() + { + // Attach events to button + if (_closeButton != null) + { + _closeButton.Click += new EventHandler(OnButtonClose); + _closeButton.GotFocus += new EventHandler(OnButtonGotFocus); + } + + if (_hideButton != null) + { + _hideButton.Click += new EventHandler(OnButtonHide); + _hideButton.GotFocus += new EventHandler(OnButtonGotFocus); + } + } + + public bool PreFilterMessage(ref Message m) + { + // Has a key been pressed? + if (m.Msg == (int)Win32.Msgs.WM_KEYDOWN) + { + // Is it the ESCAPE key? + if ((int)m.WParam == (int)Win32.VirtualKeys.VK_ESCAPE) + { + // Are we in redocking mode? + if (_redocker != null) + { + // Cancel the redocking activity + _redocker.QuitTrackingMode(null); + + // No longer need the object + _redocker = null; + + return true; + } + } + } + + return false; + } + } + + [ToolboxItem(false)] + public class WindowDetailCaptionPlain : WindowDetailCaption + { + protected enum ImageIndex + { + Close = 0, + EnabledHorizontalMax = 1, + EnabledHorizontalMin = 2, + EnabledVerticalMax = 3, + EnabledVerticalMin = 4, + AutoHide = 5, + AutoShow = 6 + } + + // Class constants + protected const int _inset = 3; + + protected const int _offset = 5; + protected const int _fixedLength = 14; + protected const int _imageWidth = 10; + protected const int _imageHeight = 10; + protected const int _buttonWidth = 12; + protected const int _buttonHeight = 12; + protected const int _insetButton = 2; + + // Instance fields + protected bool _dockLeft; + + protected int _buttonOffset; + + static WindowDetailCaptionPlain() + { + // Create a strip of images by loading an embedded bitmap resource + _images = ResourceHelper.LoadBitmapStrip(Type.GetType("Crownwood.Magic.Docking.WindowDetailCaptionPlain"), + "Crownwood.Magic.Resources.ImagesCaptionPlain.bmp", + new Size(_imageWidth, _imageHeight), + new Point(0, 0)); + } + + public WindowDetailCaptionPlain(DockingManager manager, + EventHandler closeHandler, + EventHandler restoreHandler, + EventHandler invertAutoHideHandler, + ContextHandler contextHandler) + : base(manager, + new Size(_fixedLength, _fixedLength), + closeHandler, + restoreHandler, + invertAutoHideHandler, + contextHandler) + { + // Default to thinking we are docked on a left edge + _dockLeft = true; + + // Modify painting to prevent overwriting the button control + _buttonOffset = 1 + (_buttonWidth + _insetButton) * 2; + } + + public override void ParentStateChanged(State newState) + { + // Should we dock to the left or top of our container? + switch (newState) + { + case State.DockTop: + case State.DockBottom: + _dockLeft = true; + break; + + case State.Floating: + case State.DockLeft: + case State.DockRight: + _dockLeft = false; + break; + } + + // Ignore the AutoHide feature when in floating form + _ignoreHideButton = (_parentWindow.State == State.Floating); + + RecalculateButtons(); + } + + public override void RemovedFromParent(Window parent) + { + if (parent != null) + { + if (this.Dock != DockStyle.None) + { + Size minSize = parent.MinimalSize; + + if (this.Dock == DockStyle.Left) + { + // Remove our width from the minimum size of the parent + minSize.Width -= _fixedLength; + } + else + { + // Remove our height from the minimum size of the parent + minSize.Height -= _fixedLength; + } + + parent.MinimalSize = minSize; + } + } + } + + public override void AddedToParent(Window parent) + { + if (parent != null) + { + if (this.Dock != DockStyle.None) + { + Size minSize = parent.MinimalSize; + + if (this.Dock == DockStyle.Left) + { + // Add our width from the minimum size of the parent + minSize.Width += _fixedLength; + } + else + { + // Add our height from the minimum size of the parent + minSize.Height += _fixedLength; + } + + parent.MinimalSize = minSize; + } + } + } + + protected override void DefineButtonRemapping() + { + // Define use of current system colors + ColorMap activeMap = new ColorMap(); + ColorMap inactiveMap = new ColorMap(); + + activeMap.OldColor = Color.Black; + activeMap.NewColor = _manager.InactiveTextColor; + inactiveMap.OldColor = Color.Black; + inactiveMap.NewColor = Color.FromArgb(128, _manager.InactiveTextColor); + + // Create remap attributes for use by button + _activeAttr.SetRemapTable(new ColorMap[] { activeMap }, ColorAdjustType.Bitmap); + _inactiveAttr.SetRemapTable(new ColorMap[] { inactiveMap }, ColorAdjustType.Bitmap); + } + + protected override void OnAddMaximizeInterface() + { + if (_maxButton != null) + { + _maxButton.Size = new Size(_buttonWidth, _buttonHeight); + + // Shows border all the time and not just when mouse is over control + _maxButton.PopupStyle = false; + + // Define the fixed remapping + _maxButton.ImageAttributes = _inactiveAttr; + + // Reduce the lines drawing + _buttonOffset += (_buttonWidth + _insetButton); + } + } + + protected override void OnRemoveMaximizeInterface() + { + // Reduce the lines drawing + _buttonOffset -= (_buttonWidth + _insetButton); + } + + protected override void CreateButtons() + { + // Define the ImageList and which ImageIndex to show initially + _closeButton = new InertButton(_images, (int)ImageIndex.Close); + _hideButton = new InertButton(_images, (int)ImageIndex.AutoHide); + + _closeButton.Size = new Size(_buttonWidth, _buttonHeight); + _hideButton.Size = new Size(_buttonWidth, _buttonHeight); + + // Shows border all the time and not just when mouse is over control + _closeButton.PopupStyle = false; + _hideButton.PopupStyle = false; + + // Define the fixed remapping + _closeButton.ImageAttributes = _activeAttr; + _hideButton.ImageAttributes = _activeAttr; + + // Add to the display + Controls.Add(_closeButton); + Controls.Add(_hideButton); + + // Let base class perform common actions + base.CreateButtons(); + } + + protected override void UpdateAutoHideImage() + { + if (_pinnedImage) + _hideButton.ImageIndexEnabled = (int)ImageIndex.AutoShow; + else + _hideButton.ImageIndexEnabled = (int)ImageIndex.AutoHide; + } + + protected override void UpdateMaximizeImage() + { + if (_showCloseButton) + _closeButton.ImageAttributes = _activeAttr; + else + _closeButton.ImageAttributes = _inactiveAttr; + + if (_showHideButton && !_ignoreHideButton) + _hideButton.ImageAttributes = _activeAttr; + else + _hideButton.ImageAttributes = _inactiveAttr; + + if (_maxButton != null) + { + if (_maxInterface.IsMaximizeAvailable()) + _maxButton.ImageAttributes = _activeAttr; + else + _maxButton.ImageAttributes = _inactiveAttr; + + bool maximized = _maxInterface.IsWindowMaximized(this.ParentWindow); + + if (_maxInterface.Direction == Direction.Vertical) + { + if (maximized) + _maxButton.ImageIndexEnabled = (int)ImageIndex.EnabledVerticalMin; + else + _maxButton.ImageIndexEnabled = (int)ImageIndex.EnabledVerticalMax; + } + else + { + if (maximized) + _maxButton.ImageIndexEnabled = (int)ImageIndex.EnabledHorizontalMin; + else + _maxButton.ImageIndexEnabled = (int)ImageIndex.EnabledHorizontalMax; + } + } + } + + protected override void RecalculateButtons() + { + if (_dockLeft) + { + if (this.Dock != DockStyle.Left) + { + RemovedFromParent(this.ParentWindow); + this.Dock = DockStyle.Left; + AddedToParent(this.ParentWindow); + } + + int iStart = _inset; + + // Button position is fixed, regardless of our size + _closeButton.Location = new Point(_insetButton, iStart); + _closeButton.Anchor = AnchorStyles.Top; + _closeButton.Show(); + iStart += _buttonHeight + _insetButton; + + // Button position is fixed, regardless of our size + _hideButton.Location = new Point(_insetButton, iStart); + _hideButton.Anchor = AnchorStyles.Top; + _hideButton.Show(); + iStart += _buttonHeight + _insetButton; + + if (_maxButton != null) + { + // Button position is fixed, regardless of our size + _maxButton.Location = new Point(_insetButton, iStart); + _maxButton.Anchor = AnchorStyles.Top; + } + } + else + { + if (this.Dock != DockStyle.Top) + { + RemovedFromParent(this.ParentWindow); + this.Dock = DockStyle.Top; + AddedToParent(this.ParentWindow); + } + + Size client = this.ClientSize; + int iStart = _inset; + + // Button is positioned to right hand side of bar + _closeButton.Location = new Point(client.Width - iStart - _buttonWidth, _insetButton); + _closeButton.Anchor = AnchorStyles.Right; + _closeButton.Show(); + iStart += _buttonWidth + _insetButton; + + // Next the AutoHide button is positioned + _hideButton.Location = new Point(client.Width - iStart - _buttonWidth, _insetButton); + _hideButton.Anchor = AnchorStyles.Right; + _hideButton.Show(); + iStart += _buttonWidth + _insetButton; + + if (_maxButton != null) + { + // Button position is fixed, regardless of our size + _maxButton.Location = new Point(client.Width - iStart - _buttonWidth, _insetButton); + _maxButton.Anchor = AnchorStyles.Right; + } + } + + UpdateMaximizeImage(); + } + + protected override void OnPaint(PaintEventArgs e) + { + Size ourSize = this.ClientSize; + Point[] light = new Point[4]; + Point[] dark = new Point[4]; + + // Depends on orientation + if (_dockLeft) + { + int iBottom = ourSize.Height - _inset - 1; + int iRight = _offset + 2; + int iTop = _inset + _buttonOffset; + + light[3].X = light[2].X = light[0].X = _offset; + light[2].Y = light[1].Y = light[0].Y = iTop; + light[1].X = _offset + 1; + light[3].Y = iBottom; + + dark[2].X = dark[1].X = dark[0].X = iRight; + dark[3].Y = dark[2].Y = dark[1].Y = iBottom; + dark[0].Y = iTop; + dark[3].X = iRight - 1; + } + else + { + int iBottom = _offset + 2; + int iRight = ourSize.Width - (_inset + _buttonOffset); + + light[3].X = light[2].X = light[0].X = _inset; + light[1].Y = light[2].Y = light[0].Y = _offset; + light[1].X = iRight; + light[3].Y = _offset + 1; + + dark[2].X = dark[1].X = dark[0].X = iRight; + dark[3].Y = dark[2].Y = dark[1].Y = iBottom; + dark[0].Y = _offset; + dark[3].X = _inset; + } + + using (Pen lightPen = new Pen(ControlPaint.LightLight(_manager.BackColor)), + darkPen = new Pen(ControlPaint.Dark(_manager.BackColor))) + { + e.Graphics.DrawLine(lightPen, light[0], light[1]); + e.Graphics.DrawLine(lightPen, light[2], light[3]); + e.Graphics.DrawLine(darkPen, dark[0], dark[1]); + e.Graphics.DrawLine(darkPen, dark[2], dark[3]); + + // Shift coordinates to draw section grab bar + if (_dockLeft) + { + for (int i = 0; i < 4; i++) + { + light[i].X += 4; + dark[i].X += 4; + } + } + else + { + for (int i = 0; i < 4; i++) + { + light[i].Y += 4; + dark[i].Y += 4; + } + } + + e.Graphics.DrawLine(lightPen, light[0], light[1]); + e.Graphics.DrawLine(lightPen, light[2], light[3]); + e.Graphics.DrawLine(darkPen, dark[0], dark[1]); + e.Graphics.DrawLine(darkPen, dark[2], dark[3]); + } + + base.OnPaint(e); + } + } + + public class WindowDetailCaptionIDE : WindowDetailCaption + { + protected enum ImageIndex + { + Close = 0, + EnabledVerticalMax = 1, + EnabledVerticalMin = 2, + AutoHide = 3, + AutoShow = 4 + } + + // Class constants + protected const int _yInset = 3; + + protected const int _yInsetExtra = 3; + protected const int _imageWidth = 12; + protected const int _imageHeight = 11; + protected const int _buttonWidth = 14; + protected const int _buttonHeight = 13; + protected const int _buttonSpacer = 3; + + // Class fields + protected static int _fixedLength; + + static WindowDetailCaptionIDE() + { + // Create a strip of images by loading an embedded bitmap resource + _images = ResourceHelper.LoadBitmapStrip(Type.GetType("Crownwood.Magic.Docking.WindowDetailCaptionIDE"), + "Crownwood.Magic.Resources.ImagesCaptionIDE.bmp", + new Size(_imageWidth, _imageHeight), + new Point(0, 0)); + } + + public WindowDetailCaptionIDE(DockingManager manager, + EventHandler closeHandler, + EventHandler restoreHandler, + EventHandler invertAutoHideHandler, + ContextHandler contextHandler) + : base(manager, + new Size(_fixedLength, _fixedLength), + closeHandler, + restoreHandler, + invertAutoHideHandler, + contextHandler) + { + // Use specificed font in the caption + UpdateCaptionHeight(manager.CaptionFont); + } + + public override void PropogateNameValue(PropogateName name, object value) + { + base.PropogateNameValue(name, value); + + switch (name) + { + case PropogateName.CaptionFont: + UpdateCaptionHeight((Font)value); + break; + + case PropogateName.ActiveTextColor: + case PropogateName.InactiveTextColor: + DefineButtonRemapping(); + Invalidate(); + break; + } + } + + public override void WindowGotFocus() + { + SetButtonState(); + Invalidate(); + } + + public override void WindowLostFocus() + { + SetButtonState(); + Invalidate(); + } + + public override void NotifyFullTitleText(string title) + { + this.Text = title; + Invalidate(); + } + + public override void ParentStateChanged(State newState) + { + // Ignore the AutoHide feature when in floating form + _ignoreHideButton = (_parentWindow.State == State.Floating); + + this.Dock = DockStyle.Top; + RecalculateButtons(); + Invalidate(); + } + + public override void RemovedFromParent(Window parent) + { + if (parent != null) + { + Size minSize = parent.MinimalSize; + + // Remove our height from the minimum size of the parent + minSize.Height -= _fixedLength; + minSize.Width -= _fixedLength; + + parent.MinimalSize = minSize; + } + } + + protected override void DefineButtonRemapping() + { + // Define use of current system colors + ColorMap activeMap = new ColorMap(); + ColorMap inactiveMap = new ColorMap(); + + activeMap.OldColor = Color.Black; + activeMap.NewColor = _manager.ActiveTextColor; + inactiveMap.OldColor = Color.Black; + inactiveMap.NewColor = _manager.InactiveTextColor; + + // Create remap attributes for use by button + _activeAttr.SetRemapTable(new ColorMap[] { activeMap }, ColorAdjustType.Bitmap); + _inactiveAttr.SetRemapTable(new ColorMap[] { inactiveMap }, ColorAdjustType.Bitmap); + } + + public override void AddedToParent(Window parent) + { + if (parent != null) + { + Size minSize = parent.MinimalSize; + + // Remove our height from the minimum size of the parent + minSize.Height += _fixedLength; + minSize.Width += _fixedLength; + + parent.MinimalSize = minSize; + } + } + + protected override void OnAddMaximizeInterface() + { + if (_maxButton != null) + { + // Set the correct size for the button + _maxButton.Size = new Size(_buttonWidth, _buttonHeight); + + // Give the button a very thin button + _maxButton.BorderWidth = 1; + + // Define correct color setup + _maxButton.BackColor = this.BackColor; + _maxButton.ImageAttributes = _inactiveAttr; + + // Force the ImageAttribute for the button to be set + SetButtonState(); + } + } + + protected override void UpdateAutoHideImage() + { + if (_pinnedImage) + _hideButton.ImageIndexEnabled = (int)ImageIndex.AutoShow; + else + _hideButton.ImageIndexEnabled = (int)ImageIndex.AutoHide; + } + + protected override void UpdateMaximizeImage() + { + if ((_maxButton != null) && (_maxInterface != null)) + { + bool enabled = _maxInterface.IsMaximizeAvailable(); + + if (!enabled) + { + if (_maxButton.Visible) + _maxButton.Hide(); + } + else + { + bool maximized = _maxInterface.IsWindowMaximized(this.ParentWindow); + + if (!_maxButton.Visible) + _maxButton.Show(); + + if (maximized) + _maxButton.ImageIndexEnabled = (int)ImageIndex.EnabledVerticalMin; + else + _maxButton.ImageIndexEnabled = (int)ImageIndex.EnabledVerticalMax; + } + } + } + + protected void SetButtonState() + { + if (this.ParentWindow != null) + { + if (this.ParentWindow.ContainsFocus) + { + if (_closeButton.BackColor != _manager.ActiveColor) + { + _closeButton.BackColor = _manager.ActiveColor; + _closeButton.ImageAttributes = _activeAttr; + _closeButton.Invalidate(); + } + + if (_hideButton != null) + { + if (_hideButton.BackColor != _manager.ActiveColor) + { + _hideButton.BackColor = _manager.ActiveColor; + _hideButton.ImageAttributes = _activeAttr; + _hideButton.Invalidate(); + } + } + + if (_maxButton != null) + { + if (_maxButton.BackColor != _manager.ActiveColor) + { + _maxButton.BackColor = _manager.ActiveColor; + _maxButton.ImageAttributes = _activeAttr; + _maxButton.Invalidate(); + } + } + } + else + { + if (_closeButton.BackColor != this.BackColor) + { + _closeButton.BackColor = this.BackColor; + _closeButton.ImageAttributes = _inactiveAttr; + _closeButton.Invalidate(); + } + + if (_hideButton != null) + { + if (_hideButton.BackColor != this.BackColor) + { + _hideButton.BackColor = this.BackColor; + _hideButton.ImageAttributes = _inactiveAttr; + _hideButton.Invalidate(); + } + } + + if (_maxButton != null) + { + if (_maxButton.BackColor != this.BackColor) + { + _maxButton.BackColor = this.BackColor; + _maxButton.ImageAttributes = _inactiveAttr; + _maxButton.Invalidate(); + } + } + } + } + } + + protected override void RecalculateButtons() + { + int buttonX = this.Width - _buttonWidth - _buttonSpacer; + int buttonY = (_fixedLength - _yInset * 2 - _buttonHeight) / 2 + _yInset; + + if (_showCloseButton) + { + // Button position is fixed, regardless of our size + _closeButton.Location = new Point(buttonX, buttonY); + + _closeButton.Size = new Size(_buttonWidth, _buttonHeight); + + // Give the button a very thin button + _closeButton.BorderWidth = 1; + + // Let the location of the control be updated for us + _closeButton.Anchor = AnchorStyles.Right; + + // Just in case currently hidden + _closeButton.Show(); + + // Define start of next button + buttonX -= _buttonWidth; + } + else + _closeButton.Hide(); + + if (_showHideButton && !_ignoreHideButton) + { + // Button position is fixed, regardless of our size + _hideButton.Location = new Point(buttonX, buttonY); + + _hideButton.Size = new Size(_buttonWidth, _buttonHeight); + + // Give the button a very thin button + _hideButton.BorderWidth = 1; + + // Let the location of the control be updated for us + _hideButton.Anchor = AnchorStyles.Right; + + // Just in case currently hidden + _hideButton.Show(); + + // Define start of next button + buttonX -= _buttonWidth; + + UpdateAutoHideImage(); + } + else + _hideButton.Hide(); + + if (_maxButton != null) + { + // Button position is fixed, regardless of our size + _maxButton.Location = new Point(buttonX, buttonY); + + _maxButton.Size = new Size(_buttonWidth, _buttonHeight); + + // Give the button a very thin button + _maxButton.BorderWidth = 1; + + // Let the location of the control be updated for us + _maxButton.Anchor = AnchorStyles.Right; + + // Define start of next button + buttonX -= _buttonWidth; + + UpdateMaximizeImage(); + } + } + + protected override void CreateButtons() + { + // Define the ImageList and which ImageIndex to show initially + _closeButton = new InertButton(_images, (int)ImageIndex.Close); + _hideButton = new InertButton(_images, (int)ImageIndex.AutoHide); + + _closeButton.Size = new Size(_buttonWidth, _buttonHeight); + _hideButton.Size = new Size(_buttonWidth, _buttonHeight); + + // Let the location of the control be updated for us + _closeButton.Anchor = AnchorStyles.Right; + _hideButton.Anchor = AnchorStyles.Right; + + // Define the button position relative to the size set in the constructor + _closeButton.Location = new Point(_fixedLength - _buttonWidth - _buttonSpacer, + (_fixedLength - _yInset * 2 - _buttonHeight) / 2 + _yInset); + + _hideButton.Location = new Point(_fixedLength - (_buttonWidth - _buttonSpacer) * 2, + (_fixedLength - _yInset * 2 - _buttonHeight) / 2 + _yInset); + + // Give the button a very thin button + _closeButton.BorderWidth = 1; + _hideButton.BorderWidth = 1; + + // Define correct color setup + _closeButton.BackColor = this.BackColor; + _closeButton.ImageAttributes = _inactiveAttr; + _hideButton.BackColor = this.BackColor; + _hideButton.ImageAttributes = _inactiveAttr; + + // Add to the display + Controls.Add(_closeButton); + Controls.Add(_hideButton); + + // Let base class perform common actions + base.CreateButtons(); + } + + protected void UpdateCaptionHeight(Font captionFont) + { + // Dynamically calculate the required height of the caption area + _fixedLength = (int)captionFont.GetHeight() + (_yInset + _yInsetExtra) * 2; + + int minHeight = _buttonHeight + _yInset * 4 + 1; + + // Maintain a minimum height to allow correct showing of buttons + if (_fixedLength < minHeight) + _fixedLength = minHeight; + + this.Size = new Size(_fixedLength, _fixedLength); + + RecalculateButtons(); + + Invalidate(); + } + + protected override void OnPaintBackground(PaintEventArgs e) + { + // Overriden to prevent background being painted + } + + protected override void OnPaint(PaintEventArgs e) + { + bool focused = false; + + if (this.ParentWindow != null) + focused = this.ParentWindow.ContainsFocus; + + // Sometimes the min/max button is created and then an attempt is made to + // hide the button. But for some reason it does not always manage to hide + // the button. So forced to check here everytime to ensure its hidden. + UpdateMaximizeImage(); + + SetButtonState(); + + Size ourSize = this.ClientSize; + + int xEnd = ourSize.Width; + int yEnd = ourSize.Height - _yInset * 2; + + Rectangle rectCaption = new Rectangle(0, _yInset, xEnd, yEnd - _yInset + 1); + + using (SolidBrush backBrush = new SolidBrush(this.BackColor), + activeBrush = new SolidBrush(_manager.ActiveColor), + activeTextBrush = new SolidBrush(_manager.ActiveTextColor), + inactiveBrush = new SolidBrush(_manager.InactiveTextColor)) + { + // Is this control Active? + if (focused) + { + // Fill the entire background area + e.Graphics.FillRectangle(backBrush, e.ClipRectangle); + + // Use a solid filled background for text + e.Graphics.FillRectangle(activeBrush, rectCaption); + + // Start drawing text a little from the left + rectCaption.X += _buttonSpacer; + rectCaption.Y += 1; + rectCaption.Height -= 2; + + // Reduce the width to account for close button + rectCaption.Width -= _closeButton.Width + _buttonSpacer; + + // Reduce width to account for the optional maximize button + if ((_maxButton != null) && (_maxButton.Visible)) + rectCaption.Width -= _closeButton.Width; + + e.Graphics.DrawString(this.Text, _manager.CaptionFont, activeTextBrush, rectCaption); + } + else + { + // Fill the entire background area + e.Graphics.FillRectangle(backBrush, e.ClipRectangle); + + // Inactive and so use a rounded rectangle + using (Pen dark = new Pen(ControlPaint.LightLight(_manager.InactiveTextColor))) + { + e.Graphics.DrawLine(dark, 1, _yInset, xEnd - 2, _yInset); + e.Graphics.DrawLine(dark, 1, yEnd, xEnd - 2, yEnd); + e.Graphics.DrawLine(dark, 0, _yInset + 1, 0, yEnd - 1); + e.Graphics.DrawLine(dark, xEnd - 1, _yInset + 1, xEnd - 1, yEnd - 1); + + // Start drawing text a little from the left + rectCaption.X += _buttonSpacer; + rectCaption.Y += 1; + rectCaption.Height -= 2; + + // Reduce the width to account for close button + rectCaption.Width -= _closeButton.Width + _buttonSpacer; + + // Reduce width to account for the optional maximize button + if ((_maxButton != null) && (_maxButton.Visible)) + rectCaption.Width -= _maxButton.Width; + + e.Graphics.DrawString(this.Text, _manager.CaptionFont, inactiveBrush, rectCaption); + } + } + } + + // Let delegates fire through base + base.OnPaint(e); + + // Always get the button to repaint as we have painted over their area + _closeButton.Refresh(); + } + } +} \ No newline at end of file diff --git a/Labyrinth3/Crownwood.Magic/Docking/WindowDetailCaption.resx b/Labyrinth3/Crownwood.Magic/Docking/WindowDetailCaption.resx new file mode 100644 index 0000000..7e32396 --- /dev/null +++ b/Labyrinth3/Crownwood.Magic/Docking/WindowDetailCaption.resx @@ -0,0 +1,42 @@ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + text/microsoft-resx + + + 1.0.0.0 + + + System.Resources.ResXResourceReader, System.Windows.Forms, Version=1.0.3102.0, Culture=neutral, PublicKeyToken=b77a5c561934e089 + + + System.Resources.ResXResourceWriter, System.Windows.Forms, Version=1.0.3102.0, Culture=neutral, PublicKeyToken=b77a5c561934e089 + + diff --git a/Labyrinth3/Crownwood.Magic/Docking/Zone.cs b/Labyrinth3/Crownwood.Magic/Docking/Zone.cs new file mode 100644 index 0000000..c588d09 --- /dev/null +++ b/Labyrinth3/Crownwood.Magic/Docking/Zone.cs @@ -0,0 +1,168 @@ +// ***************************************************************************** +// +// (c) Crownwood Consulting Limited 2002-2003 +// All rights reserved. The software and associated documentation +// supplied hereunder are the proprietary information of Crownwood Consulting +// Limited, Crownwood, Bracknell, Berkshire, England and are supplied subject +// to licence terms. +// +// Magic Version 1.7.4.0 www.dotnetmagic.com +// ***************************************************************************** + +using Crownwood.Magic.Collections; +using System; +using System.ComponentModel; +using System.Drawing; +using System.Windows.Forms; + +namespace Crownwood.Magic.Docking +{ + [ToolboxItem(false)] + public class Zone : Panel + { + // Instance fields + protected State _state; + + protected bool _autoDispose; + protected DockingManager _manager; + protected WindowCollection _windows; + + public Zone(DockingManager manager) + { + InternalConstruct(manager, State.DockLeft); + } + + public Zone(DockingManager manager, State state) + { + InternalConstruct(manager, state); + } + + protected void InternalConstruct(DockingManager manager, State state) + { + // Must provide a valid manager instance + if (manager == null) + throw new ArgumentNullException("DockingManager"); + + // Remember initial state + _state = state; + _manager = manager; + _autoDispose = true; + + // Get correct starting state from manager + this.BackColor = _manager.BackColor; + this.ForeColor = _manager.InactiveTextColor; + + // Create collection of windows + _windows = new WindowCollection(); + + // We want notification when contents are added/removed/cleared + _windows.Clearing += new CollectionClear(OnWindowsClearing); + _windows.Inserted += new CollectionChange(OnWindowInserted); + _windows.Removing += new CollectionChange(OnWindowRemoving); + _windows.Removed += new CollectionChange(OnWindowRemoved); + } + + public virtual State State + { + get { return _state; } + set { _state = value; } + } + + public bool AutoDispose + { + get { return _autoDispose; } + set { _autoDispose = value; } + } + + public DockingManager DockingManager + { + get { return _manager; } + } + + public WindowCollection Windows + { + get { return _windows; } + + set + { + _windows.Clear(); + _windows = value; + } + } + + public virtual Restore RecordRestore(Window w, object child, Restore childRestore) + { + return null; + } + + public virtual int MinimumWidth { get { return 0; } } + public virtual int MinimumHeight { get { return 0; } } + + public virtual void PropogateNameValue(PropogateName name, object value) + { + if (name == PropogateName.BackColor) + { + this.BackColor = (Color)value; + Invalidate(); + } + + // Pass onto each of our child Windows + foreach (Window w in _windows) + w.PropogateNameValue(name, value); + } + + protected virtual void OnWindowsClearing() + { + foreach (Control c in Controls) + { + Window w = c as Window; + + // Remove back pointers from Windows to this Zone + if (w != null) + w.ParentZone = null; + } + + // Should we kill ourself? + if (this.AutoDispose) + { + // Remove notification when contents are added/removed/cleared + _windows.Clearing -= new CollectionClear(OnWindowsClearing); + _windows.Inserted -= new CollectionChange(OnWindowInserted); + _windows.Removing -= new CollectionChange(OnWindowRemoving); + _windows.Removed -= new CollectionChange(OnWindowRemoved); + + this.Dispose(); + } + } + + protected virtual void OnWindowInserted(int index, object value) + { + Window w = value as Window; + + // Define back pointer from Window to its new Zone + w.ParentZone = this; + + // Define the State the Window should adopt + w.State = _state; + } + + protected virtual void OnWindowRemoving(int index, object value) + { + Window w = value as Window; + + // Remove back pointer from Window to this Zone + w.ParentZone = null; + } + + protected virtual void OnWindowRemoved(int index, object value) + { + // Removed the last entry? + if (_windows.Count == 0) + { + // Should we kill ourself? + if (this.AutoDispose) + this.Dispose(); + } + } + } +} \ No newline at end of file diff --git a/Labyrinth3/Crownwood.Magic/Docking/Zone.resx b/Labyrinth3/Crownwood.Magic/Docking/Zone.resx new file mode 100644 index 0000000..7e32396 --- /dev/null +++ b/Labyrinth3/Crownwood.Magic/Docking/Zone.resx @@ -0,0 +1,42 @@ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + text/microsoft-resx + + + 1.0.0.0 + + + System.Resources.ResXResourceReader, System.Windows.Forms, Version=1.0.3102.0, Culture=neutral, PublicKeyToken=b77a5c561934e089 + + + System.Resources.ResXResourceWriter, System.Windows.Forms, Version=1.0.3102.0, Culture=neutral, PublicKeyToken=b77a5c561934e089 + + diff --git a/Labyrinth3/Crownwood.Magic/Docking/ZoneHelper.cs b/Labyrinth3/Crownwood.Magic/Docking/ZoneHelper.cs new file mode 100644 index 0000000..6a106e8 --- /dev/null +++ b/Labyrinth3/Crownwood.Magic/Docking/ZoneHelper.cs @@ -0,0 +1,96 @@ +// ***************************************************************************** +// +// (c) Crownwood Consulting Limited 2002-2003 +// All rights reserved. The software and associated documentation +// supplied hereunder are the proprietary information of Crownwood Consulting +// Limited, Crownwood, Bracknell, Berkshire, England and are supplied subject +// to licence terms. +// +// Magic Version 1.7.4.0 www.dotnetmagic.com +// ***************************************************************************** + +using Crownwood.Magic.Collections; + +namespace Crownwood.Magic.Docking +{ + public class ZoneHelper + { + public static ContentCollection Contents(Zone z) + { + // Container for returned group of found Content objects + ContentCollection cc = new ContentCollection(); + + // Process each Window in the Zone + foreach (Window w in z.Windows) + { + WindowContent wc = w as WindowContent; + + // Is the Zone a Content derived variation? + if (wc != null) + { + // Add each Content into the collection + foreach (Content c in wc.Contents) + cc.Add(c); + } + } + + return cc; + } + + public static StringCollection ContentNames(Zone z) + { + // Container for returned group of found String objects + StringCollection sc = new StringCollection(); + + // Process each Window in the Zone + foreach (Window w in z.Windows) + { + WindowContent wc = w as WindowContent; + + // Is the Zone a Content derived variation? + if (wc != null) + { + // Add each Content into the collection + foreach (Content c in wc.Contents) + sc.Add(c.Title); + } + } + + return sc; + } + + public static StringCollection ContentNamesInPriority(Zone z, Content c) + { + // Container for returned group of found Content objects + StringCollection sc = new StringCollection(); + + // Process each Window in the Zone + foreach (Window w in z.Windows) + { + WindowContent wc = w as WindowContent; + + // Is the Zone a Content derived variation? + if (wc != null) + { + // Does this contain the interesting Content? + if (wc.Contents.Contains(c)) + { + // All Content of this Window are given priority and + // added into the start of the collection + foreach (Content content in wc.Contents) + sc.Insert(0, content.Title); + } + else + { + // Lower priority Window and so contents are always + // added to the end of the collection + foreach (Content content in wc.Contents) + sc.Add(content.Title); + } + } + } + + return sc; + } + } +} \ No newline at end of file diff --git a/Labyrinth3/Crownwood.Magic/Docking/ZoneSequence.cs b/Labyrinth3/Crownwood.Magic/Docking/ZoneSequence.cs new file mode 100644 index 0000000..bbd18bc --- /dev/null +++ b/Labyrinth3/Crownwood.Magic/Docking/ZoneSequence.cs @@ -0,0 +1,1435 @@ +// ***************************************************************************** +// +// (c) Crownwood Consulting Limited 2002-2003 +// All rights reserved. The software and associated documentation +// supplied hereunder are the proprietary information of Crownwood Consulting +// Limited, Crownwood, Bracknell, Berkshire, England and are supplied subject +// to licence terms. +// +// Magic Version 1.7.4.0 www.dotnetmagic.com +// ***************************************************************************** + +using Crownwood.Magic.Collections; +using Crownwood.Magic.Common; +using Crownwood.Magic.Controls; +using System; +using System.ComponentModel; +using System.Drawing; +using System.Windows.Forms; + +namespace Crownwood.Magic.Docking +{ + [ToolboxItem(false)] + public class ZoneSequence : Zone, IHotZoneSource, IZoneMaximizeWindow, IResizeSource + { + protected struct Position + { + public int length; + } + + // Class constants + protected const int _spacePrecision = 3; + + protected const int _hotVectorBeforeControl = 5; + + // Instance fields + protected VisualStyle _style; + + protected Direction _direction; + protected ResizeBar _resizeBar; + protected Window _maximizedWindow; + protected bool _suppressReposition; + protected bool _zoneMinMax; + + // Instance events + public event EventHandler RefreshMaximize; + + public ZoneSequence(DockingManager manager) + : base(manager) + { + InternalConstruct(VisualStyle.IDE, Direction.Vertical, true); + } + + public ZoneSequence(DockingManager manager, State state, VisualStyle style, Direction direction, bool zoneMinMax) + : base(manager, state) + { + InternalConstruct(style, direction, zoneMinMax); + } + + protected void InternalConstruct(VisualStyle style, Direction direction, bool zoneMinMax) + { + // Remember initial state + _style = style; + _direction = direction; + _maximizedWindow = null; + _suppressReposition = false; + _zoneMinMax = zoneMinMax; + + // Create the control used to resize the whole Zone + _resizeBar = new ResizeBar(_direction, this); + + // Place last in the list of child Controls + Controls.Add(_resizeBar); + + // Start of very small and let first content determine new size + this.Size = new Size(0, 0); + + // Do not inherit the parent BackColor, we want the .Control color as + // this blends in with the way all the docking windows are drawn + this.BackColor = SystemColors.Control; + this.ForeColor = SystemColors.ControlText; + } + + public override int MinimumWidth + { + get { return _resizeBar.Width * 5; } + } + + public override int MinimumHeight + { + get { return _resizeBar.Height * 6; } + } + + public override DockStyle Dock + { + get { return base.Dock; } + + set + { + base.Dock = value; + + RepositionControls(); + } + } + + public Direction Direction + { + get { return _direction; } + + set + { + if (_direction != value) + _direction = value; + } + } + + public override State State + { + set + { + base.State = value; + + // Inform each Window of the new requried state + foreach (Window w in _windows) + w.State = value; + + RepositionControls(); + } + } + + public void SuppressReposition() + { + _suppressReposition = true; + } + + public bool IsMaximizeAvailable() + { + return (_windows.Count > 1) && _zoneMinMax; + } + + public bool IsWindowMaximized(Window w) + { + return (w == _maximizedWindow); + } + + public void MaximizeWindow(Window w) + { + // Remember the newly maximized Window + _maximizedWindow = w; + + // Inform all interested parties of change + OnRefreshMaximize(EventArgs.Empty); + + RepositionControls(); + } + + public void RestoreWindow() + { + // Remember the newly maximized Window + _maximizedWindow = null; + + // Inform all interested parties of change + OnRefreshMaximize(EventArgs.Empty); + + RepositionControls(); + } + + public virtual void OnRefreshMaximize(EventArgs e) + { + // Any attached event handlers? + if (RefreshMaximize != null) + RefreshMaximize(this, e); + } + + public Color ResizeBarColor + { + get { return _manager.ResizeBarColor; } + } + + public int ResizeBarVector + { + get { return _manager.ResizeBarVector; } + } + + public VisualStyle Style + { + get { return _manager.Style; } + } + + public Color BackgroundColor + { + get { return _manager.BackColor; } + } + + public bool CanResize(ResizeBar bar) + { + // Is this the Window resize bar? + if (bar != _resizeBar) + { + // Find position of this ResizeBar in the Controls collection + int barIndex = Controls.IndexOf(bar); + + // The Window before this bar must be the one before it in the collection + Window wBefore = Controls[barIndex - 1] as Window; + + // The Window after this bar must be the one after it in the Window collection + Window wAfter = _windows[_windows.IndexOf(wBefore) + 1]; + + // If Windows either side of the bar have no space then cannot resize there relative positions + if (((wBefore.ZoneArea <= 0m) && (wAfter.ZoneArea <= 0m))) + return false; + + // If in maximized state and the bar is not connected to the maximized window + if ((_maximizedWindow != null) && (_maximizedWindow != wBefore) && (_maximizedWindow != wAfter)) + return false; + } + + return true; + } + + public bool StartResizeOperation(ResizeBar bar, ref Rectangle screenBoundary) + { + // Is this the Zone level resize bar? + if (bar == _resizeBar) + { + // Define resize boundary as the inner area of the Form containing the Zone + screenBoundary = this.Parent.RectangleToScreen(_manager.InnerResizeRectangle(this)); + + // Find the screen limits of this Zone + Rectangle zoneBoundary = RectangleToScreen(this.ClientRectangle); + + int minHeight = this.MinimumHeight; + int minWidth = this.MinimumWidth; + + // Restrict resize based on which edge we are attached against + switch (_state) + { + case State.DockTop: + { + // Restrict Zone being made smaller than its minimum height + int diff = zoneBoundary.Top - screenBoundary.Top + minHeight; + screenBoundary.Y += diff; + screenBoundary.Height -= diff; + + // Restrict Zone from making inner control smaller than minimum allowed + int innerMinimumWidth = _manager.InnerMinimum.Height; + screenBoundary.Height -= innerMinimumWidth; + } + break; + + case State.DockBottom: + { + // Restrict Zone being made smaller than its minimum height + int diff = zoneBoundary.Bottom - screenBoundary.Bottom - minHeight; + screenBoundary.Height += diff; + + // Restrict Zone from making inner control smaller than minimum allowed + int innerMinimumWidth = _manager.InnerMinimum.Height; + screenBoundary.Y += innerMinimumWidth; + screenBoundary.Height -= innerMinimumWidth; + } + break; + + case State.DockLeft: + { + // Restrict Zone being made smaller than its minimum width + int diff = zoneBoundary.Left - screenBoundary.Left + minWidth; + screenBoundary.X += diff; + screenBoundary.Width -= diff; + + // Restrict Zone from making inner control smaller than minimum allowed + int innerMinimumWidth = _manager.InnerMinimum.Width; + screenBoundary.Width -= innerMinimumWidth; + } + break; + + case State.DockRight: + { + // Restrict Zone being made smaller than its minimum width + int diff = zoneBoundary.Right - screenBoundary.Right - minWidth; + screenBoundary.Width += diff; + + // Restrict Zone from making inner control smaller than minimum allowed + int innerMinimumWidth = _manager.InnerMinimum.Width; + screenBoundary.X += innerMinimumWidth; + screenBoundary.Width -= innerMinimumWidth; + } + break; + } + } + else + { + // Find position of this ResizeBar in the Controls collection + int barIndex = Controls.IndexOf(bar); + + // Define resize boundary as the client area of the Zone + screenBoundary = RectangleToScreen(this.ClientRectangle); + + // The Window before this bar must be the one before it in the collection + Window wBefore = Controls[barIndex - 1] as Window; + + // The Window after this bar must be the one after it in the Window collection + Window wAfter = _windows[_windows.IndexOf(wBefore) + 1]; + + // Find screen rectangle for the Windows either side of the bar + Rectangle rectBefore = wBefore.RectangleToScreen(wBefore.ClientRectangle); + Rectangle rectAfter = wAfter.RectangleToScreen(wAfter.ClientRectangle); + + // Reduce the boundary in the appropriate direction + if (_direction == Direction.Vertical) + { + screenBoundary.Y = rectBefore.Y + wBefore.MinimalSize.Height; + screenBoundary.Height -= screenBoundary.Bottom - rectAfter.Bottom; + screenBoundary.Height -= wAfter.MinimalSize.Height; + } + else + { + screenBoundary.X = rectBefore.X + wBefore.MinimalSize.Width; + screenBoundary.Width -= screenBoundary.Right - rectAfter.Right; + screenBoundary.Width -= wAfter.MinimalSize.Width; + } + } + + // Allow resize operation to occur + return true; + } + + public void EndResizeOperation(ResizeBar bar, int delta) + { + // Is this the Zone level resize bar? + if (bar == _resizeBar) + { + switch (this.Dock) + { + case DockStyle.Left: + this.Width += delta; + break; + + case DockStyle.Right: + this.Width -= delta; + break; + + case DockStyle.Top: + this.Height += delta; + break; + + case DockStyle.Bottom: + this.Height -= delta; + break; + } + } + else + { + // Find position of this ResizeBar in the Controls collection + int barIndex = Controls.IndexOf(bar); + + // The Window relating to this bar must be the one before it in the collection + Window w = Controls[barIndex - 1] as Window; + + // Is the Window being expanded + ModifyWindowSpace(w, delta); + } + } + + public override Restore RecordRestore(Window w, object child, Restore childRestore) + { + Content c = child as Content; + + // We currently only understand Windows that have Content as children + if (c != null) + { + StringCollection best; + StringCollection next; + StringCollection previous; + + GetWindowContentFriends(w, out best, out next, out previous); + + // Create a restore object that will find the correct WindowContent to + // place a Content in within a specified Zone, or it will create a new + // WindowContent in an appropriate relative ordering + Restore zoneRestore = new RestoreZoneAffinity(childRestore, c, best, next, previous); + + if (_state == State.Floating) + { + // Create a restore object to find the correct Floating Form to restore inside + // or it will create a new Floating Form as appropriate + return new RestoreContentFloatingAffinity(zoneRestore, _state, c, best, ZoneHelper.ContentNames(this)); + } + else + { + StringCollection zoneBest; + StringCollection zoneNext; + StringCollection zonePrevious; + StringCollection zoneNextAll; + StringCollection zonePreviousAll; + + GetZoneContentFriends(c, out zoneBest, out zoneNext, out zonePrevious, + out zoneNextAll, out zonePreviousAll); + + // Create a restore object able to find the correct Zone in the appropriate + // docking direction and then restore into that Zone. If no appropriate Zone + // found then create a new one + return new RestoreContentDockingAffinity(zoneRestore, _state, c, zoneBest, + zoneNext, zonePrevious, + zoneNextAll, zonePreviousAll); + } + } + + return null; + } + + public override void PropogateNameValue(PropogateName name, object value) + { + base.PropogateNameValue(name, value); + + // Reduce flicker during update + SuspendLayout(); + + if (name == PropogateName.ZoneMinMax) + { + if (_zoneMinMax != (bool)value) + { + // Remember the new value + _zoneMinMax = (bool)value; + + // If turning off the min/max ability + if (!_zoneMinMax) + _maximizedWindow = null; // no window can be currently maximized + + // Get child windows to retest the maximize capability + OnRefreshMaximize(EventArgs.Empty); + } + } + + // Update each resize bar control + foreach (Control c in this.Controls) + { + ResizeBar rb = c as ResizeBar; + + if (rb != null) + rb.PropogateNameValue(name, value); + } + + // Recalculate positions using new values + RepositionControls(); + + ResumeLayout(); + } + + protected void GetZoneContentFriends(Content c, + out StringCollection zoneBest, + out StringCollection zoneNext, + out StringCollection zonePrevious, + out StringCollection zoneNextAll, + out StringCollection zonePreviousAll) + { + // Out best friends are all those Content inside this Zone but with the ones + // in the same Window as the first in list and so the highest priority + zoneBest = ZoneHelper.ContentNamesInPriority(this, c); + + zoneNext = new StringCollection(); + zonePrevious = new StringCollection(); + zoneNextAll = new StringCollection(); + zonePreviousAll = new StringCollection(); + + bool before = true; + + foreach (Control control in _manager.Container.Controls) + { + Zone z = control as Zone; + + if (z != null) + { + if (z == this) + before = false; + else + { + ContentCollection newContent = ZoneHelper.Contents(z); + + foreach (Content content in newContent) + { + if (before) + { + if (z.State == this.State) + zonePrevious.Add(content.Title); + + zonePreviousAll.Add(content.Title); + } + else + { + if (z.State == this.State) + zoneNext.Add(content.Title); + + zoneNextAll.Add(content.Title); + } + } + + newContent.Clear(); + } + } + } + } + + protected void GetWindowContentFriends(Window match, + out StringCollection best, + out StringCollection next, + out StringCollection previous) + { + best = new StringCollection(); + next = new StringCollection(); + previous = new StringCollection(); + + bool before = true; + + foreach (Window w in _windows) + { + WindowContent wc = w as WindowContent; + + // Is this the Window we are searching for? + if (w == match) + { + if (wc != null) + { + // Best friends are those in the matching Window + foreach (Content content in wc.Contents) + best.Add(content.Title); + } + + before = false; + } + else + { + if (wc != null) + { + // Remember all found Content in appropriate next/previous collection + foreach (Content content in wc.Contents) + { + if (before) + previous.Add(content.Title); + else + next.Add(content.Title); + } + } + } + } + } + + public void AddHotZones(Redocker redock, HotZoneCollection collection) + { + RedockerContent redocker = redock as RedockerContent; + + // Allow all the Window objects a chance to add HotZones + foreach (Window w in _windows) + { + IHotZoneSource ag = w as IHotZoneSource; + + // Does this control expose an interface for its own HotZones? + if (ag != null) + ag.AddHotZones(redock, collection); + } + + // Check for situations that need extra attention... + // + // (1) Do not allow a WindowContent from a ZoneSequence to be redocked into the + // same ZoneSequence. As removing it will cause the Zone to be destroyed and + // so it cannot be added back again. Is not logical anyway. + // + // (2) If the source is in this ZoneSequence we might need to adjust the insertion + // index because the item being removed will reduce the count for when the insert + // takes place. + + bool indexAdjustTest = false; + WindowContent redockWC = redocker.WindowContent; + + if (_windows.Count == 1) + { + if (redockWC != null) + if (redockWC == _windows[0]) + if ((redocker.Content == null) || (redockWC.Contents.Count == 1)) + return; + } + else + { + if (_windows.Contains(redockWC)) + { + if ((redocker.Content == null) || (redockWC.Contents.Count == 1)) + indexAdjustTest = true; + } + } + + // Find the Zone client area in screen coordinates + Rectangle zoneArea = this.RectangleToScreen(this.ClientRectangle); + + int length; + + // Give a rough idea of the new window size + if (_direction == Direction.Vertical) + length = zoneArea.Height / (_windows.Count + 1); + else + length = zoneArea.Width / (_windows.Count + 1); + + AddHotZoneWithIndex(collection, zoneArea, length, 0); + + int addative = 0; + int count = _windows.Count; + + for (int index = 1; index < count; index++) + { + // Grab the Window for this index + WindowContent wc = _windows[index] as WindowContent; + + if (indexAdjustTest) + { + if (wc == redockWC) + --addative; + } + + AddHotZoneWithIndex(collection, + wc.RectangleToScreen(wc.ClientRectangle), + length, + index + addative); + } + + if (_windows.Count > 0) + { + // Find hot area and new size for last docking position + Rectangle lastArea = zoneArea; + Rectangle lastSize = zoneArea; + + if (_direction == Direction.Vertical) + { + lastArea.Y = lastArea.Bottom - _hotVectorBeforeControl; + lastArea.Height = _hotVectorBeforeControl; + lastSize.Y = lastSize.Bottom - length; + lastSize.Height = length; + } + else + { + lastArea.X = lastArea.Right - _hotVectorBeforeControl; + lastArea.Width = _hotVectorBeforeControl; + lastSize.X = lastSize.Right - length; + lastSize.Width = length; + } + + collection.Add(new HotZoneSequence(lastArea, lastSize, this, _windows.Count + addative)); + } + } + + public void ModifyWindowSpace(Window w, Decimal newSpace) + { + // Double check this Window is a member of the collection + if (_windows.Contains(w)) + { + // Cannot reallocate space if it is the only element + if (_windows.Count > 1) + { + int otherWindows = _windows.Count - 1; + + // Limit the resize allowed + if (newSpace > 100m) + newSpace = 100m; + + if (newSpace <= 0m) + newSpace = 0m; + + if (newSpace != w.ZoneArea) + { + // How much needs to be reallocated to other windows + Decimal diff = w.ZoneArea - newSpace; + + // Reducing the amount of space? + if (diff > 0m) + { + // How much to give each of the other windows + Decimal extra = diff / otherWindows; + + // Looping counters + Decimal allocated = 0m; + int found = 0; + + foreach (Window target in _windows) + { + // We only process the other windows + if (target != w) + { + // Allocate it extra space + target.ZoneArea += extra; + + // Keep count of total extra allocated + allocated += extra; + + // Count number of others processed + found++; + + // The last window to be allocated needs to also be given any rouding + // errors that occur from previous division, to ensure that the total + // space it always exactly equal to 100. + if (found == otherWindows) + target.ZoneArea += (diff - allocated); + } + } + } + else + { + // Easier to work with positive than negative numbers + diff = -diff; + + while (diff > 0m) + { + // How much to grab from each of the other windows + Decimal extra = diff / otherWindows; + + foreach (Window target in _windows) + { + // We only process the other windows + if (target != w) + { + if (target.ZoneArea > 0m) + { + if (target.ZoneArea < extra) + { + // Keep count of total left to grab + diff -= target.ZoneArea; + + // Window no longer has any ZoneArea + target.ZoneArea = 0m; + } + else + { + // Allocate it extra space + target.ZoneArea -= extra; + + // Keep count of total left to grab + diff -= extra; + } + } + } + } + } + } + + w.ZoneArea = newSpace; + } + } + } + + // Recalculate the size and position of each Window and resize bar + RepositionControls(); + } + + protected void AddHotZoneWithIndex(HotZoneCollection collection, Rectangle zoneArea, int length, int index) + { + // Find hot area and new size for first docking position + Rectangle hotArea = zoneArea; + Rectangle newSize = zoneArea; + + if (_direction == Direction.Vertical) + { + hotArea.Height = _hotVectorBeforeControl; + newSize.Height = length; + } + else + { + hotArea.Width = _hotVectorBeforeControl; + newSize.Width = length; + } + + collection.Add(new HotZoneSequence(hotArea, newSize, this, index)); + } + + protected override void OnWindowsClearing() + { + base.OnWindowsClearing(); + + // Make sure no Window is recorded as maximized + _maximizedWindow = null; + + // Remove all child controls + Controls.Clear(); + + if (!this.AutoDispose) + { + // Add back the Zone resize bar + Controls.Add(_resizeBar); + + Invalidate(); + } + } + + protected override void OnWindowInserted(int index, object value) + { + base.OnWindowInserted(index, value); + + Window w = value as Window; + + // Is this the first Window entry? + if (_windows.Count == 1) + { + // Use size of the Window to determine our new size + Size wSize = w.Size; + + // Adjust to account for the ResizeBar + switch (this.Dock) + { + case DockStyle.Left: + case DockStyle.Right: + wSize.Width += _resizeBar.Width; + break; + + case DockStyle.Top: + case DockStyle.Bottom: + wSize.Height += _resizeBar.Height; + break; + } + + this.Size = wSize; + + // Add the Window to the appearance + Controls.Add(w); + + // Reposition to the start of the collection + Controls.SetChildIndex(w, 0); + } + else + { + ResizeBar bar = new ResizeBar(_direction, this); + + // Add the bar and Window + Controls.Add(bar); + Controls.Add(w); + + // Adding at start of collection? + if (index == 0) + { + // Reposition the bar and Window to start of collection + Controls.SetChildIndex(bar, 0); + Controls.SetChildIndex(w, 0); + } + else + { + int pos = index * 2 - 1; + + // Reposition the bar and Window to correct relative ordering + Controls.SetChildIndex(bar, pos++); + Controls.SetChildIndex(w, pos); + } + } + + // Allocate space for the new Window from other Windows + AllocateWindowSpace(w); + + // Recalculate the size and position of each Window and resize bar + RepositionControls(); + + // Inform all interested parties of possible change in maximized state + OnRefreshMaximize(EventArgs.Empty); + } + + protected override void OnWindowRemoving(int index, object value) + { + base.OnWindowRemoving(index, value); + + Window w = value as Window; + + // If the Window being removed the maximized one? + if (_maximizedWindow == w) + _maximizedWindow = null; + + // Is this the only Window entry? + if (_windows.Count == 1) + { + // Remove Window from appearance + + // Use helper method to circumvent form Close bug + ControlHelper.RemoveAt(this.Controls, 0); + } + else + { + int pos = 0; + + // Calculate position of Window to remove + if (index != 0) + pos = index * 2 - 1; + + // Remove Window and bar + + // Use helper method to circumvent form Close bug + ControlHelper.RemoveAt(this.Controls, pos); + ControlHelper.RemoveAt(this.Controls, pos); + } + + // Redistribute space taken up by Window to other windows + RemoveWindowSpace(w); + } + + protected override void OnWindowRemoved(int index, object value) + { + base.OnWindowRemoved(index, value); + + // Recalculate the size and position of each Window and resize bar + RepositionControls(); + + // Inform all interested parties of possible change in maximized state + OnRefreshMaximize(EventArgs.Empty); + } + + protected void AllocateWindowSpace(Window w) + { + // Is this the only Window? + if (_windows.Count == 1) + { + // Give it all the space + w.ZoneArea = 100m; + } + else + { + // Calculate how much space it should have + Decimal newSpace = 100m / _windows.Count; + + // How much space should we steal from each of the others + Decimal reduceSpace = newSpace / (_windows.Count - 1); + + // Actual space acquired + Decimal allocatedSpace = 0m; + + foreach (Window entry in _windows) + { + if (entry != w) + { + // How much space the entry currently has + Decimal currentSpace = entry.ZoneArea; + + // How much space to steal from it + Decimal xferSpace = reduceSpace; + + // Does it have at least the requested amount of space? + if (currentSpace < xferSpace) + xferSpace = currentSpace; + + // Transfer the space across + currentSpace -= xferSpace; + + // Round the sensible number of decimal places + currentSpace = Decimal.Round(currentSpace, _spacePrecision); + + // Update window with new space allocation + entry.ZoneArea = currentSpace; + + allocatedSpace += currentSpace; + } + } + + // Assign allocated space to new window + w.ZoneArea = 100m - allocatedSpace; + } + } + + protected void ModifyWindowSpace(Window w, int vector) + { + // Remove any maximized state + if (_maximizedWindow != null) + { + // Make the maximized Window have all the space + foreach (Window entry in _windows) + { + if (entry == _maximizedWindow) + entry.ZoneArea = 100m; + else + entry.ZoneArea = 0m; + } + + // Remove maximized state + _maximizedWindow = null; + + // Inform all interested parties of change + OnRefreshMaximize(EventArgs.Empty); + } + + Rectangle clientRect = this.ClientRectangle; + + RepositionZoneBar(ref clientRect); + + // Space available for allocation + int space; + + // New pixel length of the modified Window + 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 += w.Height; + newLength -= w.MinimalSize.Height; + } + else + { + space = clientRect.Width; + + // New pixel size is requested change plus original + // width minus the minimal size that is always added + newLength += w.Width; + newLength -= w.MinimalSize.Width; + } + + int barSpace = 0; + + // Create temporary array of working values + Position[] positions = new Position[Controls.Count - 1]; + + // 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 * 100; + + // What is the change in area + Decimal reallocate = newPercent - w.ZoneArea; + + // Find the Window after this one + Window nextWindow = _windows[_windows.IndexOf(w) + 1]; + + if ((nextWindow.ZoneArea - reallocate) < 0m) + reallocate = nextWindow.ZoneArea; + + // Modify the Window in question + w.ZoneArea += reallocate; + + // Reverse modify the Window afterwards + nextWindow.ZoneArea -= reallocate; + + // Update the visual appearance + RepositionControls(); + } + + protected Decimal ReduceAreaEvenly(int thisIndex, Decimal windowAllocation) + { + Decimal removed = 0m; + + // Process each Window after this one in the collection + for (int index = thisIndex + 1; index < _windows.Count; index++) + { + Decimal zoneArea = _windows[index].ZoneArea; + + if (zoneArea > 0m) + { + if (zoneArea >= windowAllocation) + { + // Reduce the area available for this Window + _windows[index].ZoneArea -= windowAllocation; + + // Keep total of all area removed + removed += windowAllocation; + } + else + { + // Remove all the area from this Window + _windows[index].ZoneArea = 0m; + + // Keep total of all area removed + removed += zoneArea; + } + } + } + + return removed; + } + + protected void RemoveWindowSpace(Window w) + { + // Is there only a single Window left? + if (_windows.Count == 1) + { + // Give it all the space + _windows[0].ZoneArea = 100m; + } + else + { + // Is there any space to reallocate? + if (w.ZoneArea > 0) + { + // Total up all the values + Decimal totalAllocated = 0m; + + // How much space should we add to each of the others + Decimal freedSpace = w.ZoneArea / (_windows.Count - 1); + + foreach (Window entry in _windows) + { + if (entry != w) + { + // We only retain a sensible level of precision + Decimal newSpace = Decimal.Round(entry.ZoneArea + freedSpace, _spacePrecision); + + // Assign back new space + entry.ZoneArea = newSpace; + + // Total up all space so far + totalAllocated += newSpace; + } + } + + // Look for minor errors due not all fractions can be accurately represented in binary! + if (totalAllocated > 100m) + { + Decimal correction = totalAllocated - 100m; + + // Remove from first entry + foreach (Window entry in _windows) + { + if (entry != w) + { + // Apply correction to this window + entry.ZoneArea = totalAllocated - 100m; + break; + } + } + } + else if (totalAllocated < 100m) + { + Decimal correction = 100m - totalAllocated; + + // Remove from first entry + foreach (Window entry in _windows) + { + if (entry != w) + { + // Apply correction to this window + entry.ZoneArea += 100m - totalAllocated; + break; + } + } + } + + // Window no longer has any space + w.ZoneArea = 0m; + } + } + } + + protected void RepositionControls() + { + // Caller has requested that this call be ignored + if (_suppressReposition) + { + _suppressReposition = false; + return; + } + + Rectangle clientRect = this.ClientRectangle; + + RepositionZoneBar(ref clientRect); + + if (_windows.Count > 0) + { + // Space available for allocation + int space; + + // Starting position of first control + int delta; + + if (_direction == Direction.Vertical) + { + space = clientRect.Height; + delta = clientRect.Top; + } + else + { + space = clientRect.Width; + delta = clientRect.Left; + } + + // Ensure this is not negative + if (space < 0) + space = 0; + + int barSpace = 0; + int allocation = space; + + // Create temporary array of working values + Position[] positions = new Position[Controls.Count - 1]; + + // 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); + + // If there any more space left + if (space > 0) + { + // Pass 2, allocate any space left over according to the request percent + // area that each Window would like to achieve. + AllocateRemainingSpace(ref positions, space); + } + + // Pass 3, reposition the controls according to allocated values. + RepositionControls(ref positions, clientRect, delta); + } + } + + protected void AllocateMandatorySizes(ref Position[] positions, ref int barSpace, ref int space) + { + // Process each control (except last which is the Zone level ResizeBar) + for (int index = 0; index < (Controls.Count - 1); index++) + { + ResizeBar bar = Controls[index] as ResizeBar; + + if (bar != null) + { + // Length needed is depends on direction + positions[index].length = bar.Length; + + // Add up how much space was allocated to ResizeBars + barSpace += positions[index].length; + } + else + { + Window w = Controls[index] as Window; + + if (w != null) + { + Size minimal = w.MinimalSize; + + // Length needed is depends on direction + if (_direction == Direction.Vertical) + positions[index].length = minimal.Height; + else + positions[index].length = minimal.Width; + } + } + + // Reduce available space by that just allocated + space -= positions[index].length; + } + } + + protected void AllocateRemainingSpace(ref Position[] positions, int windowSpace) + { + // Space allocated so far + int allocated = 0; + + // Process each control (except last which is the Zone level ResizeBar) + for (int index = 0; index < (Controls.Count - 1); index++) + { + Window w = Controls[index] as Window; + + // If no window is maximized then as long as the control is a window we enter the if statement, + // If a window is maximized then we only enter the if statement if this is the maximzied one + if ((w != null) && ((_maximizedWindow == null) || ((_maximizedWindow != null) && (_maximizedWindow == w)))) + { + // How much of remaining space does the Window request to have? + int extra; + + if (_maximizedWindow == null) + { + extra = (int)(windowSpace / 100m * w.ZoneArea); + + // Is this the last Window to be positioned? + if (index == (Controls.Count - 1)) + { + // Use up all the remaining space, this handles the case of + // the above vector calculation giving rounding errors so that + // the last element needs adusting to fill exactly all the + // available space + extra = windowSpace - allocated; + } + } + else + { + extra = windowSpace - allocated; + } + + // Add the extra space to any existing space it has + positions[index].length += extra; + + // Keep count of all allocated so far + allocated += extra; + } + } + } + + protected void RepositionControls(ref Position[] positions, Rectangle clientRect, int delta) + { + // Process each control (except last which is the Zone level ResizeBar) + for (int index = 0; index < (Controls.Count - 1); index++) + { + int newDelta = positions[index].length; + + ResizeBar bar = Controls[index] as ResizeBar; + + if (bar != null) + { + if (_direction == Direction.Vertical) + { + // Set new position + bar.Location = new Point(clientRect.X, delta); + bar.Width = clientRect.Width; + bar.Height = newDelta; + + // Move delta down to next position + delta += newDelta; + } + else + { + // Set new position + bar.Location = new Point(delta, clientRect.Y); + bar.Height = clientRect.Height; + bar.Width = newDelta; + + // Move delta across to next position + delta += newDelta; + } + } + else + { + Window w = Controls[index] as Window; + + if (w != null) + { + if (newDelta == 0) + w.Hide(); + else + { + // Set new position/size based on direction + if (_direction == Direction.Vertical) + { + w.Location = new Point(clientRect.X, delta); + w.Width = clientRect.Width; + w.Height = newDelta; + } + else + { + w.Location = new Point(delta, clientRect.Y); + w.Height = clientRect.Height; + w.Width = newDelta; + } + + if (!w.Visible) + w.Show(); + + // Move delta to next position + delta += newDelta; + } + } + } + } + } + + protected void RepositionZoneBar(ref Rectangle clientRect) + { + Rectangle barRect; + + int length = _resizeBar.Length; + + // We only want a resizeBar when actually docked against an edge + bool resizeBarPresent = ((this.Dock != DockStyle.Fill) && (this.Dock != DockStyle.None)); + + // Define the correct direction for the resize bar and new Zone position + switch (_state) + { + case State.DockLeft: + _resizeBar.Direction = Direction.Horizontal; + barRect = new Rectangle(this.Width - length, 0, length, this.Height); + + if (resizeBarPresent) + clientRect.Width -= length; + break; + + case State.DockTop: + _resizeBar.Direction = Direction.Vertical; + barRect = new Rectangle(0, this.Height - length, this.Width, length); + + if (resizeBarPresent) + clientRect.Height -= length; + break; + + case State.DockRight: + _resizeBar.Direction = Direction.Horizontal; + barRect = new Rectangle(0, 0, length, this.Height); + + if (resizeBarPresent) + { + clientRect.X += length; + clientRect.Width -= length; + } + break; + + case State.DockBottom: + _resizeBar.Direction = Direction.Vertical; + barRect = new Rectangle(0, 0, this.Width, length); + + if (resizeBarPresent) + { + clientRect.Y += length; + clientRect.Height -= length; + } + break; + + case State.Floating: + default: + _resizeBar.Direction = Direction.Horizontal; + barRect = new Rectangle(0, 0, 0, 0); + break; + } + + if (resizeBarPresent) + { + // Reposition the Zone level resize bar control + _resizeBar.Location = new Point(barRect.X, barRect.Y); + _resizeBar.Size = new Size(barRect.Width, barRect.Height); + + if (!_resizeBar.Visible) + _resizeBar.Show(); + } + else + { + if (_resizeBar.Visible) + _resizeBar.Hide(); + } + } + + protected override void OnResize(EventArgs e) + { + // Need to recalculate based on new window space + RepositionControls(); + + base.OnResize(e); + } + } +} \ No newline at end of file diff --git a/Labyrinth3/Crownwood.Magic/Forms/WizardDialog.cs b/Labyrinth3/Crownwood.Magic/Forms/WizardDialog.cs new file mode 100644 index 0000000..f9484dd --- /dev/null +++ b/Labyrinth3/Crownwood.Magic/Forms/WizardDialog.cs @@ -0,0 +1,306 @@ +// ***************************************************************************** +// +// (c) Crownwood Consulting Limited 2002-2003 +// All rights reserved. The software and associated documentation +// supplied hereunder are the proprietary information of Crownwood Consulting +// Limited, Crownwood, Bracknell, Berkshire, England and are supplied subject +// to licence terms. +// +// Magic Version 1.7.4.0 www.dotnetmagic.com +// ***************************************************************************** + +using Crownwood.Magic.Controls; +using System; +using System.ComponentModel; +using System.Windows.Forms; + +namespace Crownwood.Magic.Forms +{ + /// + /// Summary description for WizardDialog. + /// + public class WizardDialog : System.Windows.Forms.Form + { + public enum TitleModes + { + None, + WizardPageTitle, + WizardPageSubTitle, + WizardPageCaptionTitle, + Steps + } + + protected string _cachedTitle; + protected TitleModes _titleMode; + protected WizardControl wizardControl; + + /// + /// Required designer variable. + /// + private System.ComponentModel.Container components = null; + + public WizardDialog() + { + // + // Required for Windows Form Designer support + // + InitializeComponent(); + + // Initialize properties + ResetTitleMode(); + + // Hook into wizard page collection changes + wizardControl.WizardPages.Cleared += new Collections.CollectionClear(OnPagesCleared); + wizardControl.WizardPages.Inserted += new Collections.CollectionChange(OnPagesChanged); + wizardControl.WizardPages.Removed += new Collections.CollectionChange(OnPagesChanged); + } + + /// + /// Clean up any resources being used. + /// + protected override void Dispose(bool disposing) + { + if (disposing) + { + if (components != null) + { + components.Dispose(); + } + } + base.Dispose(disposing); + } + + #region Windows Form Designer generated code + + /// + /// Required method for Designer support - do not modify + /// the contents of this method with the code editor. + /// + private void InitializeComponent() + { + System.Resources.ResourceManager resources = new System.Resources.ResourceManager(typeof(WizardDialog)); + this.wizardControl = new Crownwood.Magic.Controls.WizardControl(); + this.SuspendLayout(); + // + // wizardControl + // + this.wizardControl.Dock = System.Windows.Forms.DockStyle.Fill; + this.wizardControl.Name = "wizardControl"; + this.wizardControl.Picture = ((System.Drawing.Bitmap)(resources.GetObject("wizardControl.Picture"))); + this.wizardControl.SelectedIndex = -1; + this.wizardControl.Size = new System.Drawing.Size(416, 285); + this.wizardControl.TabIndex = 0; + this.wizardControl.CancelClick += new System.EventHandler(this.OnCancelClick); + this.wizardControl.CloseClick += new System.EventHandler(this.OnCloseClick); + this.wizardControl.NextClick += new System.ComponentModel.CancelEventHandler(this.OnNextClick); + this.wizardControl.FinishClick += new System.EventHandler(this.OnFinishClick); + this.wizardControl.WizardPageEnter += new Crownwood.Magic.Controls.WizardControl.WizardPageHandler(this.OnWizardPageEnter); + this.wizardControl.BackClick += new System.ComponentModel.CancelEventHandler(this.OnBackClick); + this.wizardControl.HelpClick += new System.EventHandler(this.OnHelpClick); + this.wizardControl.WizardPageLeave += new Crownwood.Magic.Controls.WizardControl.WizardPageHandler(this.OnWizardPageLeave); + this.wizardControl.WizardCaptionTitleChanged += new System.EventHandler(this.OnWizardCaptionTitleChanged); + this.wizardControl.SelectionChanged += new System.EventHandler(this.OnSelectionChanged); + this.wizardControl.UpdateClick += new System.EventHandler(this.OnUpdateClick); + // + // WizardDialog + // + this.AutoScaleBaseSize = new System.Drawing.Size(5, 13); + this.ClientSize = new System.Drawing.Size(416, 285); + this.Controls.AddRange(new System.Windows.Forms.Control[] { + this.wizardControl}); + this.Name = "WizardDialog"; + this.Text = "Wizard Dialog"; + this.ResumeLayout(false); + } + + #endregion Windows Form Designer generated code + + public new string Text + { + get { return _cachedTitle; } + + set + { + // Store the provided value + _cachedTitle = value; + + // Apply the title mode extra to the end + ApplyTitleMode(); + } + } + + [Category("Wizard")] + [Description("Determine how the title is automatically defined")] + [DefaultValue(typeof(TitleModes), "WizardPageCaptionTitle")] + public TitleModes TitleMode + { + get { return _titleMode; } + + set + { + if (_titleMode != value) + { + _titleMode = value; + ApplyTitleMode(); + } + } + } + + public void ResetTitleMode() + { + TitleMode = TitleModes.WizardPageCaptionTitle; + } + + protected virtual void ApplyTitleMode() + { + string newTitle = _cachedTitle; + + // Calculate new title text + switch (_titleMode) + { + case TitleModes.None: + // Do nothing! + break; + + case TitleModes.Steps: + // Get the current page + int selectedPage = wizardControl.SelectedIndex; + int totalPages = wizardControl.WizardPages.Count; + + // Only need separator if some text is already present + if (newTitle.Length > 0) + newTitle += " - "; + + // Append the required text + newTitle += "Step " + (selectedPage + 1).ToString() + " of " + totalPages.ToString(); + break; + + case TitleModes.WizardPageTitle: + // Do we have a valid page currently selected? + if (wizardControl.SelectedIndex != -1) + { + // Get the page + WizardPage wp = wizardControl.WizardPages[wizardControl.SelectedIndex]; + + // Only need separator if some text is already present + if (newTitle.Length > 0) + newTitle += " - "; + + // Append page title to the title + newTitle += wp.Title; + } + break; + + case TitleModes.WizardPageSubTitle: + // Do we have a valid page currently selected? + if (wizardControl.SelectedIndex != -1) + { + // Get the page + WizardPage wp = wizardControl.WizardPages[wizardControl.SelectedIndex]; + + // Only need separator if some text is already present + if (newTitle.Length > 0) + newTitle += " - "; + + // Append page sub-title to the title + newTitle += wp.SubTitle; + } + break; + + case TitleModes.WizardPageCaptionTitle: + // Do we have a valid page currently selected? + if (wizardControl.SelectedIndex != -1) + { + // Get the page + WizardPage wp = wizardControl.WizardPages[wizardControl.SelectedIndex]; + + // Only need separator if some text is already present + if (newTitle.Length > 0) + newTitle += " - "; + + // Append page sub-title to the title + newTitle += wp.CaptionTitle; + } + break; + } + + // Use base class to update actual caption bar + base.Text = newTitle; + } + + protected virtual void OnPagesCleared() + { + // Update the caption bar to reflect change in selection + ApplyTitleMode(); + } + + protected virtual void OnPagesChanged(int index, object value) + { + // Update the caption bar to reflect change in selection + ApplyTitleMode(); + } + + protected virtual void OnCloseClick(object sender, EventArgs e) + { + // By default we close the Form + this.DialogResult = DialogResult.OK; + this.Close(); + } + + protected virtual void OnFinishClick(object sender, EventArgs e) + { + // By default we close the Form + this.DialogResult = DialogResult.OK; + this.Close(); + } + + protected virtual void OnCancelClick(object sender, EventArgs e) + { + // By default we close the Form + this.DialogResult = DialogResult.Cancel; + this.Close(); + } + + protected virtual void OnNextClick(object sender, CancelEventArgs e) + { + // By default we do nothing, let derived class override + } + + protected virtual void OnBackClick(object sender, CancelEventArgs e) + { + // By default we do nothing, let derived class override + } + + protected virtual void OnUpdateClick(object sender, EventArgs e) + { + // By default we do nothing, let derived class override + } + + protected virtual void OnHelpClick(object sender, EventArgs e) + { + // By default we do nothing, let derived class override + } + + protected virtual void OnSelectionChanged(object sender, EventArgs e) + { + // Update the caption bar to reflect change in selection + ApplyTitleMode(); + } + + protected virtual void OnWizardPageEnter(Controls.WizardPage wp, Controls.WizardControl wc) + { + // By default we do nothing, let derived class override + } + + protected virtual void OnWizardPageLeave(Controls.WizardPage wp, Controls.WizardControl wc) + { + // By default we do nothing, let derived class override + } + + protected virtual void OnWizardCaptionTitleChanged(object sender, EventArgs e) + { + // Update the caption bar to reflect change in selection + ApplyTitleMode(); + } + } +} \ No newline at end of file diff --git a/Labyrinth3/Crownwood.Magic/Forms/WizardDialog.resx b/Labyrinth3/Crownwood.Magic/Forms/WizardDialog.resx new file mode 100644 index 0000000..d304fb0 --- /dev/null +++ b/Labyrinth3/Crownwood.Magic/Forms/WizardDialog.resx @@ -0,0 +1,318 @@ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + text/microsoft-resx + + + 1.3 + + + System.Resources.ResXResourceReader, System.Windows.Forms, Version=1.0.3300.0, Culture=neutral, PublicKeyToken=b77a5c561934e089 + + + System.Resources.ResXResourceWriter, System.Windows.Forms, Version=1.0.3300.0, Culture=neutral, PublicKeyToken=b77a5c561934e089 + + + Family + + + True + + + + Qk02MAAAAAAAADYAAAAoAAAAQAAAAEAAAAABABgAAAAAAAAAAAATCwAAEwsAAAAAAAAAAAAAgICAgICA + gICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICA + gICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICA + gICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICA + gICAgICAgICA//////////////////////////////////////////////////////////////////// + //////////////////////////////////////////////////////////////////////////////// + //////////////////////////////////////////////////////////////////////////////// + ////////////////////gICAgICA//////////////////////////////////////////////////// + //////////////////////////////////////////////////////////////////////////////// + //////////////////////////////////////////////////////////////////////////////// + ////////////////////////////////////gICAgICA//////////////////////////////////// + //////////////////////////////////////////////////////////////////////////////// + //////////////////////////////////////////////////////////////////////////////// + ////////////////////////////////////////////////////gICAgICA//////////////////// + //////////////////////////////////////////////////////////////////////////////// + //////////////////////////////////////////////////////////////////////////////// + ////////////////////////////////////////////////////////////////////gICAgICA//// + //////////////////////////////////////////////////////////////////////////////// + /////////////////v7+/f39+/z8/P39//////////////////////////////////////////////// + //////////////////////////////////////////////////////////////////////////////// + ////gICAgICA//////////////////////////////////////////////////////////////////// + /////////v7+/////////////////////////v7+/f39/f39/v7+/v7+/v7+//////////////////// + //////////////////////////////////////////////////////////////////////////////// + ////////////////////gICAgICA//////////////////////////////////////////////////// + /////////////////////////v7+/v7+/f7+/f7+/v7+/v7+/v7+/////////v3+/f387+7w6+jqxMHC + v7y+zLnD1cTN5+Hk//////////////////////////////////////////////////////////////// + ////////////////////////////////////gICAgICA//////////////////////////////////// + /////////////////v7+/v7+/v7+/////////v7+/v7+/f7+/f7+/f7+/f79/f39/f39/v7+/v7+8fDx + 3dvcqp+mdGNrjmR6iWh5tXCWpGOFgFhti1x1mXKGpJGbyLO+283U7+zt//////////////////////// + ////////////////////////////////////////////////////gICAgICA//////////////////// + /////////////////////////////////v7+/v7+/v7+/v7+/v7+/v7+/f79/f7+/f7+/P79+/z89/f3 + 9fT25+TlurW4o5admIGOiFRvz3um44W1yXih8Ii/53W123es6oC72YGusnCSuGuUm15+eFZolmd/gXuN + lJeos7XE0M3S9PP0////////////////////////////////////////////////////gICAgICA//// + /////////////////////////////////////////////v7//f3+/f7+/P7+/P3+/f3+/f39/P38/P79 + +vv77+/w2dnaxMDClYySfmdznW+GqmuMu2uW332x7n+952612VSm4F6tyjGXyjGXzDWZ00ag0FKg3XGv + 6Hy32nyt5364qGGPj1yHeVmCTS9GQhc6VS5TdFB0yIHI+fD5//////////////////////////////// + ////gICAgICA////////////////////////////////////////////////+fn6+fj4/f39+/z8+vv7 + 9/f38fHx8/Pz4+Pjvbq8o5qelH+IgFxtnV9/z3ym2nqt4nCx5Gey3Vmr0D6dzjmbyjGXyjGXyTGWyTCW + yjGXyjGXxTOUuEONvTmOwj2Su0SOoUB7mk15rGOIvnGYuW6UpF2Eh0NxiCJ/zbjM/v7+//////////// + ////////////////////gICAgICA////////////////////////////////////////////v77TysTK + x8TGu7q7uLK2ta+yuLO0s6yujIKGf21zmH2CpH6HuXmU4IWy9pHE7n+84WKv1UiizDaZyjGXyjGXyjGX + yjGXyDGWxTCTvi6OvS2MwS6Qqip/giZifSxgWyVFZTFOhENnklJzjlRwgE5nfUpkmFt5smiOlFF5fVB3 + ////////////////////////////////////gICAgICA//////////////////////////////////// + ////////PDZkg1dxbkZcVz9Lf1xumHeCknZ7kXB3uIuU1qKs3J+w6Ja464K56HC131qs10qkzzucyjOX + yjGXyTGWyjGXxjGUxC+SwC6PsSuEgiNjZBxMdCNXgzZlfkdkkl11w32c2o+t1pOr2pav5Jq27J2975nA + 4Yi0xXSel1B8k3OL////////////////////////////////////gICAgICA//////////////////// + ////////////////////5uXoXE1jnU5+vWKWqWmHlGJ2mG55xJac6Kq59Z/B6oK35nSz3lyr0kKfzDSZ + yjKXyzOYyjGXyjGXyTGXxTGTvy6PxzGUuy2LmyVzbRxSURc9dzhcq2SIxoKd3Jmw9bHD+77I+7zI/LfJ + /LTK/LPK+K7H4pW2m1t+dTZkj1mGya3G////////////////////////////////////gICAgICA//// + ////////////////////////////////////7u7xsKq0ellujT5vz3yi1Zuqs4WPmG16oFl+uj2NxDuT + yzqZyzSZyjGWyTGWyjGXyjGXyTGWxjCUxjCUyDGVyDCVryqCeR1aaSBPbzJWt1+Q5Zq38rHB9LTCwJmj + 3aW2+qjI/aTK/aPK/aHK9JfEzX6lcDpdThNHm3mY4tfh//////////////////////////////////// + ////gICAgICA////////////////////////////////////////+/z98fHzy8rLhXmAe1NorXeL0JSm + tn2RdUVdSh85Zh5MgSFgmyZ0siuEvi6OyDGVxDCSvy6PtCuHrCqBqyqAhCFjZSJNfztiqmKF45S0+7rI + +7rJ8a3Cv5SnZYCPiIijwXykuHWb+pbJ+pbIwHCbWSlMTQRLyLTI9/T3//////////////////////// + ////////////////////gICAgICA/////////////////////////////////////////v7//v7+/f39 + 8O/wwLi8nIWQoXSIwHab4H+z3X+xsWSNkUxzhD1nhDNldCVYaR1OdCNYeyZehC5kejFdYzBMh1BqtHeO + 2ZWs97DE/brK/LDK+J/G0Yyxa4CUJLC4IL7EM46Zg3mU75DAynijVyhKWB9Y8+7z//////////////// + ////////////////////////////////////gICAgICA//////////////////////////////////// + /////////////////v7+9fT11tPVpJegc05oeC5fq0KEx1ybzGugwnabunqUsXaMsHeNsHWMpnGEpHOD + voaX46e17LG88rLB97LG+q7I/KLK/JnK+5fJ24q3e42mJcnRCubnOrjFrIap2IGueEZ1IQU9cER4//// + ////////////////////////////////////////////////////gICAgICA//////////////////// + /////////////////////////////////////////Pz8tra7WlhzFQ0pQBEyeyZdpT9+v2WU3Y+v86/A + 6qy64KOy3p+x4KCy76q986vC3JSvwH6Z2Iis9JXE/JfK/JfK/ZfK9pTGuYKoZpClRKCuVoKUuYKorGST + OiB/CACGFgBdlIGd////////////////////////////////////////////////////gICAgICA//// + /////////////////////////////////////////////////////v7+6enqXVxzCwlkDAF0PxBBhCBh + lSVtlSpvqjaAxUSVokV8mkl2plOAsVqJzmGg01yjt2GQwW2Z3IOw9pPF/JfK/JfK/JfK/JfK2IOvrnGV + 0IWxx4St1IKwdEFoJA+FFgaxDAOgNRNkxrjH//////////////////////////////////////////// + ////gICAgICA/////////////////////////////////////////////////////////v7+1NTXTUtv + AgJ0AAB/CAFWLAluVhRefR5rniZ5vC2Lty6JsSyDqix/v0eS7IC7+ZDG7ou+8Y3A+5bJ+pbJ+5bJ8Y/B + 0Xyp03+qvXGdtmuf34S12YOujFJ5OhxHPRSDWRzHHwi4HABEz8jR//////////////////////////// + ////////////////////gICAgICA//////////////////////////////////////////////////// + /////v7+5ubngH+UFRVhAAB3AAB+AgCBFgV0PBF+RxNeSxNKZRphgCFpkChwqESH13yu642+44a244e3 + 24Cw032r1n6ulleIZzWJVi9xRyh2QR6EUShcPSNMIhGXMg+iThmwVBrwDQPZGwA59fT2//////////// + ////////////////////////////////////gICAgICA//////////////////////////////////// + /////////////////v7+/v7++vr6xsbHWVhoCgpLAAB7AAB7DgSTQBTIQxW7JAu6OxPBORCRMQ94RRx0 + TydbRiROUipdZjdrdj5/YzNzSCVUUSKCWR+2GgdwEASRPBPMShioDgVtBgKsHAjEHgmgEgSuEwGSVCVc + ////////////////////////////////////////////////////gICAgICA//////////////////// + /////////////////////////////////v7+/v7+/v7+/Pz80dHRTEhZDghABABABABtDgOQCQKACwOh + HQi5EASbDwSqQRTKQxWfTBitSxi5NRGSPxScNxCtFgZ2JQuCMA6dDgNzCAKFGgetGAa2BQGCAABkAgBr + BgBOFQA2b1R75+Do////////////////////////////////////////////////////gICAgICA//// + /////////////////////////////////////////////v7+/v7+/v7+/v7+/v7+7e3tTTlHhiJodRxg + RxFiIQhpDQNQAQBsBQGBAgBpCAKJKQypJAqFHAiZHwmuGgiYKg2qIAm0BwFmBAFoBwJ0AgBgAABqAACc + AACcAABtAQBuBgFiFwNHJwJAlYKb//////////////////////////////////////////////////// + ////gICAgICA/////////////////////////////////////////////////////v7+/v7+/v7++/v7 + 2tXZbUFetyyHvi2MoSh3ZyJYVRtLQA80Pw9IOA5JIghTGwZmEANACQFCCQJjCwNUCwNYBgF0BAFLAQBe + AgB7AQBQAABmAABpAAA+AQBgAgCSEQSLORKfRBaxKA+iVzV61MfU//////////////////////////// + ////////////////////gICAgICA//////////////////////////////////////////////////// + /////v7+/v7+/f3909HTglZzsiuExzCVqTONY0aLVlKTbEmEd0F6nTZ4iitoiClnmCtyhiRochxobB1i + XhlPQxBBWxdHUBNMJQpYHgc4HQZeCwJUAAAvBgA6AQBXDwRmRxeuZCDLNxDZKwFS2tLc//////////// + ////////////////////////////////////gICAgICA//////////////////////////////////// + /////////////////////////////f792NjYjGh/myh1tS6Lc0OPJHO8CZjnLYfDjnSk4nO05mu04mKv + 3Vmr01KjzEycz02f1Eyi0Uaf1EqizFieqFOMiThueiFaSBFEBABkAwBrBAApBAAvDgJrEQWYFQLGOARR + ////////////////////////////////////////////////////gICAgICA//////////////////// + /////////////////////////////////////////v7+/f397u3uhm9/lC1ysy2JbEeRGHzLAZX0E5Pb + dISu3oy6+5bJ+5fK/JfK+JDF84XB8YC/8oPA9orD+JDF9Y7D8Im/43Czy0KZhCBrFwNPBAB0DwNTGAIt + FwA0DABoHQB7cDB5////////////////////////////////////////////////////gICAgICA//// + /////////////////////////////////////////////////////////v7+/f39/Pz9mJKXiTFsvi6N + rDGJQlSdF3O9LIO3a3aW0oiz+ZXI/ZfK/ZfK/ZfK/ZfK+pXI+JTG+5bJ2oaylWyLs3me6IC5y0+cZhlQ + DQJECgKLKgycPg56OgRMRABCSgBPllyX//////////////////////////////////////////////// + ////gICAgICA/////////////////////////////////////////////////////////v7+/v79/f39 + /Pz90M3QYS1PvC6OxTCVazyEZkGEsFCby4Cw7ZDA+pbJ/ZfK/ZfK/ZfK/JfK1YWxuoSq2466sn+kSZSk + aX+U0oOxrEyFQhk2CAIyBgGDOBLGXR3KPg5tRgtKpn2m6d3p//////////////////////////////// + ////////////////////gICAgICA//////////////////////////////////////////////////// + /////v7+/v7+/f7+/P394eDhe15xoip5xjCVri2DsC6GwEyVsXCXxIat4Yq4/JbJ/ZfK/ZfK/JfKtHug + MXuGRoGPSXmIHtDWOo2ZxYSseEJhcFtsLCZfBgSQIgrLWBq6YTZ4y8HM+fb5//////////////////// + ////////////////////////////////////gICAgICA//////////////////////////////////// + /////////////////////v7+/v7+/v7+/v7+7e3uoY+chC5nxTKUwjGSmT2JWnaWVKCyboeftnmg+JXH + /JfK/ZfK+ZXIzY+4RZyqDt7hEuvwH93jQIKPtnecRjM9w7/ERkNhAgJoGxSDPQle8e3z//////////// + ////////////////////////////////////////////////////gICAgICA//////////////////// + /////////////////////////////////////v7+/v7+/v7+/v7++fn5ta2ygkVttS+IsDGMW2GaHai/ + R62+jIyp0Iey+JXG/JfK/ZfK/JbK7pLDtImuY42hOZKdT4iZhXCMkmR+dG9y7Oztq6uwfHyTkYyhlnKX + ////////////////////////////////////////////////////////////////////gICAgICA//// + /////////////////////////////////////////////////////v7+/v7+/v7+/v7+/P381tTWhF12 + pC98ny+COHWuELnRZp210Yy3+pfJ6Yy7t2+Vwnmh0Iax1IWx7o/A8o/C2Yq3yoWwsG6Sjm9/uba5/P39 + 8fLz5ufo9fX2//////////////////////////////////////////////////////////////////// + ////gICAgICA/////////////////////////////////////////v7//v7//////////v7+/v7+/v7+ + /v7+/f799PP0h3eDlzB1qC2CPmedDcPWQ56vt4Sp9JPE34u4dI+nWImcWo2gi3qW3Im2/JfK+ZbJ6Iu6 + m2WBqZyj6uvr/P39+/z9+/z9/f39//////////////////////////////////////////////////// + ////////////////////gICAgICA/////////////////////////////////////v7//Pz///////// + /////////////v7+/f39/P38+vr7r6uvbyZYwi6QkDiGTnaYSoWWn3CQ7I29zYqzQam2FtHXEcTJdoOc + 5ZC+/JbK/JfKx3SgXz9SzcnM/////////P39+vr6/P39//////////////////////////////////// + ////////////////////////////////////gICAgICA//////////////////////////////////// + /v7//v7//////////////////////v7+/f39/f39+fn50MvOaj5ctyyIxDGUr0GRrWyfz4Cq3om2cHqR + FMrOAvf5BOvsYZCk6pHA+5bJ+5bIiEtwk4mQ8O/w/////////v7+/Pz9/f3+//////////////////// + ////////////////////////////////////////////////////gICAgICA//////////////////// + /////////////////////////////////////////////v7+/f39/f39+/z819XWhmN6lyVyyDGWyzaZ + 2Vao7oS9yoWuVn2OHLG2A+bnFcjNS52sw4Sp+ZvG3YSzcEBl//////////////////////////////// + ////////////////////////////////////////////////////////////////////gICAgICA//// + /////////////////////////////////////////////////////////////f79/f39/f39+vr61NHT + g2d6iiZpxzCUyjKX0T+d42Wx7onA0oq1a5iuKq+5YZaqj4Sfun+c7Zq+rGKNd1Zy//////////////// + //////////////////////////////////////////////////////////////////////////////// + ////gICAgICA/////////////////////////////////////////////////////////////////v7+ + /f39/f396+vrmZGXXTtSbiFTmCdxsyyGxjKT0kOf6XC38Y/Dm3+ed36WwYmx85fE9qPF1Iqrbz1diXuI + //////////////////////////////////////////////////////////////////////////////// + ////////////////////gICAgICA//////////////////////////////////////////////////// + /////////////v7+/f39/f395ubmUEVNeiFdqTiCslKMvliT1Fmj10+l4mGu9YnC4Yy61om175PD/KXK + 9KTCn2mBfmp3x8TH//////////////////////////////////////////////////////////////// + ////////////////////////////////////gICAgICA//////////////////////////////////// + ///////////////////////+/v7+/f3+/v7+/Pz87OzsZFlgfB5dyjWX3WKt6Ii485nA8Y2+74C9+pHH + +JXH+ZbI+53J/LTK4ZS1XkJQt7K28vLy//////////////////////////////////////////////// + ////////////////////////////////////////////////////gICAgICA//////////////////// + /////////////////////////////////////v7+/f3+/f39/f3+/f396+rrkIWNThg7sSuF0ECe5m2z + 9p7D/LTJ/KnK/JrJ/JfK/JjK+6vJ9rTFs3GPTktM8vLy/v7+//////////////////////////////// + ////////////////////////////////////////////////////////////////////gICAgICA//// + /////////////////////////////////////////////////////v7+/f3+/f39/f39/Pv729jaknmJ + WR1Egh9ivy+O0kOf5XCy+KfF/b3K/bTK/aDK/KTK+LLG05GqgF9vraqs/Pz8/f39//////////////// + //////////////////////////////////////////////////////////////////////////////// + ////gICAgICA/////////////////////////////////////////////////////////v7+/f39/Pz8 + +vr63drcooualEd5pSt7oit6tjeKz0Gd3lyr9IvB/azK/LfK/LDK/LDJ56O5pXGIi4CF6enq/P39/f39 + /v7+//////////////////////////////////////////////////////////////////////////// + ////////////////////gICAgICA//////////////////////////////////////////////////// + //7+/v7+/Pz79/X2xL7CkXCGjztztDCIyjWY0kOf4muw6nK37nu7+I7F/ZjK/KLK/bTK9a7Dun6WlXmH + w8LD+vr7/P39/f39/f79/v7+/v7+//////////////////////////////////////////////////// + ////////////////////////////////////gICAgICA//////////////////////////////////// + /////////////v7+/f39+fn55uPkpqCjdUBjnDB5vTGO0EKe3Vmq73u8+JDF+pLH+5TJ/JfJ/ZnK/a/K + /LnK1I6qiWV2u7K37+/v/Pz8/f39/f7+/v7+/Pz8/f39//////////////////////////////////// + ////////////////////////////////////////////////////gICAgICA/////////////f39//// + /////////////v7+/v7+/v7+/////v7+8vLyxsPFh25+biRVsC+FzUKc3lus6nS4+JDG+5bJ/JfK/ZfK + /ZfK/ZrK/avK/cDK66K7hldtlIuP7Orq/Pz8/f39/f39/v7+/////v7+/f3+/v7+//////////////// + ////////////////////////////////////////////////////////////////////gICAgICA//// + /////////////////////////////v7+/f39/f39/v7+8vHxurW4eFlufSZgvDKM106k63W59ovD+5XI + /ZfK/JfK/ZfK/ZjK/Z/K/K3K+r3I56a5m2d+emty2dnZ/f39/f39/f39/v7+/////v7+/v7+/f3+/v7+ + +/v7/v7+//////////////////////////////////////////////////////////////////////// + ////gICAgICA/////////////////////////////////f39/f39/f39+vr6w77BgF10hShmuy+N1Uuj + 7Ha5+ZHH/JfK/ZfK/JfK/ZfK/Z3K/afK/LPJ97rG4qO0n22Cfm11xsPE+fn5/f39/v39/f3+/v7+//// + /v7+/f39/P39/P39+/v7//////////////////////////////////////////////////////////// + ////////////////////gICAgICA/////////////////////////////////v7+/v7+/f393NvbfWl2 + izBsuCyJ0D2d52y0947E/JfK/ZzK/Z/K/KHK/KzK/bfK+7zI7rO+zJWkjmZ1iXqBxsPE9fX1/f39/f39 + /f39/v7+/////////v7+/f39/P39+/z9+vr9//////////////////////////////////////////// + ////////////////////////////////////gICAgICA/////////////////////////////////v7+ + /v7+/v7+pKKjYCpNtCyGxzCV21Ko9IfB+5fI/aXK/bDK/LjJ+8DJ/MXK9rzE26OvsYGRg2d0mpKW2NbX + 9fT1/v7+/f39/f39/f39/v7+/////////////////f39/f39/f3+//////////////////////////// + ////////////////////////////////////////////////////gICAgICA//////////////////// + /////////////v7+/v7+8/PznJaaXR5ItCyGwjCS2Vin+pPH+pfH9KLD6Ku546+15bK3yJagoHeCnnyI + l4aNycPG9PPz+fn5/f39/v3+/v7+/f39/f39/v7+//7+//7+/////////v7+/v7+//////////////// + ////////////////////////////////////////////////////////////////////gICAgICA//// + /////////////////////////////v7+/f3++/v71M/SiWt+hz5vmzh6oEN9oF+Ak1t2kWB2lm19iWhz + YU1Ug3V6tKquxb/C7Orr/f39/Pz8/f39/f39/v3+/v7+/f7+/f39/v7+/v7+/v7+/v7+/v7+//////// + //////////////////////////////////////////////////////////////////////////////// + ////gICAgICA////////////////////////////////////+vr/+fn+9fT208/Sp56kj4SMhHyBkIeM + npOYmJCUlJCSraus2tjZ5+bn8PDw+vr6/P38/f38/f39/f39/f39/v7+/v7+/////v7+/v7+/v7+/v7+ + /v7+/v7+/v7+/v7+//////////////////////////////////////////////////////////////// + ////////////////////gICAgICA/////////////////////////////////////////v7//v7///// + /v3+/f39/f398fDx6enp7u7u9/n4/P79/f79/v7+/v7+/f39/Pz8/Pz8/Pz8/v7+/v7+//////////// + /////////////////////////v7+//////////////////////////////////////////////////// + ////////////////////////////////////gICAgICA//////////////////////////////////// + /////////////////////////////v7+/v7+/v7+/////////v7+/////////////////////v7+//// + //////////////////////////////////////////////////////////////////////////////// + ////////////////////////////////////////////////////gICAgICA//////////////////// + //////////////////////////////////////////////////////////////////////////////// + //////////////////////////////////////////////////////////////////////////////// + ////////////////////////////////////////////////////////////////////gICAgICA//// + //////////////////////////////////////////////////////////////////////////////// + //////////////////////////////////////////////////////////////////////////////// + //////////////////////////////////////////////////////////////////////////////// + ////gICAgICA//////////////////////////////////////////////////////////////////// + //////////////////////////////////////////////////////////////////////////////// + //////////////////////////////////////////////////////////////////////////////// + ////////////////////gICAgICA//////////////////////////////////////////////////// + //////////////////////////////////////////////////////////////////////////////// + //////////////////////////////////////////////////////////////////////////////// + ////////////////////////////////////gICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICA + gICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICA + gICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICA + gICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICA + + + + WizardDialog + + \ No newline at end of file diff --git a/Labyrinth3/Crownwood.Magic/Menus/DrawCommand.cs b/Labyrinth3/Crownwood.Magic/Menus/DrawCommand.cs new file mode 100644 index 0000000..86193f9 --- /dev/null +++ b/Labyrinth3/Crownwood.Magic/Menus/DrawCommand.cs @@ -0,0 +1,209 @@ +// ***************************************************************************** +// +// (c) Crownwood Consulting Limited 2002-2003 +// All rights reserved. The software and associated documentation +// supplied hereunder are the proprietary information of Crownwood Consulting +// Limited, Crownwood, Bracknell, Berkshire, England and are supplied subject +// to licence terms. +// +// Magic Version 1.7.4.0 www.dotnetmagic.com +// ***************************************************************************** + +using System.Drawing; + +namespace Crownwood.Magic.Menus +{ + internal class DrawCommand + { + // Instance fields + protected int _row; + + protected int _col; + protected char _mnemonic; + protected bool _enabled; + protected bool _subMenu; + protected bool _expansion; + protected bool _separator; + protected bool _vertSeparator; + protected bool _chevron; + protected bool _topBorder; + protected bool _bottomBorder; + protected bool _infrequent; + protected Rectangle _drawRect; + protected Rectangle _selectRect; + protected MenuCommand _command; + + public DrawCommand(Rectangle drawRect) + { + _row = -1; + _col = -1; + _mnemonic = '0'; + _enabled = true; + _subMenu = false; + _expansion = false; + _separator = false; + _vertSeparator = false; + _topBorder = false; + _bottomBorder = false; + _infrequent = false; + _chevron = true; + _drawRect = drawRect; + _selectRect = drawRect; + _command = null; + } + + public DrawCommand(Rectangle drawRect, bool expansion) + { + _row = -1; + _col = -1; + _mnemonic = '0'; + _enabled = true; + _subMenu = false; + _expansion = expansion; + _separator = !expansion; + _vertSeparator = !expansion; + _topBorder = false; + _bottomBorder = false; + _infrequent = false; + _chevron = false; + _drawRect = drawRect; + _selectRect = drawRect; + _command = null; + } + + public DrawCommand(MenuCommand command, Rectangle drawRect) + { + InternalConstruct(command, drawRect, drawRect, -1, -1); + } + + public DrawCommand(MenuCommand command, Rectangle drawRect, Rectangle selectRect) + { + InternalConstruct(command, drawRect, selectRect, -1, -1); + } + + public DrawCommand(MenuCommand command, Rectangle drawRect, int row, int col) + { + InternalConstruct(command, drawRect, drawRect, row, col); + } + + public void InternalConstruct(MenuCommand command, Rectangle drawRect, Rectangle selectRect, int row, int col) + { + _row = row; + _col = col; + _enabled = command.Enabled; + _expansion = false; + _vertSeparator = false; + _drawRect = drawRect; + _selectRect = selectRect; + _command = command; + _topBorder = false; + _bottomBorder = false; + _infrequent = command.Infrequent; + + _chevron = false; + + // Is this MenuCommand a separator? + _separator = (_command.Text == "-"); + + // Does this MenuCommand contain a submenu? + _subMenu = (_command.MenuCommands.Count > 0); + + // Find position of first mnemonic character + int position = -1; + + if (command.Text != null) + position = command.Text.IndexOf('&'); + + // Did we find a mnemonic indicator? + if (position != -1) + { + // Must be a character after the indicator + if (position < (command.Text.Length - 1)) + { + // Remember the character + _mnemonic = char.ToUpper(command.Text[position + 1]); + } + } + } + + public Rectangle DrawRect + { + get { return _drawRect; } + set { _drawRect = value; } + } + + public Rectangle SelectRect + { + get { return _selectRect; } + set { _selectRect = value; } + } + + public MenuCommand MenuCommand + { + get { return _command; } + } + + public bool Separator + { + get { return _separator; } + } + + public bool VerticalSeparator + { + get { return _vertSeparator; } + } + + public bool Expansion + { + get { return _expansion; } + } + + public bool SubMenu + { + get { return _subMenu; } + } + + public char Mnemonic + { + get { return _mnemonic; } + } + + public bool Enabled + { + get { return _enabled; } + } + + public int Row + { + get { return _row; } + } + + public int Col + { + get { return _col; } + } + + public bool Chevron + { + get { return _chevron; } + } + + public bool TopBorder + { + get { return _topBorder; } + set { _topBorder = value; } + } + + public bool BottomBorder + { + get { return _bottomBorder; } + set { _bottomBorder = value; } + } + + public bool Infrequent + { + get { return _infrequent; } + set { _infrequent = value; } + } + } +} \ No newline at end of file diff --git a/Labyrinth3/Crownwood.Magic/Menus/MenuCommand.cs b/Labyrinth3/Crownwood.Magic/Menus/MenuCommand.cs new file mode 100644 index 0000000..4db91b2 --- /dev/null +++ b/Labyrinth3/Crownwood.Magic/Menus/MenuCommand.cs @@ -0,0 +1,422 @@ +// ***************************************************************************** +// +// (c) Crownwood Consulting Limited 2002-2003 +// All rights reserved. The software and associated documentation +// supplied hereunder are the proprietary information of Crownwood Consulting +// Limited, Crownwood, Bracknell, Berkshire, England and are supplied subject +// to licence terms. +// +// Magic Version 1.7.4.0 www.dotnetmagic.com +// ***************************************************************************** + +using Crownwood.Magic.Collections; +using System; +using System.ComponentModel; +using System.Drawing; +using System.Windows.Forms; + +namespace Crownwood.Magic.Menus +{ + // Declare event signature + public delegate void CommandHandler(MenuCommand item); + + // Should animation be shown? + public enum Animate + { + No, + Yes, + System + } + + // How should animation be displayed? + public enum Animation + { + System = 0x00100000, + Blend = 0x00080000, + SlideCenter = 0x00040010, + SlideHorVerPositive = 0x00040005, + SlideHorVerNegative = 0x0004000A, + SlideHorPosVerNegative = 0x00040009, + SlideHorNegVerPositive = 0x00040006 + } + + // How show glyph fading be calculated? + public enum GlyphFading + { + None, + Default, + Grayscale, + DecreaseColorDepth, + Enlighten + } + + [ToolboxItem(false)] + [DefaultProperty("Text")] + [DefaultEvent("Click")] + public class MenuCommand : Component + { + // Enumeration of property change events + public enum Property + { + Text, + Enabled, + ImageIndex, + ImageList, + Image, + Shortcut, + Checked, + RadioCheck, + Break, + Infrequent, + Visible, + Description + } + + // Declare the property change event signature + public delegate void PropChangeHandler(MenuCommand item, Property prop); + + // Instance fields + protected bool _visible; + + protected bool _break; + protected string _text; + protected string _description; + protected bool _enabled; + protected bool _checked; + protected int _imageIndex; + protected bool _infrequent; + protected object _tag; + protected bool _radioCheck; + protected Shortcut _shortcut; + protected ImageList _imageList; + protected Image _image; + protected MenuCommandCollection _menuItems; + + // Exposed events + public event EventHandler Click; + + public event EventHandler Update; + + public event CommandHandler PopupStart; + + public event CommandHandler PopupEnd; + + public event PropChangeHandler PropertyChanged; + + public MenuCommand() + { + InternalConstruct("MenuItem", null, -1, Shortcut.None, null); + } + + public MenuCommand(string text) + { + InternalConstruct(text, null, -1, Shortcut.None, null); + } + + public MenuCommand(string text, EventHandler clickHandler) + { + InternalConstruct(text, null, -1, Shortcut.None, clickHandler); + } + + public MenuCommand(string text, Shortcut shortcut) + { + InternalConstruct(text, null, -1, shortcut, null); + } + + public MenuCommand(string text, Shortcut shortcut, EventHandler clickHandler) + { + InternalConstruct(text, null, -1, shortcut, clickHandler); + } + + public MenuCommand(string text, ImageList imageList, int imageIndex) + { + InternalConstruct(text, imageList, imageIndex, Shortcut.None, null); + } + + public MenuCommand(string text, ImageList imageList, int imageIndex, Shortcut shortcut) + { + InternalConstruct(text, imageList, imageIndex, shortcut, null); + } + + public MenuCommand(string text, ImageList imageList, int imageIndex, EventHandler clickHandler) + { + InternalConstruct(text, imageList, imageIndex, Shortcut.None, clickHandler); + } + + public MenuCommand(string text, + ImageList imageList, + int imageIndex, + Shortcut shortcut, + EventHandler clickHandler) + { + InternalConstruct(text, imageList, imageIndex, shortcut, clickHandler); + } + + protected void InternalConstruct(string text, + ImageList imageList, + int imageIndex, + Shortcut shortcut, + EventHandler clickHandler) + { + // Save parameters + _text = text; + _imageList = imageList; + _imageIndex = imageIndex; + _shortcut = shortcut; + _description = text; + + if (clickHandler != null) + Click += clickHandler; + + // Define defaults for others + _enabled = true; + _checked = false; + _radioCheck = false; + _break = false; + _tag = null; + _visible = true; + _infrequent = false; + _image = null; + + // Create the collection of embedded menu commands + _menuItems = new MenuCommandCollection(); + } + + [DesignerSerializationVisibility(DesignerSerializationVisibility.Content)] + public MenuCommandCollection MenuCommands + { + get { return _menuItems; } + } + + [DefaultValue("MenuItem")] + [Localizable(true)] + public string Text + { + get { return _text; } + + set + { + if (_text != value) + { + _text = value; + OnPropertyChanged(Property.Text); + } + } + } + + [DefaultValue(true)] + public bool Enabled + { + get { return _enabled; } + + set + { + if (_enabled != value) + { + _enabled = value; + OnPropertyChanged(Property.Enabled); + } + } + } + + [DefaultValue(-1)] + public int ImageIndex + { + get { return _imageIndex; } + + set + { + if (_imageIndex != value) + { + _imageIndex = value; + OnPropertyChanged(Property.ImageIndex); + } + } + } + + [DefaultValue(null)] + public ImageList ImageList + { + get { return _imageList; } + + set + { + if (_imageList != value) + { + _imageList = value; + OnPropertyChanged(Property.ImageList); + } + } + } + + [DefaultValue(null)] + public Image Image + { + get { return _image; } + + set + { + if (_image != value) + { + _image = value; + OnPropertyChanged(Property.Image); + } + } + } + + [DefaultValue(typeof(Shortcut), "None")] + public Shortcut Shortcut + { + get { return _shortcut; } + + set + { + if (_shortcut != value) + { + _shortcut = value; + OnPropertyChanged(Property.Shortcut); + } + } + } + + [DefaultValue(false)] + public bool Checked + { + get { return _checked; } + + set + { + if (_checked != value) + { + _checked = value; + OnPropertyChanged(Property.Checked); + } + } + } + + [DefaultValue(false)] + public bool RadioCheck + { + get { return _radioCheck; } + + set + { + if (_radioCheck != value) + { + _radioCheck = value; + OnPropertyChanged(Property.RadioCheck); + } + } + } + + [DefaultValue(false)] + public bool Break + { + get { return _break; } + + set + { + if (_break != value) + { + _break = value; + OnPropertyChanged(Property.Break); + } + } + } + + [DefaultValue(false)] + public bool Infrequent + { + get { return _infrequent; } + + set + { + if (_infrequent != value) + { + _infrequent = value; + OnPropertyChanged(Property.Infrequent); + } + } + } + + [DefaultValue(true)] + public bool Visible + { + get { return _visible; } + + set + { + if (_visible != value) + { + _visible = value; + OnPropertyChanged(Property.Visible); + } + } + } + + [Browsable(false)] + public bool IsParent + { + get { return (_menuItems.Count > 0); } + } + + [DefaultValue("")] + [Localizable(true)] + public string Description + { + get { return _description; } + set { _description = value; } + } + + [DefaultValue(null)] + public object Tag + { + get { return _tag; } + set { _tag = value; } + } + + public virtual void OnPropertyChanged(Property prop) + { + // Any attached event handlers? + if (PropertyChanged != null) + PropertyChanged(this, prop); + } + + public void PerformClick() + { + // Update command with correct state + OnUpdate(EventArgs.Empty); + + // Notify event handlers of click event + OnClick(EventArgs.Empty); + } + + public virtual void OnClick(EventArgs e) + { + // Any attached event handlers? + if (Click != null) + Click(this, e); + } + + public virtual void OnUpdate(EventArgs e) + { + // Any attached event handlers? + if (Update != null) + Update(this, e); + } + + public virtual void OnPopupStart() + { + // Any attached event handlers? + if (PopupStart != null) + PopupStart(this); + } + + public virtual void OnPopupEnd() + { + // Any attached event handlers? + if (PopupEnd != null) + PopupEnd(this); + } + } +} \ No newline at end of file diff --git a/Labyrinth3/Crownwood.Magic/Menus/MenuCommand.resx b/Labyrinth3/Crownwood.Magic/Menus/MenuCommand.resx new file mode 100644 index 0000000..7e32396 --- /dev/null +++ b/Labyrinth3/Crownwood.Magic/Menus/MenuCommand.resx @@ -0,0 +1,42 @@ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + text/microsoft-resx + + + 1.0.0.0 + + + System.Resources.ResXResourceReader, System.Windows.Forms, Version=1.0.3102.0, Culture=neutral, PublicKeyToken=b77a5c561934e089 + + + System.Resources.ResXResourceWriter, System.Windows.Forms, Version=1.0.3102.0, Culture=neutral, PublicKeyToken=b77a5c561934e089 + + diff --git a/Labyrinth3/Crownwood.Magic/Menus/MenuControl.bmp b/Labyrinth3/Crownwood.Magic/Menus/MenuControl.bmp new file mode 100644 index 0000000..2110269 Binary files /dev/null and b/Labyrinth3/Crownwood.Magic/Menus/MenuControl.bmp differ diff --git a/Labyrinth3/Crownwood.Magic/Menus/MenuControl.cs b/Labyrinth3/Crownwood.Magic/Menus/MenuControl.cs new file mode 100644 index 0000000..bce2aaf --- /dev/null +++ b/Labyrinth3/Crownwood.Magic/Menus/MenuControl.cs @@ -0,0 +1,2889 @@ +// ***************************************************************************** +// +// (c) Crownwood Consulting Limited 2002-2003 +// All rights reserved. The software and associated documentation +// supplied hereunder are the proprietary information of Crownwood Consulting +// Limited, Crownwood, Bracknell, Berkshire, England and are supplied subject +// to licence terms. +// +// Magic Version 1.7.4.0 www.dotnetmagic.com +// ***************************************************************************** + +using Crownwood.Magic.Collections; + +//using Crownwood.Magic.Win32; +using Crownwood.Magic.Common; +using Crownwood.Magic.Controls; +using Microsoft.Win32; +using System; +using System.Collections; +using System.ComponentModel; +using System.Drawing; +using System.Drawing.Drawing2D; +using System.Drawing.Text; +using System.Windows.Forms; + +namespace Crownwood.Magic.Menus +{ + [ToolboxBitmap(typeof(MenuControl))] + [DefaultProperty("MenuCommands")] + [DefaultEvent("PopupSelected")] + [Designer(typeof(Crownwood.Magic.Menus.MenuControlDesigner))] + public class MenuControl : ContainerControl, IMessageFilter + { + internal class MdiClientSubclass : NativeWindow + { + protected override void WndProc(ref Message m) + { + switch (m.Msg) + { + case (int)Win32.Msgs.WM_MDISETMENU: + case (int)Win32.Msgs.WM_MDIREFRESHMENU: + return; + } + + base.WndProc(ref m); + } + } + + // Class constants + protected const int _lengthGap = 3; + + protected const int _boxExpandUpper = 1; + protected const int _boxExpandSides = 2; + protected const int _shadowGap = 4; + protected const int _shadowYOffset = 4; + protected const int _separatorWidth = 15; + protected const int _subMenuBorderAdjust = 2; + protected const int _minIndex = 0; + protected const int _restoreIndex = 1; + protected const int _closeIndex = 2; + protected const int _chevronIndex = 3; + protected const int _buttonLength = 16; + protected const int _chevronLength = 12; + protected const int _pendantLength = 48; + protected const int _pendantOffset = 3; + + // Class constant is marked as 'readonly' to allow non constant initialization + protected readonly int WM_OPERATEMENU = (int)Win32.Msgs.WM_USER + 1; + + // Class fields + protected static ImageList _menuImages = null; + + protected static bool _supportsLayered = false; + + // Instance fields + protected int _rowWidth; + + protected int _rowHeight; + protected int _trackItem; + protected int _breadthGap; + protected int _animateTime; + protected IntPtr _oldFocus; + protected Pen _controlLPen; + protected bool _animateFirst; + protected bool _selected; + protected bool _multiLine; + protected bool _mouseOver; + protected bool _manualFocus; + protected bool _drawUpwards; + protected bool _defaultFont; + protected bool _defaultBackColor; + protected bool _defaultTextColor; + protected bool _defaultHighlightBackColor; + protected bool _defaultHighlightTextColor; + protected bool _defaultSelectedBackColor; + protected bool _defaultSelectedTextColor; + protected bool _defaultPlainSelectedTextColor; + protected bool _plainAsBlock; + protected bool _dismissTransfer; + protected bool _ignoreMouseMove; + protected bool _expandAllTogether; + protected bool _rememberExpansion; + protected bool _deselectReset; + protected bool _highlightInfrequent; + protected bool _exitLoop; + protected Color _textColor; + protected Color _highlightBackColor; + protected Color _useHighlightBackColor; + protected Color _highlightTextColor; + protected Color _highlightBackDark; + protected Color _highlightBackLight; + protected Color _selectedBackColor; + protected Color _selectedTextColor; + protected Color _plainSelectedTextColor; + protected Form _activeChild; + protected Form _mdiContainer; + protected GlyphFading _glyphFading; + protected VisualStyle _style; + protected Direction _direction; + protected PopupMenu _popupMenu; + protected ArrayList _drawCommands; + protected SolidBrush _controlLBrush; + protected SolidBrush _backBrush; + protected Animate _animate; + protected Animation _animateStyle; + internal MdiClientSubclass _clientSubclass; + protected MenuCommand _chevronStartCommand; + protected MenuCommandCollection _menuCommands; + + // Instance fields - pendant buttons + protected InertButton _minButton; + + protected InertButton _restoreButton; + protected InertButton _closeButton; + + // Instance fields - events + public event CommandHandler Selected; + + public event CommandHandler Deselected; + + static MenuControl() + { + // Create a strip of images by loading an embedded bitmap resource + _menuImages = ResourceHelper.LoadBitmapStrip(Type.GetType("Crownwood.Magic.Menus.MenuControl"), + "Crownwood.Magic.Resources.ImagesMenuControl.bmp", + new Size(_buttonLength, _buttonLength), + new Point(0, 0)); + + // We need to know if the OS supports layered windows + _supportsLayered = (OSFeature.Feature.GetVersionPresent(OSFeature.LayeredWindows) != null); + } + + public MenuControl() + { + // Set default values + _trackItem = -1; + _oldFocus = IntPtr.Zero; + _minButton = null; + _popupMenu = null; + _activeChild = null; + _closeButton = null; + _controlLPen = null; + _mdiContainer = null; + _restoreButton = null; + _controlLBrush = null; + _chevronStartCommand = null; + _animateFirst = true; + _exitLoop = false; + _selected = false; + _multiLine = false; + _mouseOver = false; + _defaultFont = true; + _manualFocus = false; + _drawUpwards = false; + _plainAsBlock = false; + _clientSubclass = null; + _ignoreMouseMove = false; + _deselectReset = true; + _expandAllTogether = true; + _rememberExpansion = true; + _highlightInfrequent = true; + _dismissTransfer = false; + _style = VisualStyle.IDE; + _direction = Direction.Horizontal; + _menuCommands = new MenuCommandCollection(); + _glyphFading = GlyphFading.Default; + this.Dock = DockStyle.Top; + this.Cursor = System.Windows.Forms.Cursors.Arrow; + + // Animation details + _animateTime = 100; + _animate = Animate.System; + _animateStyle = Animation.System; + + // Prevent flicker with double buffering and all painting inside WM_PAINT + SetStyle(ControlStyles.DoubleBuffer | + ControlStyles.AllPaintingInWmPaint | + ControlStyles.UserPaint, true); + + // Should not be allowed to select this control + SetStyle(ControlStyles.Selectable, false); + + // Hookup to collection events + _menuCommands.Cleared += new CollectionClear(OnCollectionCleared); + _menuCommands.Inserted += new CollectionChange(OnCollectionInserted); + _menuCommands.Removed += new CollectionChange(OnCollectionRemoved); + + // Need notification when the MenuFont is changed + Microsoft.Win32.SystemEvents.UserPreferenceChanged += + new UserPreferenceChangedEventHandler(OnPreferenceChanged); + + DefineColors(); + + // Set the starting Font + DefineFont(SystemInformation.MenuFont); + + // Do not allow tab key to select this control + this.TabStop = false; + + // Default to one line of items + this.Height = _rowHeight; + + // Add ourself to the application filtering list + Application.AddMessageFilter(this); + } + + protected override void Dispose(bool disposing) + { + if (disposing) + { + // Remove notifications + Microsoft.Win32.SystemEvents.UserPreferenceChanged -= + new UserPreferenceChangedEventHandler(OnPreferenceChanged); + } + base.Dispose(disposing); + } + + [Category("Behaviour")] + [DesignerSerializationVisibility(DesignerSerializationVisibility.Content)] + public MenuCommandCollection MenuCommands + { + get { return _menuCommands; } + } + + [Category("Appearance")] + public VisualStyle Style + { + get { return _style; } + + set + { + if (_style != value) + { + _style = value; + + Recalculate(); + Invalidate(); + } + } + } + + public override Font Font + { + get { return base.Font; } + + set + { + if (value != base.Font) + { + _defaultFont = (value == SystemInformation.MenuFont); + + DefineFont(value); + + Recalculate(); + Invalidate(); + } + } + } + + public override Color BackColor + { + get { return base.BackColor; } + + set + { + if (value != base.BackColor) + { + _defaultBackColor = (value == SystemColors.Control); + base.BackColor = value; + _backBrush = new SolidBrush(base.BackColor); + + Recalculate(); + Invalidate(); + } + } + } + + private bool ShouldSerializeBackColor() + { + return this.BackColor != SystemColors.Control; + } + + [Category("Appearance")] + public Color TextColor + { + get { return _textColor; } + + set + { + if (value != _textColor) + { + _textColor = value; + _defaultTextColor = (value == SystemColors.MenuText); + + Recalculate(); + Invalidate(); + } + } + } + + private bool ShouldSerializeTextColor() + { + return _textColor != SystemColors.MenuText; + } + + [Category("Appearance")] + public Color HighlightBackColor + { + get { return _highlightBackColor; } + + set + { + if (value != _highlightBackColor) + { + _defaultHighlightBackColor = (value == SystemColors.Highlight); + DefineHighlightBackColors(value); + + Recalculate(); + Invalidate(); + } + } + } + + private bool ShouldSerializeHighlightBackColor() + { + return _highlightBackColor != SystemColors.Highlight; + } + + [Category("Appearance")] + public Color HighlightTextColor + { + get { return _highlightTextColor; } + + set + { + if (value != _highlightTextColor) + { + _highlightTextColor = value; + _defaultHighlightTextColor = (value == SystemColors.MenuText); + + Recalculate(); + Invalidate(); + } + } + } + + private bool ShouldSerializeHighlightTextColor() + { + return _highlightTextColor != SystemColors.HighlightText; + } + + [Category("Appearance")] + public Color SelectedBackColor + { + get { return _selectedBackColor; } + + set + { + if (value != _selectedBackColor) + { + DefineSelectedBackColors(value); + _defaultSelectedBackColor = (value == SystemColors.Control); + + Recalculate(); + Invalidate(); + } + } + } + + private bool ShouldSerializeSelectedBackColor() + { + return _selectedBackColor != SystemColors.Control; + } + + [Category("Appearance")] + public Color SelectedTextColor + { + get { return _selectedTextColor; } + + set + { + if (value != _selectedTextColor) + { + _selectedTextColor = value; + _defaultSelectedTextColor = (value == SystemColors.MenuText); + + Recalculate(); + Invalidate(); + } + } + } + + private bool ShouldSerializeSelectedTextColor() + { + return _selectedTextColor != SystemColors.MenuText; + } + + [Category("Appearance")] + public Color PlainSelectedTextColor + { + get { return _plainSelectedTextColor; } + + set + { + if (value != _plainSelectedTextColor) + { + _plainSelectedTextColor = value; + _defaultPlainSelectedTextColor = (value == SystemColors.ActiveCaptionText); + + Recalculate(); + Invalidate(); + } + } + } + + private bool ShouldSerializePlainSelectedTextColor() + { + return _plainSelectedTextColor != SystemColors.ActiveCaptionText; + } + + [Category("Appearance")] + [DefaultValue(false)] + public bool PlainAsBlock + { + get { return _plainAsBlock; } + + set + { + if (_plainAsBlock != value) + { + _plainAsBlock = value; + + Recalculate(); + Invalidate(); + } + } + } + + [Category("Appearance")] + [DefaultValue(false)] + public bool MultiLine + { + get { return _multiLine; } + + set + { + if (_multiLine != value) + { + _multiLine = value; + + Recalculate(); + Invalidate(); + } + } + } + + [Category("Appearance")] + public Direction Direction + { + get { return _direction; } + + set + { + if (_direction != value) + { + _direction = value; + + Recalculate(); + Invalidate(); + } + } + } + + [Category("Behaviour")] + [DefaultValue(true)] + public bool RememberExpansion + { + get { return _rememberExpansion; } + set { _rememberExpansion = value; } + } + + [Category("Behaviour")] + [DefaultValue(true)] + public bool ExpandAllTogether + { + get { return _expandAllTogether; } + set { _expandAllTogether = value; } + } + + [Category("Behaviour")] + [DefaultValue(true)] + public bool DeselectReset + { + get { return _deselectReset; } + set { _deselectReset = value; } + } + + [Category("Behaviour")] + [DefaultValue(true)] + public bool HighlightInfrequent + { + get { return _highlightInfrequent; } + set { _highlightInfrequent = value; } + } + + public override DockStyle Dock + { + get { return base.Dock; } + + set + { + base.Dock = value; + + switch (value) + { + case DockStyle.None: + _direction = Direction.Horizontal; + break; + + case DockStyle.Top: + case DockStyle.Bottom: + this.Height = 0; + _direction = Direction.Horizontal; + break; + + case DockStyle.Left: + case DockStyle.Right: + this.Width = 0; + _direction = Direction.Vertical; + break; + } + + Recalculate(); + Invalidate(); + } + } + + [Category("Animate")] + [DefaultValue(typeof(Animate), "System")] + public Animate Animate + { + get { return _animate; } + set { _animate = value; } + } + + [Category("AnimateTime")] + public int AnimateTime + { + get { return _animateTime; } + set { _animateTime = value; } + } + + [Category("AnimateStyle")] + public Animation AnimateStyle + { + get { return _animateStyle; } + set { _animateStyle = value; } + } + + [Category("Appearance")] + [DefaultValue(GlyphFading.Default)] + public GlyphFading GlyphFading + { + get { return _glyphFading; } + set { _glyphFading = value; } + } + + [Category("Behaviour")] + [DefaultValue(null)] + public Form MdiContainer + { + get { return _mdiContainer; } + + set + { + if (_mdiContainer != value) + { + if (_mdiContainer != null) + { + // Unsubclass from MdiClient and then remove object reference + _clientSubclass.ReleaseHandle(); + _clientSubclass = null; + + // Remove registered events + _mdiContainer.MdiChildActivate -= new EventHandler(OnMdiChildActivate); + + RemovePendantButtons(); + } + + _mdiContainer = value; + + if (_mdiContainer != null) + { + CreatePendantButtons(); + + foreach (Control c in _mdiContainer.Controls) + { + MdiClient client = c as MdiClient; + + if (client != null) + { + // We need to subclass the MdiClient to prevent any attempt + // to change the menu for the container Form. This prevents + // the system from automatically adding the pendant. + _clientSubclass = new MdiClientSubclass(); + _clientSubclass.AssignHandle(client.Handle); + } + } + + // Need to be informed of the active child window + _mdiContainer.MdiChildActivate += new EventHandler(OnMdiChildActivate); + } + } + } + } + + protected void DefineColors() + { + // Define starting text colors + _defaultTextColor = true; + _defaultHighlightTextColor = true; + _defaultSelectedTextColor = true; + _defaultPlainSelectedTextColor = true; + _textColor = SystemColors.MenuText; + _highlightTextColor = SystemColors.MenuText; + _selectedTextColor = SystemColors.MenuText; + _plainSelectedTextColor = SystemColors.ActiveCaptionText; + + // Define starting back colors + _defaultBackColor = true; + _defaultHighlightBackColor = true; + _defaultSelectedBackColor = true; + base.BackColor = SystemColors.Control; + _backBrush = new SolidBrush(base.BackColor); + _highlightBackColor = SystemColors.Highlight; + DefineHighlightBackColors(SystemColors.Highlight); + DefineSelectedBackColors(SystemColors.Control); + } + + public void ResetColors() + { + this.BackColor = SystemColors.Control; + this.TextColor = SystemColors.MenuText; + this.HighlightBackColor = SystemColors.Highlight; + this.HighlightTextColor = SystemColors.MenuText; + this.SelectedBackColor = SystemColors.Control; + this.SelectedTextColor = SystemColors.MenuText; + } + + protected void DefineFont(Font newFont) + { + base.Font = newFont; + + _breadthGap = (this.Font.Height / 3) + 1; + + // Calculate the initial height/width of the control + _rowWidth = _rowHeight = this.Font.Height + _breadthGap * 2 + 1; + } + + protected void DefineSelectedBackColors(Color baseColor) + { + _selectedBackColor = baseColor; + Color lightColor = ColorHelper.CalculateColor(baseColor, Color.White, 200); + _controlLPen = new Pen(lightColor); + _controlLBrush = new SolidBrush(lightColor); + } + + protected void DefineHighlightBackColors(Color baseColor) + { + _highlightBackColor = baseColor; + + if (_defaultHighlightBackColor) + { + _highlightBackDark = SystemColors.Highlight; + _highlightBackLight = ColorHelper.CalculateColor(_highlightBackDark, Color.White, 70); + } + else + { + _highlightBackDark = ControlPaint.Dark(baseColor); + _highlightBackLight = baseColor; + } + } + + public virtual void OnSelected(MenuCommand mc) + { + // Any attached event handlers? + if (Selected != null) + Selected(mc); + } + + public virtual void OnDeselected(MenuCommand mc) + { + // Any attached event handlers? + if (Deselected != null) + Deselected(mc); + } + + protected void OnCollectionCleared() + { + // Reset state ready for a recalculation + Deselect(); + RemoveItemTracking(); + + Recalculate(); + Invalidate(); + } + + protected void OnCollectionInserted(int index, object value) + { + MenuCommand mc = value as MenuCommand; + + // We need notification whenever the properties of this command change + mc.PropertyChanged += new MenuCommand.PropChangeHandler(OnCommandChanged); + + // Reset state ready for a recalculation + Deselect(); + RemoveItemTracking(); + + Recalculate(); + Invalidate(); + } + + protected void OnCollectionRemoved(int index, object value) + { + // Reset state ready for a recalculation + Deselect(); + RemoveItemTracking(); + + Recalculate(); + Invalidate(); + } + + protected void OnCommandChanged(MenuCommand item, MenuCommand.Property prop) + { + Recalculate(); + Invalidate(); + } + + protected void OnMdiChildActivate(object sender, EventArgs e) + { + // Unhook from event + if (_activeChild != null) + _activeChild.SizeChanged -= new EventHandler(OnMdiChildSizeChanged); + + // Remember the currently active child form + _activeChild = _mdiContainer.ActiveMdiChild; + + // Need to know when window becomes maximized + if (_activeChild != null) + _activeChild.SizeChanged += new EventHandler(OnMdiChildSizeChanged); + + // Might be a change in pendant requirements + Recalculate(); + Invalidate(); + } + + protected void OnMdiChildSizeChanged(object sender, EventArgs e) + { + // Has window changed to become maximized? + if (_activeChild.WindowState == FormWindowState.Maximized) + { + // Reflect change in menu + Recalculate(); + Invalidate(); + } + } + + protected void OnMdiMin(object sender, EventArgs e) + { + if (_activeChild != null) + { + _activeChild.WindowState = FormWindowState.Minimized; + + // Reflect change in menu + Recalculate(); + Invalidate(); + } + } + + protected void OnMdiRestore(object sender, EventArgs e) + { + if (_activeChild != null) + { + _activeChild.WindowState = FormWindowState.Normal; + + // Reflect change in menu + Recalculate(); + Invalidate(); + } + } + + protected void OnMdiClose(object sender, EventArgs e) + { + if (_activeChild != null) + { + _activeChild.Close(); + + // Reflect change in menu + Recalculate(); + Invalidate(); + } + } + + protected void CreatePendantButtons() + { + // Create the objects + _minButton = new InertButton(_menuImages, _minIndex); + _restoreButton = new InertButton(_menuImages, _restoreIndex); + _closeButton = new InertButton(_menuImages, _closeIndex); + + // Define the constant sizes + _minButton.Size = new Size(_buttonLength, _buttonLength); + _restoreButton.Size = new Size(_buttonLength, _buttonLength); + _closeButton.Size = new Size(_buttonLength, _buttonLength); + + // Default their position so they are not visible + _minButton.Location = new Point(-_buttonLength, -_buttonLength); + _restoreButton.Location = new Point(-_buttonLength, -_buttonLength); + _closeButton.Location = new Point(-_buttonLength, -_buttonLength); + + // Hookup event handlers + _minButton.Click += new EventHandler(OnMdiMin); + _restoreButton.Click += new EventHandler(OnMdiRestore); + _closeButton.Click += new EventHandler(OnMdiClose); + + // Add to display + this.Controls.AddRange(new Control[] { _minButton, _restoreButton, _closeButton }); + } + + protected void RemovePendantButtons() + { + // Unhook event handlers + _minButton.Click -= new EventHandler(OnMdiMin); + _restoreButton.Click -= new EventHandler(OnMdiRestore); + _closeButton.Click -= new EventHandler(OnMdiClose); + + // Remove from display + + // Use helper method to circumvent form Close bug + ControlHelper.Remove(this.Controls, _minButton); + ControlHelper.Remove(this.Controls, _restoreButton); + ControlHelper.Remove(this.Controls, _closeButton); + + // Release resources + _minButton.Dispose(); + _restoreButton.Dispose(); + _closeButton.Dispose(); + + // Remove references + _minButton = null; + _restoreButton = null; + _closeButton = null; + } + + protected override void OnEnabledChanged(EventArgs e) + { + base.OnEnabledChanged(e); + + // Have we become disabled? + if (!this.Enabled) + { + // Is an item selected? + if (_selected) + { + // Is a popupMenu showing? + if (_popupMenu != null) + { + // Dismiss the submenu + _popupMenu.Dismiss(); + + // No reference needed + _popupMenu = null; + } + + // Reset state + Deselect(); + _drawUpwards = false; + + SimulateReturnFocus(); + } + } + + // Do not draw any item as being tracked + RemoveItemTracking(); + + // Change in state changes the way items are drawn + Invalidate(); + } + + /* + internal void OnWM_MOUSEDOWN(Win32.POINT screenPos) + { + // Convert the mouse position to screen coordinates + User32.ScreenToClient(this.Handle, ref screenPos); + + OnProcessMouseDown(screenPos.x, screenPos.y); + } + */ + + protected override void OnMouseDown(MouseEventArgs e) + { + OnProcessMouseDown(e.X, e.Y); + + base.OnMouseDown(e); + } + + protected void OnProcessMouseDown(int xPos, int yPos) + { + Point pos = new Point(xPos, yPos); + + for (int i = 0; i < _drawCommands.Count; i++) + { + DrawCommand dc = _drawCommands[i] as DrawCommand; + + // Find the DrawCommand this is over + if (dc.SelectRect.Contains(pos) && dc.Enabled) + { + // Is an item already selected? + if (_selected) + { + // Is it this item that is already selected? + if (_trackItem == i) + { + // Is a popupMenu showing + if (_popupMenu != null) + { + // Dismiss the submenu + _popupMenu.Dismiss(); + + // No reference needed + _popupMenu = null; + } + } + } + else + { + // Select the tracked item + _selected = true; + _drawUpwards = false; + + // Is there a change in tracking? + if (_trackItem != i) + { + // Modify the display of the two items + _trackItem = SwitchTrackingItem(_trackItem, i); + } + else + { + // Update display to show as selected + DrawCommand(_trackItem, true); + } + + // Is there a submenu to show? + // if (dc.Chevron || (dc.MenuCommand.MenuCommands.Count > 0)) + // User32.PostMessage(this.Handle, WM_OPERATEMENU, 1, 0); + } + + break; + } + } + } + + protected override void OnMouseUp(MouseEventArgs e) + { + // Is an item currently being tracked? + if (_trackItem != -1) + { + // Is it also selected? + if (_selected == true) + { + // Is it also showing a submenu + if (_popupMenu == null) + { + // Deselect the item + Deselect(); + _drawUpwards = false; + + DrawCommand(_trackItem, true); + + SimulateReturnFocus(); + } + } + } + + base.OnMouseUp(e); + } + + /* + internal void OnWM_MOUSEMOVE(Win32.POINT screenPos) + { + // Convert the mouse position to screen coordinates + User32.ScreenToClient(this.Handle, ref screenPos); + + OnProcessMouseMove(screenPos.x, screenPos.y); + } + */ + + protected override void OnMouseMove(MouseEventArgs e) + { + // Sometimes we need to ignore this message + if (_ignoreMouseMove) + _ignoreMouseMove = false; + else + OnProcessMouseMove(e.X, e.Y); + + base.OnMouseMove(e); + } + + protected void OnProcessMouseMove(int xPos, int yPos) + { + // Sometimes we need to ignore this message + if (_ignoreMouseMove) + _ignoreMouseMove = false; + else + { + // Is the first time we have noticed a mouse movement over our window + if (!_mouseOver) + { + // Create the structure needed for User32 call + Win32.TRACKMOUSEEVENTS tme = new Win32.TRACKMOUSEEVENTS(); + + // Fill in the structure + tme.cbSize = 16; + tme.dwFlags = (uint)Win32.TrackerEventFlags.TME_LEAVE; + tme.hWnd = this.Handle; + tme.dwHoverTime = 0; + + // Request that a message gets sent when mouse leaves this window + // User32.TrackMouseEvent(ref tme); + + // Yes, we know the mouse is over window + _mouseOver = true; + } + + Form parentForm = this.FindForm(); + + // Only hot track if this Form is active + if ((parentForm != null) && parentForm.ContainsFocus) + { + Point pos = new Point(xPos, yPos); + + int i = 0; + + for (i = 0; i < _drawCommands.Count; i++) + { + DrawCommand dc = _drawCommands[i] as DrawCommand; + + // Find the DrawCommand this is over + if (dc.SelectRect.Contains(pos) && dc.Enabled) + { + // Is there a change in selected item? + if (_trackItem != i) + { + // We are currently selecting an item + if (_selected) + { + if (_popupMenu != null) + { + // Note that we are dismissing the submenu but not removing + // the selection of items, this flag is tested by the routine + // that will return because the submenu has been finished + _dismissTransfer = true; + + // Dismiss the submenu + _popupMenu.Dismiss(); + + // Default to downward drawing + _drawUpwards = false; + } + + // Modify the display of the two items + _trackItem = SwitchTrackingItem(_trackItem, i); + + // Does the newly selected item have a submenu? + //if (dc.Chevron || (dc.MenuCommand.MenuCommands.Count > 0)) + // User32.PostMessage(this.Handle, WM_OPERATEMENU, 1, 0); + } + else + { + // Modify the display of the two items + _trackItem = SwitchTrackingItem(_trackItem, i); + } + } + + break; + } + } + + // If not in selected mode + if (!_selected) + { + // None of the commands match? + if (i == _drawCommands.Count) + { + // If we have the focus then do not change the tracked item + if (!_manualFocus) + { + // Modify the display of the two items + _trackItem = SwitchTrackingItem(_trackItem, -1); + } + } + } + } + } + } + + protected override void OnMouseLeave(EventArgs e) + { + _mouseOver = false; + + // If we manually grabbed focus then do not switch + // selection when the mouse leaves the control area + if (!_manualFocus) + { + if (_trackItem != -1) + { + // If an item is selected then do not change tracking item when the + // mouse leaves the control area, as a popup menu might be showing and + // so keep the tracking and selection indication visible + if (_selected == false) + _trackItem = SwitchTrackingItem(_trackItem, -1); + } + } + + base.OnMouseLeave(e); + } + + protected override void OnResize(EventArgs e) + { + Recalculate(); + + // Any resize of control should redraw all of it otherwise when you + // stretch to the right it will not paint correctly as we have a one + // pixel gap between text and min button which is not honoured otherwise + this.Invalidate(); + + base.OnResize(e); + } + + internal void DrawSelectionUpwards() + { + // Double check the state is correct for this method to be called + if ((_trackItem != -1) && (_selected)) + { + // This flag is tested in the DrawCommand method + _drawUpwards = true; + + // Force immediate redraw of the item + DrawCommand(_trackItem, true); + } + } + + protected void Deselect() + { + // The next submenu should be animated + _animateFirst = true; + + // Remove selection state + _selected = false; + + // Should expansion items be reset on deselection? + if (_deselectReset) + { + // Set everything to expanded + SetAllCommandsExpansion(_menuCommands, false); + } + } + + protected void Recalculate() + { + int length; + + if (_direction == Direction.Horizontal) + length = this.Width; + else + length = this.Height; + + // Is there space for any commands? + if (length > 0) + { + // Count the number of rows needed + int rows = 0; + + // Number of items on this row + int columns = 0; + + // Create a collection of drawing objects + _drawCommands = new ArrayList(); + + // Minimum length is a gap on either side of the text + int cellMinLength = _lengthGap * 2; + + // Each cell is as broad as the whole control + int cellBreadth = this.Height; + + // Accumulate starting position of each cell + int lengthStart = 0; + + // Allow enough space to draw a chevron + length -= (cellMinLength + _chevronLength); + + bool showPendant = ((rows == 0) && (_activeChild != null)); + + // If we are showing on a single line but the active child is not + // currently maximized then we can show a menu item in pendant space + if (showPendant && !_multiLine && (_activeChild.WindowState != FormWindowState.Maximized)) + showPendant = false; + + // Pendant positioning information + int xPos = 0; + int yPos = 0; + int xInc = 0; + int yInc = 0; + + // First line needs extra space for pendant + if (showPendant) + { + length -= (_pendantLength + _pendantOffset + _shadowGap); + + bool popupStyle = (_style == VisualStyle.IDE); + int borderWidth = (_style == VisualStyle.IDE) ? 1 : 2; + + // Define the correct visual style + _minButton.PopupStyle = popupStyle; + _restoreButton.PopupStyle = popupStyle; + _closeButton.PopupStyle = popupStyle; + + // Define correct border width + _minButton.BorderWidth = borderWidth; + _restoreButton.BorderWidth = borderWidth; + _closeButton.BorderWidth = borderWidth; + + if (_direction == Direction.Horizontal) + { + xPos = this.Width - _pendantOffset - _buttonLength; + yPos = _pendantOffset; + xInc = -_buttonLength; + } + else + { + xPos = _pendantOffset; + yPos = this.Height - _pendantOffset - _buttonLength; + yInc = -_buttonLength; + } + } + + // Assume chevron is not needed by default + _chevronStartCommand = null; + + using (Graphics g = this.CreateGraphics()) + { + // Count the item we are processing + int index = 0; + + foreach (MenuCommand command in _menuCommands) + { + // Give the command a chance to update its state + command.OnUpdate(EventArgs.Empty); + + // Ignore items that are marked as hidden + if (!command.Visible) + continue; + + int cellLength = 0; + + // Is this a separator? + if (command.Text == "-") + cellLength = _separatorWidth; + else + { + // Calculate the text width of the cell + SizeF dimension = g.MeasureString(command.Text, this.Font); + + // Always add 1 to ensure that rounding is up and not down + cellLength = cellMinLength + (int)dimension.Width + 1; + } + + Rectangle cellRect; + + // Create a new position rectangle + if (_direction == Direction.Horizontal) + cellRect = new Rectangle(lengthStart, _rowHeight * rows, cellLength, _rowHeight); + else + cellRect = new Rectangle(_rowWidth * rows, lengthStart, _rowWidth, cellLength); + + lengthStart += cellLength; + columns++; + + // If this item is overlapping the control edge and it is not the first + // item on the line then we should wrap around to the next row. + if ((lengthStart > length) && (columns > 1)) + { + if (_multiLine) + { + // Move to next row + rows++; + + // Reset number of items on this column + columns = 1; + + // Reset starting position of next item + lengthStart = cellLength; + + // Reset position of this item + if (_direction == Direction.Horizontal) + { + cellRect.X = 0; + cellRect.Y += _rowHeight; + } + else + { + cellRect.X += _rowWidth; + cellRect.Y = 0; + } + + // Only the first line needs extra space for pendant + if (showPendant && (rows == 1)) + length += (_pendantLength + _pendantOffset); + } + else + { + // Is a tracked item being make invisible + if (index <= _trackItem) + { + // Need to remove tracking of this item + RemoveItemTracking(); + } + + // Remember which item is first for the chevron submenu + _chevronStartCommand = command; + + if (_direction == Direction.Horizontal) + { + cellRect.Y = 0; + cellRect.Width = cellMinLength + _chevronLength; + cellRect.X = this.Width - cellRect.Width; + cellRect.Height = _rowHeight; + xPos -= cellRect.Width; + } + else + { + cellRect.X = 0; + cellRect.Height = cellMinLength + _chevronLength; + cellRect.Y = this.Height - (cellMinLength + _chevronLength); + cellRect.Width = _rowWidth; + yPos -= cellRect.Height; + } + + // Create a draw command for this chevron + _drawCommands.Add(new DrawCommand(cellRect)); + + // Exit, do not add the current item or any afterwards + break; + } + } + + Rectangle selectRect = cellRect; + + // Selection rectangle differs from drawing rectangle with IDE, because pressing the + // mouse down causes the menu to appear and because the popup menu appears drawn slightly + // over the drawing area the mouse up might select the first item in the popup. + if (_style == VisualStyle.IDE) + { + // Modify depending on orientation + if (_direction == Direction.Horizontal) + selectRect.Height -= (_lengthGap + 2); + else + selectRect.Width -= _breadthGap; + } + + // Create a drawing object + _drawCommands.Add(new DrawCommand(command, cellRect, selectRect)); + + index++; + } + } + + // Position the pendant buttons + if (showPendant) + { + if (_activeChild.WindowState == FormWindowState.Maximized) + { + // Window maximzied, must show the buttons + if (!_minButton.Visible) + { + _minButton.Show(); + _restoreButton.Show(); + _closeButton.Show(); + } + + // Only enabled minimize box if child is allowed to be minimized + _minButton.Enabled = _activeChild.MinimizeBox; + + _closeButton.Location = new Point(xPos, yPos); + + xPos += xInc; yPos += yInc; + _restoreButton.Location = new Point(xPos, yPos); + + xPos += xInc; yPos += yInc; + _minButton.Location = new Point(xPos, yPos); + } + else + { + // No window is maximized, so hide the buttons + if (_minButton.Visible) + { + _minButton.Hide(); + _restoreButton.Hide(); + _closeButton.Hide(); + } + } + } + else + { + // No window is maximized, so hide the buttons + if ((_minButton != null) && _minButton.Visible) + { + _minButton.Hide(); + _restoreButton.Hide(); + _closeButton.Hide(); + } + } + + if (_direction == Direction.Horizontal) + { + int controlHeight = (rows + 1) * _rowHeight; + + // Ensure the control is the correct height + if (this.Height != controlHeight) + this.Height = controlHeight; + } + else + { + int controlWidth = (rows + 1) * _rowWidth; + + // Ensure the control is the correct width + if (this.Width != controlWidth) + this.Width = controlWidth; + } + } + } + + protected void DrawCommand(int drawItem, bool tracked) + { + // Create a graphics object for drawing + using (Graphics g = this.CreateGraphics()) + DrawSingleCommand(g, _drawCommands[drawItem] as DrawCommand, tracked); + } + + internal void DrawSingleCommand(Graphics g, DrawCommand dc, bool tracked) + { + Rectangle drawRect = dc.DrawRect; + MenuCommand mc = dc.MenuCommand; + + // Copy the rectangle used for drawing cell + Rectangle shadowRect = drawRect; + + // Expand to right and bottom to cover the area used to draw shadows + shadowRect.Width += _shadowGap; + shadowRect.Height += _shadowGap; + + if (!dc.Separator) + { + Rectangle textRect; + + // Text rectangle size depends on type of draw command we are drawing + if (dc.Chevron) + { + // Create chevron drawing rectangle + textRect = new Rectangle(drawRect.Left + _lengthGap, drawRect.Top + _boxExpandUpper, + drawRect.Width - _lengthGap * 2, drawRect.Height - (_boxExpandUpper * 2)); + } + else + { + // Create text drawing rectangle + textRect = new Rectangle(drawRect.Left + _lengthGap, drawRect.Top + _lengthGap, + drawRect.Width - _lengthGap * 2, drawRect.Height - _lengthGap * 2); + } + + if (dc.Enabled) + { + // Draw selection + if (tracked) + { + Rectangle boxRect; + + // Create the rectangle for box around the text + if (_direction == Direction.Horizontal) + { + boxRect = new Rectangle(textRect.Left - _boxExpandSides, + textRect.Top - _boxExpandUpper, + textRect.Width + _boxExpandSides * 2, + textRect.Height + _boxExpandUpper); + } + else + { + if (!dc.Chevron) + { + boxRect = new Rectangle(textRect.Left, + textRect.Top - _boxExpandSides, + textRect.Width - _boxExpandSides, + textRect.Height + _boxExpandSides * 2); + } + else + boxRect = textRect; + } + + switch (_style) + { + case VisualStyle.IDE: + if (_selected) + { + // Fill the entire inside + g.FillRectangle(Brushes.White, boxRect); + g.FillRectangle(_controlLBrush, boxRect); + + Color extraColor = Color.FromArgb(64, 0, 0, 0); + Color darkColor = Color.FromArgb(48, 0, 0, 0); + Color lightColor = Color.FromArgb(0, 0, 0, 0); + + int rightLeft = boxRect.Right + 1; + int rightBottom = boxRect.Bottom; + + if (_drawUpwards && (_direction == Direction.Horizontal)) + { + // Draw the box around the selection area + using (Pen dark = new Pen(ControlPaint.Dark(_selectedBackColor))) + g.DrawRectangle(dark, boxRect); + + if (dc.SubMenu) + { + // Right shadow + int rightTop = boxRect.Top; + int leftLeft = boxRect.Left + _shadowGap; + + // Bottom shadow + int top = boxRect.Bottom + 1; + int left = boxRect.Left + _shadowGap; + int width = boxRect.Width + 1; + int height = _shadowGap; + + Brush rightShadow; + Brush bottomLeftShadow; + Brush bottomShadow; + Brush bottomRightShadow; + + // Decide if we need to use an alpha brush + if (_supportsLayered) + { + // Create brushes + rightShadow = new LinearGradientBrush(new Point(rightLeft, 9999), + new Point(rightLeft + _shadowGap, 9999), + darkColor, lightColor); + + bottomLeftShadow = new LinearGradientBrush(new Point(left + _shadowGap, top - _shadowGap), + new Point(left, top + height), + extraColor, lightColor); + + bottomRightShadow = new LinearGradientBrush(new Point(left + width - _shadowGap - 2, top - _shadowGap - 2), + new Point(left + width, top + height), + extraColor, lightColor); + + bottomShadow = new LinearGradientBrush(new Point(9999, top), + new Point(9999, top + height), + darkColor, lightColor); + } + else + { + rightShadow = new SolidBrush(SystemColors.ControlDark); + bottomLeftShadow = rightShadow; + bottomShadow = rightShadow; + bottomRightShadow = rightShadow; + } + + // Draw each part of the shadow area + g.FillRectangle(rightShadow, new Rectangle(rightLeft, rightTop, _shadowGap, rightBottom - rightTop + 1)); + g.FillRectangle(bottomLeftShadow, left, top, _shadowGap, height); + g.FillRectangle(bottomRightShadow, left + width - _shadowGap, top, _shadowGap, height); + g.FillRectangle(bottomShadow, left + _shadowGap, top, width - _shadowGap * 2, height); + + // Dispose of brush objects + if (_supportsLayered) + { + rightShadow.Dispose(); + bottomLeftShadow.Dispose(); + bottomShadow.Dispose(); + bottomRightShadow.Dispose(); + } + else + rightShadow.Dispose(); + } + } + else + { + // Draw the box around the selection area + using (Pen dark = new Pen(ControlPaint.Dark(_selectedBackColor))) + g.DrawRectangle(dark, boxRect); + + if (dc.SubMenu) + { + if (_direction == Direction.Horizontal) + { + // Remove the bottom line of the selection area + g.DrawLine(Pens.White, boxRect.Left, boxRect.Bottom, boxRect.Right, boxRect.Bottom); + g.DrawLine(_controlLPen, boxRect.Left, boxRect.Bottom, boxRect.Right, boxRect.Bottom); + + int rightTop = boxRect.Top + _shadowYOffset; + + Brush shadowBrush; + + // Decide if we need to use an alpha brush + if (_supportsLayered && (_style == VisualStyle.IDE)) + { + using (LinearGradientBrush topBrush = new LinearGradientBrush(new Point(rightLeft - _shadowGap, rightTop + _shadowGap), + new Point(rightLeft + _shadowGap, rightTop), + extraColor, lightColor)) + { + g.FillRectangle(topBrush, new Rectangle(rightLeft, rightTop, _shadowGap, _shadowGap)); + + rightTop += _shadowGap; + } + + shadowBrush = new LinearGradientBrush(new Point(rightLeft, 9999), + new Point(rightLeft + _shadowGap, 9999), + darkColor, lightColor); + } + else + shadowBrush = new SolidBrush(SystemColors.ControlDark); + + g.FillRectangle(shadowBrush, new Rectangle(rightLeft, rightTop, _shadowGap, rightBottom - rightTop)); + + shadowBrush.Dispose(); + } + else + { + // Remove the right line of the selection area + g.DrawLine(Pens.White, boxRect.Right, boxRect.Top, boxRect.Right, boxRect.Bottom); + g.DrawLine(_controlLPen, boxRect.Right, boxRect.Top, boxRect.Right, boxRect.Bottom); + + int leftLeft = boxRect.Left + _shadowYOffset; + + Brush shadowBrush; + + // Decide if we need to use an alpha brush + if (_supportsLayered && (_style == VisualStyle.IDE)) + { + using (LinearGradientBrush topBrush = new LinearGradientBrush(new Point(leftLeft + _shadowGap, rightBottom + 1 - _shadowGap), + new Point(leftLeft, rightBottom + 1 + _shadowGap), + extraColor, lightColor)) + { + g.FillRectangle(topBrush, new Rectangle(leftLeft, rightBottom + 1, _shadowGap, _shadowGap)); + + leftLeft += _shadowGap; + } + + shadowBrush = new LinearGradientBrush(new Point(9999, rightBottom + 1), + new Point(9999, rightBottom + 1 + _shadowGap), + darkColor, lightColor); + } + else + shadowBrush = new SolidBrush(SystemColors.ControlDark); + + g.FillRectangle(shadowBrush, new Rectangle(leftLeft, rightBottom + 1, rightBottom - leftLeft - _shadowGap, _shadowGap)); + + shadowBrush.Dispose(); + } + } + } + } + else + { + using (Pen selectPen = new Pen(_highlightBackDark)) + { + // Draw the selection area in white so can alpha draw over the top + g.FillRectangle(Brushes.White, boxRect); + + using (SolidBrush selectBrush = new SolidBrush(_highlightBackLight)) + { + // Draw the selection area + g.FillRectangle(selectBrush, boxRect); + + // Draw a border around the selection area + g.DrawRectangle(selectPen, boxRect); + } + } + } + break; + + case VisualStyle.Plain: + if (_plainAsBlock) + { + using (SolidBrush selectBrush = new SolidBrush(_highlightBackDark)) + g.FillRectangle(selectBrush, drawRect); + } + else + { + if (_selected) + { + using (Pen lighlight = new Pen(ControlPaint.LightLight(this.BackColor)), + dark = new Pen(ControlPaint.DarkDark(this.BackColor))) + { + g.DrawLine(dark, boxRect.Left, boxRect.Bottom, boxRect.Left, boxRect.Top); + g.DrawLine(dark, boxRect.Left, boxRect.Top, boxRect.Right, boxRect.Top); + g.DrawLine(lighlight, boxRect.Right, boxRect.Top, boxRect.Right, boxRect.Bottom); + g.DrawLine(lighlight, boxRect.Right, boxRect.Bottom, boxRect.Left, boxRect.Bottom); + } + } + else + { + using (Pen lighlight = new Pen(ControlPaint.LightLight(this.BackColor)), + dark = new Pen(ControlPaint.DarkDark(this.BackColor))) + { + g.DrawLine(lighlight, boxRect.Left, boxRect.Bottom, boxRect.Left, boxRect.Top); + g.DrawLine(lighlight, boxRect.Left, boxRect.Top, boxRect.Right, boxRect.Top); + g.DrawLine(dark, boxRect.Right, boxRect.Top, boxRect.Right, boxRect.Bottom); + g.DrawLine(dark, boxRect.Right, boxRect.Bottom, boxRect.Left, boxRect.Bottom); + } + } + } + break; + } + } + } + + if (dc.Chevron) + { + // Draw the chevron image in the centre of the text area + int yPos = drawRect.Top; + int xPos = drawRect.X + ((drawRect.Width - _chevronLength) / 2); + + // When selected... + if (_selected) + { + // ...offset down and to the right + xPos += 1; + yPos += 1; + } + + g.DrawImage(_menuImages.Images[_chevronIndex], xPos, yPos); + } + else + { + // Left align the text drawing on a single line centered vertically + // and process the & character to be shown as an underscore on next character + StringFormat format = new StringFormat(); + format.FormatFlags = StringFormatFlags.NoClip | StringFormatFlags.NoWrap; + format.Alignment = StringAlignment.Center; + format.LineAlignment = StringAlignment.Center; + format.HotkeyPrefix = HotkeyPrefix.Show; + + if (_direction == Direction.Vertical) + format.FormatFlags |= StringFormatFlags.DirectionVertical; + + if (dc.Enabled && this.Enabled) + { + if (tracked && (_style == VisualStyle.Plain) && _plainAsBlock) + { + // Is the item selected as well as tracked? + if (_selected) + { + // Offset to show it is selected + textRect.X += 2; + textRect.Y += 2; + } + + using (SolidBrush textBrush = new SolidBrush(_plainSelectedTextColor)) + g.DrawString(mc.Text, this.Font, textBrush, textRect, format); + } + else + { + if (_selected && tracked) + { + using (SolidBrush textBrush = new SolidBrush(_selectedTextColor)) + g.DrawString(mc.Text, this.Font, textBrush, textRect, format); + } + else + { + if (tracked) + { + using (SolidBrush textBrush = new SolidBrush(_highlightTextColor)) + g.DrawString(mc.Text, this.Font, textBrush, textRect, format); + } + else + { + using (SolidBrush textBrush = new SolidBrush(_textColor)) + g.DrawString(mc.Text, this.Font, textBrush, textRect, format); + } + } + } + } + else + { + // Helper values used when drawing grayed text in plain style + Rectangle rectDownRight = textRect; + rectDownRight.Offset(1, 1); + + // Draw the text offset down and right + g.DrawString(mc.Text, this.Font, Brushes.White, rectDownRight, format); + + // Draw then text offset up and left + using (SolidBrush grayBrush = new SolidBrush(SystemColors.GrayText)) + g.DrawString(mc.Text, this.Font, grayBrush, textRect, format); + } + } + } + } + + protected void DrawAllCommands(Graphics g) + { + for (int i = 0; i < _drawCommands.Count; i++) + { + // Grab some commonly used values + DrawCommand dc = _drawCommands[i] as DrawCommand; + + // Draw this command only + DrawSingleCommand(g, dc, (i == _trackItem)); + } + } + + protected int SwitchTrackingItem(int oldItem, int newItem) + { + // Create a graphics object for drawinh + using (Graphics g = this.CreateGraphics()) + { + // Deselect the old draw command + if (oldItem != -1) + { + DrawCommand dc = _drawCommands[oldItem] as DrawCommand; + + // Draw old item not selected + DrawSingleCommand(g, _drawCommands[oldItem] as DrawCommand, false); + + // Generate an unselect event + if (dc.MenuCommand != null) + OnDeselected(dc.MenuCommand); + } + + _trackItem = newItem; + + // Select the new draw command + if (_trackItem != -1) + { + DrawCommand dc = _drawCommands[_trackItem] as DrawCommand; + + // Draw new item selected + DrawSingleCommand(g, _drawCommands[_trackItem] as DrawCommand, true); + + // Generate an select event + if (dc.MenuCommand != null) + OnSelected(dc.MenuCommand); + } + + // Request redraw of all items to prevent strange bug where some items + // never get redrawn correctly and so leave blank spaces when using the + // mouse/keyboard to shift between popup menus + Invalidate(); + } + + return _trackItem; + } + + protected void RemoveItemTracking() + { + if (_trackItem != -1) + { + DrawCommand dc = _drawCommands[_trackItem] as DrawCommand; + + // Generate an unselect event + if (dc.MenuCommand != null) + OnDeselected(dc.MenuCommand); + + // Remove tracking value + _trackItem = -1; + } + } + + internal void OperateSubMenu(DrawCommand dc, bool selectFirst, bool trackRemove) + { + if (this.IsDisposed) + return; + + Rectangle drawRect = dc.DrawRect; + + // Find screen positions for popup menu + Point screenPos; + + if (_style == VisualStyle.IDE) + { + if (_direction == Direction.Horizontal) + screenPos = PointToScreen(new Point(dc.DrawRect.Left + 1, drawRect.Bottom - _lengthGap - 2)); + else + screenPos = PointToScreen(new Point(dc.DrawRect.Right - _breadthGap, drawRect.Top + _boxExpandSides - 1)); + } + else + { + if (_direction == Direction.Horizontal) + screenPos = PointToScreen(new Point(dc.DrawRect.Left + 1, drawRect.Bottom)); + else + screenPos = PointToScreen(new Point(dc.DrawRect.Right, drawRect.Top)); + } + + Point aboveScreenPos; + + if (_style == VisualStyle.IDE) + { + if (_direction == Direction.Horizontal) + aboveScreenPos = PointToScreen(new Point(dc.DrawRect.Left + 1, drawRect.Top + _breadthGap + _lengthGap - 1)); + else + aboveScreenPos = PointToScreen(new Point(dc.DrawRect.Right - _breadthGap, drawRect.Bottom + _lengthGap + 1)); + } + else + { + if (_direction == Direction.Horizontal) + aboveScreenPos = PointToScreen(new Point(dc.DrawRect.Left + 1, drawRect.Top)); + else + aboveScreenPos = PointToScreen(new Point(dc.DrawRect.Right, drawRect.Bottom)); + } + + int borderGap; + + // Calculate the missing gap in the PopupMenu border + if (_direction == Direction.Horizontal) + borderGap = dc.DrawRect.Width - _subMenuBorderAdjust; + else + borderGap = dc.DrawRect.Height - _subMenuBorderAdjust; + + _popupMenu = new PopupMenu(); + + // Define the correct visual style based on ours + _popupMenu.Style = this.Style; + + // Key direction when keys cause dismissal + int returnDir = 0; + + // Command selected by the PopupMenu + MenuCommand returnCommand = null; + + // Should the PopupMenu tell the collection to remember expansion state + _popupMenu.RememberExpansion = _rememberExpansion; + + // Propogate our highlight setting + _popupMenu.HighlightInfrequent = _highlightInfrequent; + + // Might need to define custom colors + if (!_defaultSelectedBackColor) + _popupMenu.BackColor = _selectedBackColor; + + if (!_defaultSelectedTextColor) + _popupMenu.TextColor = _selectedTextColor; + + if (!_defaultHighlightTextColor) + _popupMenu.HighlightTextColor = _highlightTextColor; + + if (!_defaultHighlightBackColor) + _popupMenu.HighlightColor = _highlightBackColor; + + if (!_defaultFont) + _popupMenu.Font = base.Font; + + // Pass on the animation values + _popupMenu.Animate = _animate; + _popupMenu.AnimateStyle = _animateStyle; + _popupMenu.AnimateTime = _animateTime; + + if (dc.Chevron) + { + MenuCommandCollection mcc = new MenuCommandCollection(); + + bool addCommands = false; + + // Generate a collection of menu commands for those not visible + foreach (MenuCommand command in _menuCommands) + { + if (!addCommands && (command == _chevronStartCommand)) + addCommands = true; + + if (addCommands) + mcc.Add(command); + } + + // Track the popup using provided menu item collection + returnCommand = _popupMenu.TrackPopup(screenPos, + aboveScreenPos, + _direction, + mcc, + borderGap, + selectFirst, + this, + _animateFirst, + ref returnDir); + } + else + { + // Generate event so that caller has chance to modify MenuCommand contents + dc.MenuCommand.OnPopupStart(); + + // Honour the collections request for showing infrequent items + _popupMenu.ShowInfrequent = dc.MenuCommand.MenuCommands.ShowInfrequent; + + // Track the popup using provided menu item collection + returnCommand = _popupMenu.TrackPopup(screenPos, + aboveScreenPos, + _direction, + dc.MenuCommand.MenuCommands, + borderGap, + selectFirst, + this, + _animateFirst, + ref returnDir); + } + + // No more animation till simulation ends + _animateFirst = false; + + // If we are supposed to expand all items at the same time + if (_expandAllTogether) + { + // Is anything we have shown now in the expanded state + if (AnythingExpanded(_menuCommands)) + { + // Set everything to expanded + SetAllCommandsExpansion(_menuCommands, true); + } + } + + // Was arrow key not used to dismiss the submenu? + if (returnDir == 0) + { + // The submenu may have eaten the mouse leave event + _mouseOver = false; + + // Only if the submenu was dismissed at the request of the submenu + // should the selection mode be cancelled, otherwise keep selection mode + if (!_dismissTransfer) + { + // This item is no longer selected + Deselect(); + _drawUpwards = false; + + if (!this.IsDisposed) + { + // Should we stop tracking this item + if (trackRemove) + { + // Unselect the current item + _trackItem = SwitchTrackingItem(_trackItem, -1); + } + else + { + if (_trackItem != -1) + { + // Repaint the item + DrawCommand(_trackItem, true); + } + } + } + } + else + { + // Do not change _selected status + _dismissTransfer = false; + } + } + + if (!dc.Chevron) + { + // Generate event so that caller has chance to modify MenuCommand contents + dc.MenuCommand.OnPopupEnd(); + } + + // Spin the message loop so the messages dealing with destroying + // the PopupMenu window are processed and cause it to disappear from + // view before events are generated + Application.DoEvents(); + + // Remove unwanted object + _popupMenu = null; + + // Was arrow key used to dismiss the submenu? + if (returnDir != 0) + { + if (returnDir < 0) + { + // Shift selection left one + ProcessMoveLeft(true); + } + else + { + // Shift selection right one + ProcessMoveRight(true); + } + + // A WM_MOUSEMOVE is generated when we open up the new submenu for + // display, ignore this as it causes the selection to move + _ignoreMouseMove = true; + } + else + { + // Was a MenuCommand returned? + if (returnCommand != null) + { + // Remove + + // Are we simulating having the focus? + if (_manualFocus) + { + // Always return focus to original when a selection is made + SimulateReturnFocus(); + } + + // Pulse the selected event for the command + returnCommand.OnClick(EventArgs.Empty); + } + } + } + + protected bool AnythingExpanded(MenuCommandCollection mcc) + { + foreach (MenuCommand mc in mcc) + { + if (mc.MenuCommands.ShowInfrequent) + return true; + + if (AnythingExpanded(mc.MenuCommands)) + return true; + } + + return false; + } + + protected void SetAllCommandsExpansion(MenuCommandCollection mcc, bool show) + { + foreach (MenuCommand mc in mcc) + { + // Set the correct value for this collection + mc.MenuCommands.ShowInfrequent = show; + + // Recurse into all lower level collections + SetAllCommandsExpansion(mc.MenuCommands, show); + } + } + + protected void SimulateGrabFocus() + { + /* + if (!_manualFocus) + { + _manualFocus = true; + _animateFirst = true; + + Form parentForm = this.FindForm(); + + // Want notification when user selects a different Form + parentForm.Deactivate += new EventHandler(OnParentDeactivate); + + // Must hide caret so user thinks focus has changed + bool hideCaret = User32.HideCaret(IntPtr.Zero); + + // Create an object for storing windows message information + Win32.MSG msg = new Win32.MSG(); + + _exitLoop = false; + + // Process messages until exit condition recognised + while(!_exitLoop) + { + // Suspend thread until a windows message has arrived + if (User32.WaitMessage()) + { + // Take a peek at the message details without removing from queue + while(!_exitLoop && User32.PeekMessage(ref msg, 0, 0, 0, (int)Win32.PeekMessageFlags.PM_NOREMOVE)) + { + // Console.WriteLine("Loop {0} {1}", this.Handle, ((Win32.Msgs)msg.message).ToString()); + + if (User32.GetMessage(ref msg, 0, 0, 0)) + { + // Should this method be dispatched? + if (!ProcessInterceptedMessage(ref msg)) + { + User32.TranslateMessage(ref msg); + User32.DispatchMessage(ref msg); + } + } + } + } + } + + // Remove notification when user selects a different Form + parentForm.Deactivate -= new EventHandler(OnParentDeactivate); + + // If caret was hidden then show it again now + if (hideCaret) + User32.ShowCaret(IntPtr.Zero); + + // We lost the focus + _manualFocus = false; + } + */ + } + + protected void SimulateReturnFocus() + { + if (_manualFocus) + _exitLoop = true; + + // Remove any item being tracked + if (_trackItem != -1) + { + // Unselect the current item + _trackItem = SwitchTrackingItem(_trackItem, -1); + } + } + + protected void OnParentDeactivate(object sender, EventArgs e) + { + SimulateReturnFocus(); + } + + protected override void OnPaint(PaintEventArgs e) + { + DrawAllCommands(e.Graphics); + base.OnPaint(e); + } + + protected void ProcessMoveLeft(bool select) + { + if (_popupMenu == null) + { + int newItem = _trackItem; + int startItem = newItem; + + for (int i = 0; i < _drawCommands.Count; i++) + { + // Move to previous item + newItem--; + + // Have we looped all the way around all choices + if (newItem == startItem) + return; + + // Check limits + if (newItem < 0) + newItem = _drawCommands.Count - 1; + + DrawCommand dc = _drawCommands[newItem] as DrawCommand; + + // Can we select this item? + if (!dc.Separator && (dc.Chevron || dc.MenuCommand.Enabled)) + { + // If a change has occured + if (newItem != _trackItem) + { + // Modify the display of the two items + _trackItem = SwitchTrackingItem(_trackItem, newItem); + + if (_selected) + { + //if (dc.Chevron || (dc.MenuCommand.MenuCommands.Count > 0)) + // User32.PostMessage(this.Handle, WM_OPERATEMENU, 0, 1); + } + + break; + } + } + } + } + } + + protected void ProcessMoveRight(bool select) + { + if (_popupMenu == null) + { + int newItem = _trackItem; + int startItem = newItem; + + for (int i = 0; i < _drawCommands.Count; i++) + { + // Move to previous item + newItem++; + + // Check limits + if (newItem >= _drawCommands.Count) + newItem = 0; + + DrawCommand dc = _drawCommands[newItem] as DrawCommand; + + // Can we select this item? + if (!dc.Separator && (dc.Chevron || dc.MenuCommand.Enabled)) + { + // If a change has occured + if (newItem != _trackItem) + { + // Modify the display of the two items + _trackItem = SwitchTrackingItem(_trackItem, newItem); + + if (_selected) + { + //if (dc.Chevron || (dc.MenuCommand.MenuCommands.Count > 0)) + // User32.PostMessage(this.Handle, WM_OPERATEMENU, 0, 1); + } + + break; + } + } + } + } + } + + protected void ProcessEnter() + { + if (_popupMenu == null) + { + // Are we tracking an item? + if (_trackItem != -1) + { + // The item must not already be selected + if (!_selected) + { + DrawCommand dc = _drawCommands[_trackItem] as DrawCommand; + + // Is there a submenu to show? + if (dc.Chevron || (dc.MenuCommand.MenuCommands.Count >= 0)) + { + // Select the tracked item + _selected = true; + _drawUpwards = false; + + // Update display to show as selected + DrawCommand(_trackItem, true); + + // Show the submenu + + //if (dc.Chevron || (dc.MenuCommand.MenuCommands.Count > 0)) + // User32.PostMessage(this.Handle, WM_OPERATEMENU, 0, 1); + } + else + { + // No, pulse the Click event for the command + dc.MenuCommand.OnClick(EventArgs.Empty); + + int item = _trackItem; + + // Not tracking anymore + RemoveItemTracking(); + + // Update display to show as not selected + DrawCommand(item, false); + + // Finished, so return focus to origin + SimulateReturnFocus(); + } + } + else + { + // Must be showing a submenu less item as selected + DrawCommand dc = _drawCommands[_trackItem] as DrawCommand; + + // Pulse the event + dc.MenuCommand.OnClick(EventArgs.Empty); + + int item = _trackItem; + + RemoveItemTracking(); + + // Not selected anymore + Deselect(); + + // Update display to show as not selected + DrawCommand(item, false); + + // Finished, so return focus to origin + SimulateReturnFocus(); + } + } + } + } + + protected void ProcessMoveDown() + { + if (_popupMenu == null) + { + // Are we tracking an item? + if (_trackItem != -1) + { + // The item must not already be selected + if (!_selected) + { + DrawCommand dc = _drawCommands[_trackItem] as DrawCommand; + + // Is there a submenu to show? + if (dc.Chevron || (dc.MenuCommand.MenuCommands.Count >= 0)) + { + // Select the tracked item + _selected = true; + _drawUpwards = false; + + // Update display to show as selected + DrawCommand(_trackItem, true); + + // Show the submenu + //if (dc.Chevron || (dc.MenuCommand.MenuCommands.Count > 0)) + // User32.PostMessage(this.Handle, WM_OPERATEMENU, 0, 1); + } + } + } + } + } + + protected bool ProcessMnemonicKey(char key) + { + // No current selection + if (!_selected) + { + // Search for an item that matches + for (int i = 0; i < _drawCommands.Count; i++) + { + DrawCommand dc = _drawCommands[i] as DrawCommand; + + // Only interested in enabled items + if ((dc.MenuCommand != null) && dc.MenuCommand.Enabled && dc.MenuCommand.Visible) + { + // Does the character match? + if (key == dc.Mnemonic) + { + // Select the tracked item + _selected = true; + _drawUpwards = false; + + // Is there a change in tracking? + if (_trackItem != i) + { + // Modify the display of the two items + _trackItem = SwitchTrackingItem(_trackItem, i); + } + else + { + // Update display to show as selected + DrawCommand(_trackItem, true); + } + + // Is there a submenu to show? + if (dc.Chevron || (dc.MenuCommand.MenuCommands.Count >= 0)) + { + //if (dc.Chevron || (dc.MenuCommand.MenuCommands.Count > 0)) + // User32.PostMessage(this.Handle, WM_OPERATEMENU, 0, 1); + + return true; + } + else + { + // No, pulse the Click event for the command + dc.MenuCommand.OnClick(EventArgs.Empty); + + int item = _trackItem; + + RemoveItemTracking(); + + // No longer seleted + Deselect(); + + // Update display to show as not selected + DrawCommand(item, false); + + // Finished, so return focus to origin + SimulateReturnFocus(); + + return false; + } + } + } + } + } + + return false; + } + + protected void OnPreferenceChanged(object sender, UserPreferenceChangedEventArgs e) + { + // Are we using the default menu or a user defined value? + if (_defaultFont) + { + DefineFont(SystemInformation.MenuFont); + + Recalculate(); + Invalidate(); + } + } + + protected override void OnSystemColorsChanged(EventArgs e) + { + if (_defaultBackColor) + this.BackColor = SystemColors.Control; + + if (_defaultHighlightBackColor) + this.HighlightBackColor = SystemColors.Highlight; + + if (_defaultSelectedBackColor) + this.SelectedBackColor = SystemColors.Control; + + if (_defaultTextColor) + _textColor = SystemColors.MenuText; + + if (_defaultHighlightTextColor) + _highlightTextColor = SystemColors.MenuText; + + if (_defaultSelectedTextColor) + _selectedTextColor = SystemColors.MenuText; + + Recalculate(); + Invalidate(); + + base.OnSystemColorsChanged(e); + } + + public bool PreFilterMessage(ref Message msg) + { + Form parentForm = this.FindForm(); + + // Only interested if the Form we are on is activate (i.e. contains focus) + if ((parentForm != null) && (parentForm == Form.ActiveForm) && parentForm.ContainsFocus) + { + switch (msg.Msg) + { + case (int)Win32.Msgs.WM_KEYDOWN: + /* + // Ignore keyboard input if the control is disabled + if (this.Enabled) + { + // Find up/down state of shift and control keys + ushort shiftKey = User32.GetKeyState((int)Win32.VirtualKeys.VK_SHIFT); + ushort controlKey = User32.GetKeyState((int)Win32.VirtualKeys.VK_CONTROL); + + // Basic code we are looking for is the key pressed... + int code = (int)msg.WParam; + + // ...plus the modifier for SHIFT... + if (((int)shiftKey & 0x00008000) != 0) + code += 0x00010000; + + // ...plus the modifier for CONTROL + if (((int)controlKey & 0x00008000) != 0) + code += 0x00020000; + + // Construct shortcut from keystate and keychar + Shortcut sc = (Shortcut)(code); + + // Search for a matching command + return GenerateShortcut(sc, _menuCommands); + } + */ + break; + + case (int)Win32.Msgs.WM_SYSKEYUP: + // Ignore keyboard input if the control is disabled + if (this.Enabled) + { + if ((int)msg.WParam == (int)Win32.VirtualKeys.VK_MENU) + { + // Are there any menu commands? + if (_drawCommands.Count > 0) + { + // If no item is currently tracked then... + if (_trackItem == -1) + { + // ...start tracking the first valid command + for (int i = 0; i < _drawCommands.Count; i++) + { + DrawCommand dc = _drawCommands[i] as DrawCommand; + + if (!dc.Separator && (dc.Chevron || dc.MenuCommand.Enabled)) + { + _trackItem = SwitchTrackingItem(-1, i); + break; + } + } + } + + // Grab the focus for key events + SimulateGrabFocus(); + } + + return true; + } + } + break; + + case (int)Win32.Msgs.WM_SYSKEYDOWN: + // Ignore keyboard input if the control is disabled + if (this.Enabled) + { + if ((int)msg.WParam != (int)Win32.VirtualKeys.VK_MENU) + { + // Construct shortcut from ALT + keychar + Shortcut sc = (Shortcut)(0x00040000 + (int)msg.WParam); + + if (GenerateShortcut(sc, _menuCommands)) + return true; + + // Last resort is treat as a potential mnemonic + if (ProcessMnemonicKey((char)msg.WParam)) + { + if (!_manualFocus) + SimulateGrabFocus(); + + return true; + } + } + } + break; + + default: + break; + } + } + + return false; + } + + /* + protected bool ProcessInterceptedMessage(ref Win32.MSG msg) + { + bool eat = false; + + switch(msg.message) + { + case (int)Win32.Msgs.WM_LBUTTONDOWN: + case (int)Win32.Msgs.WM_MBUTTONDOWN: + case (int)Win32.Msgs.WM_RBUTTONDOWN: + case (int)Win32.Msgs.WM_XBUTTONDOWN: + case (int)Win32.Msgs.WM_NCLBUTTONDOWN: + case (int)Win32.Msgs.WM_NCMBUTTONDOWN: + case (int)Win32.Msgs.WM_NCRBUTTONDOWN: + // Mouse clicks cause the end of simulated focus unless they are + // inside the client area of the menu control itself + Point pt = new Point( (int)((uint)msg.lParam & 0x0000FFFFU), + (int)(((uint)msg.lParam & 0xFFFF0000U) >> 16)); + + if (!this.ClientRectangle.Contains(pt)) + SimulateReturnFocus(); + break; + + case (int)Win32.Msgs.WM_KEYDOWN: + // Find up/down state of shift and control keys + ushort shiftKey = User32.GetKeyState((int)Win32.VirtualKeys.VK_SHIFT); + ushort controlKey = User32.GetKeyState((int)Win32.VirtualKeys.VK_CONTROL); + + // Basic code we are looking for is the key pressed... + int basecode = (int)msg.wParam; + int code = basecode; + + // ...plus the modifier for SHIFT... + if (((int)shiftKey & 0x00008000) != 0) + code += 0x00010000; + + // ...plus the modifier for CONTROL + if (((int)controlKey & 0x00008000) != 0) + code += 0x00020000; + + if (code == (int)Win32.VirtualKeys.VK_ESCAPE) + { + // Is an item being tracked + if (_trackItem != -1) + { + // Is it also showing a submenu + if (_popupMenu == null) + { + // Unselect the current item + _trackItem = SwitchTrackingItem(_trackItem, -1); + } + } + + SimulateReturnFocus(); + + // Prevent intended destination getting message + eat = true; + } + else if (code == (int)Win32.VirtualKeys.VK_LEFT) + { + if (_direction == Direction.Horizontal) + ProcessMoveLeft(false); + + if (_selected) + _ignoreMouseMove = true; + + // Prevent intended destination getting message + eat = true; + } + else if (code == (int)Win32.VirtualKeys.VK_RIGHT) + { + if (_direction == Direction.Horizontal) + ProcessMoveRight(false); + else + ProcessMoveDown(); + + if (_selected) + _ignoreMouseMove = true; + + // Prevent intended destination getting message + eat = true; + } + else if (code == (int)Win32.VirtualKeys.VK_RETURN) + { + ProcessEnter(); + + // Prevent intended destination getting message + eat = true; + } + else if (code == (int)Win32.VirtualKeys.VK_DOWN) + { + if (_direction == Direction.Horizontal) + ProcessMoveDown(); + else + ProcessMoveRight(false); + + // Prevent intended destination getting message + eat = true; + } + else if (code == (int)Win32.VirtualKeys.VK_UP) + { + ProcessMoveLeft(false); + + // Prevent intended destination getting message + eat = true; + } + else + { + // Construct shortcut from keystate and keychar + Shortcut sc = (Shortcut)(code); + + // Search for a matching command + if (!GenerateShortcut(sc, _menuCommands)) + { + // Last resort is treat as a potential mnemonic + ProcessMnemonicKey((char)msg.wParam); + + if (_selected) + _ignoreMouseMove = true; + } + else + { + SimulateReturnFocus(); + } + + // Always eat keyboard message in simulated focus + eat = true; + } + break; + + case (int)Win32.Msgs.WM_KEYUP: + eat = true; + break; + + case (int)Win32.Msgs.WM_SYSKEYUP: + // Ignore keyboard input if the control is disabled + if ((int)msg.wParam == (int)Win32.VirtualKeys.VK_MENU) + { + if (_trackItem != -1) + { + // Is it also showing a submenu + if (_popupMenu == null) + { + // Unselect the current item + _trackItem = SwitchTrackingItem(_trackItem, -1); + } + } + + SimulateReturnFocus(); + + // Always eat keyboard message in simulated focus + eat = true; + } + break; + + case (int)Win32.Msgs.WM_SYSKEYDOWN: + if ((int)msg.wParam != (int)Win32.VirtualKeys.VK_MENU) + { + // Construct shortcut from ALT + keychar + Shortcut sc = (Shortcut)(0x00040000 + (int)msg.wParam); + + // Search for a matching command + if (!GenerateShortcut(sc, _menuCommands)) + { + // Last resort is treat as a potential mnemonic + ProcessMnemonicKey((char)msg.wParam); + + if (_selected) + _ignoreMouseMove = true; + } + else + { + SimulateReturnFocus(); + } + + // Always eat keyboard message in simulated focus + eat = true; + } + break; + + default: + break; + } + + return eat; + } + */ + + protected bool GenerateShortcut(Shortcut sc, MenuCommandCollection mcc) + { + foreach (MenuCommand mc in mcc) + { + // Does the command match? + if (mc.Enabled && (mc.Shortcut == sc)) + { + // Generate event for command + mc.OnClick(EventArgs.Empty); + + return true; + } + else + { + // Any child items to test? + if (mc.MenuCommands.Count > 0) + { + // Recursive descent of all collections + if (GenerateShortcut(sc, mc.MenuCommands)) + return true; + } + } + } + + return false; + } + + protected void OnWM_OPERATEMENU(ref Message m) + { + // Is there a valid item being tracted? + if (_trackItem != -1) + { + DrawCommand dc = _drawCommands[_trackItem] as DrawCommand; + + OperateSubMenu(dc, (m.LParam != IntPtr.Zero), (m.WParam != IntPtr.Zero)); + } + } + + protected void OnWM_GETDLGCODE(ref Message m) + { + // We want to the Form to provide all keyboard input to us + m.Result = (IntPtr)Win32.DialogCodes.DLGC_WANTALLKEYS; + } + + protected override void WndProc(ref Message m) + { + // WM_OPERATEMENU is not a constant and so cannot be in a switch + if (m.Msg == WM_OPERATEMENU) + OnWM_OPERATEMENU(ref m); + else + { + switch (m.Msg) + { + case (int)Win32.Msgs.WM_GETDLGCODE: + OnWM_GETDLGCODE(ref m); + return; + } + } + + base.WndProc(ref m); + } + } +} \ No newline at end of file diff --git a/Labyrinth3/Crownwood.Magic/Menus/MenuControl.resx b/Labyrinth3/Crownwood.Magic/Menus/MenuControl.resx new file mode 100644 index 0000000..7e32396 --- /dev/null +++ b/Labyrinth3/Crownwood.Magic/Menus/MenuControl.resx @@ -0,0 +1,42 @@ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + text/microsoft-resx + + + 1.0.0.0 + + + System.Resources.ResXResourceReader, System.Windows.Forms, Version=1.0.3102.0, Culture=neutral, PublicKeyToken=b77a5c561934e089 + + + System.Resources.ResXResourceWriter, System.Windows.Forms, Version=1.0.3102.0, Culture=neutral, PublicKeyToken=b77a5c561934e089 + + diff --git a/Labyrinth3/Crownwood.Magic/Menus/MenuControlDesigner.cs b/Labyrinth3/Crownwood.Magic/Menus/MenuControlDesigner.cs new file mode 100644 index 0000000..3bd04cc --- /dev/null +++ b/Labyrinth3/Crownwood.Magic/Menus/MenuControlDesigner.cs @@ -0,0 +1,34 @@ +// ***************************************************************************** +// +// (c) Crownwood Consulting Limited 2002-2003 +// All rights reserved. The software and associated documentation +// supplied hereunder are the proprietary information of Crownwood Consulting +// Limited, Crownwood, Bracknell, Berkshire, England and are supplied subject +// to licence terms. +// +// Magic Version 1.7.4.0 www.dotnetmagic.com +// ***************************************************************************** + +using System.Collections; + +namespace Crownwood.Magic.Menus +{ + public class MenuControlDesigner : System.Windows.Forms.Design.ParentControlDesigner + { + public override ICollection AssociatedComponents + { + get + { + if (base.Control is Crownwood.Magic.Menus.MenuControl) + return ((Crownwood.Magic.Menus.MenuControl)base.Control).MenuCommands; + else + return base.AssociatedComponents; + } + } + + protected override bool DrawGrid + { + get { return false; } + } + } +} \ No newline at end of file diff --git a/Labyrinth3/Crownwood.Magic/Menus/PopupMenu.cs b/Labyrinth3/Crownwood.Magic/Menus/PopupMenu.cs new file mode 100644 index 0000000..e687df2 --- /dev/null +++ b/Labyrinth3/Crownwood.Magic/Menus/PopupMenu.cs @@ -0,0 +1,3519 @@ +// ***************************************************************************** +// +// (c) Crownwood Consulting Limited 2002-2003 +// All rights reserved. The software and associated documentation +// supplied hereunder are the proprietary information of Crownwood Consulting +// Limited, Crownwood, Bracknell, Berkshire, England and are supplied subject +// to licence terms. +// +// Magic Version 1.7.4.0 www.dotnetmagic.com +// ***************************************************************************** + +using Crownwood.Magic.Collections; + +//using Crownwood.Magic.Win32; +using Crownwood.Magic.Common; +using System; +using System.Collections; +using System.ComponentModel; +using System.Drawing; +using System.Drawing.Drawing2D; +using System.Drawing.Imaging; +using System.Drawing.Text; +using System.Windows.Forms; + +namespace Crownwood.Magic.Menus +{ + [ToolboxItem(false)] + [DefaultProperty("MenuCommands")] + public class PopupMenu : NativeWindow + { + // Enumeration of Indexes into positioning constants array + protected enum PI + { + BorderTop = 0, + BorderLeft = 1, + BorderBottom = 2, + BorderRight = 3, + ImageGapTop = 4, + ImageGapLeft = 5, + ImageGapBottom = 6, + ImageGapRight = 7, + TextGapLeft = 8, + TextGapRight = 9, + SubMenuGapLeft = 10, + SubMenuWidth = 11, + SubMenuGapRight = 12, + SeparatorHeight = 13, + SeparatorWidth = 14, + ShortcutGap = 15, + ShadowWidth = 16, + ShadowHeight = 17, + ExtraWidthGap = 18, + ExtraHeightGap = 19, + ExtraRightGap = 20, + ExtraReduce = 21 + } + + // Class constants for sizing/positioning each style + protected static readonly int[,] _position = { + {2, 1, 0, 1, 2, 3, 3, 5, 4, 4, 2, 6, 5, 5, 1, 10, 4, 4, 2, 2, 0, 0}, // IDE + {1, 0, 1, 2, 2, 1, 3, 4, 3, 3, 2, 8, 5, 5, 5, 10, 0, 0, 2, 2, 2, 5} // Plain + }; + + // Other class constants + protected static int _selectionDelay = 400; + + protected static int _expansionDelay = 1100; + protected static int _imageWidth = 16; + protected static int _imageHeight = 16; + protected static int _shadowLength = 4; + protected static int _shadowHalf = 2; + protected static int _blendSteps = 6; + protected static Bitmap _shadowCache = null; + protected static int _shadowCacheWidth = 0; + protected static int _shadowCacheHeight = 0; + + // Class fields + protected static ImageList _menuImages = null; + + protected static bool _supportsLayered = false; + + // Indexes into the menu images strip + protected enum ImageIndex + { + Check = 0, + Radio = 1, + SubMenu = 2, + CheckSelected = 3, + RadioSelected = 4, + SubMenuSelected = 5, + Expansion = 6, + ImageError = 7 + } + + // Operation of DrawShadowHorizontal + protected enum Shadow + { + Left, + Right, + All + } + + // Class constants that are marked as 'readonly' are allowed computed initialization + protected readonly int WM_DISMISS = (int)Win32.Msgs.WM_USER + 1; + + protected readonly int WM_OPERATE_SUBMENU = (int)Win32.Msgs.WM_USER + 2; + + // Instance fields + protected Timer _timer; + + protected Font _textFont; + protected int _popupItem; + protected int _trackItem; + protected int _borderGap; + protected int _returnDir; + protected int _extraSize; + protected int _excludeOffset; + protected int _animateTime; + protected bool _animateFirst; + protected bool _animateIn; + protected bool _layered; + protected bool _exitLoop; + protected bool _mouseOver; + protected bool _popupDown; + protected bool _popupRight; + protected bool _excludeTop; + protected bool _showInfrequent; + protected bool _rememberExpansion; + protected bool _highlightInfrequent; + protected Color _backColor; + protected Color _textColor; + protected Color _highlightTextColor; + protected Color _highlightColor; + protected Color _highlightColorDark; + protected Color _highlightColorLight; + protected Color _highlightColorLightLight; + protected Color _controlLL; + protected Color _controlLLight; + protected Size _currentSize; + protected VisualStyle _style; + protected Point _screenPos; + protected Point _lastMousePos; + protected Point _currentPoint; + protected Point _leftScreenPos; + protected Point _aboveScreenPos; + protected Direction _direction; + protected PopupMenu _parentMenu; + protected PopupMenu _childMenu; + protected SolidBrush _controlLBrush; + protected SolidBrush _controlEBrush; + protected SolidBrush _controlLLBrush; + protected Animate _animate; + protected Animate _animateTrack; + protected Animation _animateStyle; + protected ArrayList _drawCommands; + protected MenuControl _parentControl; + protected MenuCommand _returnCommand; + protected MenuCommandCollection _menuCommands; + + // Instance fields - events + public event CommandHandler Selected; + + public event CommandHandler Deselected; + + static PopupMenu() + { + // Create a strip of images by loading an embedded bitmap resource + _menuImages = ResourceHelper.LoadBitmapStrip(Type.GetType("Crownwood.Magic.Menus.PopupMenu"), + "Crownwood.Magic.Resources.ImagesPopupMenu.bmp", + new Size(16, 16), + new Point(0, 0)); + + // We need to know if the OS supports layered windows + _supportsLayered = (OSFeature.Feature.GetVersionPresent(OSFeature.LayeredWindows) != null); + } + + public PopupMenu() + { + // Create collection objects + _drawCommands = new ArrayList(); + _menuCommands = new MenuCommandCollection(); + + // Default the properties + _returnDir = 0; + _extraSize = 0; + _popupItem = -1; + _trackItem = -1; + _childMenu = null; + _exitLoop = false; + _popupDown = true; + _mouseOver = false; + _excludeTop = true; + _popupRight = true; + _parentMenu = null; + _excludeOffset = 0; + _parentControl = null; + _returnCommand = null; + _controlLBrush = null; + _controlEBrush = null; + _controlLLBrush = null; + _highlightInfrequent = false; + _showInfrequent = false; + _style = VisualStyle.IDE; + _rememberExpansion = true; + _lastMousePos = new Point(-1, -1); + _direction = Direction.Horizontal; + _textFont = SystemInformation.MenuFont; + + // Animation details + _animateTime = 100; + _animate = Animate.System; + _animateStyle = Animation.System; + _animateFirst = true; + _animateIn = true; + + // Create and initialise the timer object (but do not start it running!) + _timer = new Timer(); + _timer.Interval = _selectionDelay; + _timer.Tick += new EventHandler(OnTimerExpire); + + // Define default colors + _textColor = SystemColors.MenuText; + _highlightTextColor = SystemColors.HighlightText; + DefineHighlightColors(SystemColors.Highlight); + DefineColors(SystemColors.Control); + } + + [Category("Appearance")] + [DesignerSerializationVisibility(DesignerSerializationVisibility.Content)] + public MenuCommandCollection MenuCommands + { + get { return _menuCommands; } + } + + [Category("Appearance")] + [DefaultValue(typeof(VisualStyle), "IDE")] + public VisualStyle Style + { + get { return _style; } + set { _style = value; } + } + + [Category("Appearance")] + public Font Font + { + get { return _textFont; } + set { _textFont = value; } + } + + [Category("Behaviour")] + [DefaultValue(false)] + public bool ShowInfrequent + { + get { return _showInfrequent; } + set { _showInfrequent = value; } + } + + [Category("Behaviour")] + [DefaultValue(true)] + public bool RememberExpansion + { + get { return _rememberExpansion; } + set { _rememberExpansion = value; } + } + + [Category("Behaviour")] + [DefaultValue(true)] + public bool HighlightInfrequent + { + get { return _highlightInfrequent; } + set { _highlightInfrequent = value; } + } + + [Category("Behaviour")] + public Color BackColor + { + get { return _backColor; } + set { DefineColors(value); } + } + + [Category("Behaviour")] + public Color TextColor + { + get { return _textColor; } + set { _textColor = value; } + } + + [Category("Behaviour")] + public Color HighlightTextColor + { + get { return _highlightTextColor; } + set { _highlightTextColor = value; } + } + + [Category("Behaviour")] + public Color HighlightColor + { + get { return _highlightColor; } + set { DefineHighlightColors(value); } + } + + [Category("Animate")] + [DefaultValue(typeof(Animate), "System")] + public Animate Animate + { + get { return _animate; } + set { _animate = value; } + } + + [Category("AnimateTime")] + public int AnimateTime + { + get { return _animateTime; } + set { _animateTime = value; } + } + + [Category("AnimateStyle")] + public Animation AnimateStyle + { + get { return _animateStyle; } + set { _animateStyle = value; } + } + + public MenuCommand TrackPopup(Point screenPos) + { + return TrackPopup(screenPos, false); + } + + public MenuCommand TrackPopup(Point screenPos, bool selectFirst) + { + // No point in showing PopupMenu if there are no entries + if (_menuCommands.VisibleItems()) + { + // Default the drawing direction + _direction = Direction.Horizontal; + + // Remember screen positions + _screenPos = screenPos; + _aboveScreenPos = screenPos; + _leftScreenPos = screenPos; + + return InternalTrackPopup(selectFirst); + } + + return null; + } + + internal MenuCommand TrackPopup(Point screenPos, + Point aboveScreenPos, + Direction direction, + MenuCommandCollection menuCollection, + int borderGap, + bool selectFirst, + MenuControl parentControl, + bool animateIn, + ref int returnDir) + { + // Remember which direction the MenuControl is drawing in + _direction = direction; + + // Remember the MenuControl that initiated us + _parentControl = parentControl; + + // Remember the gap in drawing the top border + _borderGap = borderGap; + + // Is this the first time a menu at this level has been animated + _animateIn = animateIn; + + // Remember any currect menu item collection + MenuCommandCollection oldCollection = _menuCommands; + + // Use the passed in collection of menu commands + _menuCommands = menuCollection; + + // Remember screen positions + _screenPos = screenPos; + _aboveScreenPos = aboveScreenPos; + _leftScreenPos = screenPos; + + MenuCommand ret = InternalTrackPopup(selectFirst); + + // Restore to original collection + _menuCommands = oldCollection; + + // Remove reference no longer required + _parentControl = null; + + // Return the direction key that caused dismissal + returnDir = _returnDir; + + return ret; + } + + protected MenuCommand InternalTrackPopup(Point screenPosTR, + Point screenPosTL, + MenuCommandCollection menuCollection, + PopupMenu parentMenu, + bool selectFirst, + MenuControl parentControl, + bool popupRight, + bool popupDown, + bool animateIn, + ref int returnDir) + { + // Default the drawing direction + _direction = Direction.Horizontal; + + // Remember the MenuControl that initiated us + _parentControl = parentControl; + + // We have a parent popup menu that should be consulted about operation + _parentMenu = parentMenu; + + // Is this the first time a menu at this level has been animated + _animateIn = animateIn; + + // Remember any currect menu item collection + MenuCommandCollection oldCollection = _menuCommands; + + // Use the passed in collection of menu commands + _menuCommands = menuCollection; + + // Remember screen positions + _screenPos = screenPosTR; + _aboveScreenPos = screenPosTR; + _leftScreenPos = screenPosTL; + + // Remember display directions + _popupRight = popupRight; + _popupDown = popupDown; + + MenuCommand ret = InternalTrackPopup(selectFirst); + + // Restore to original collection + _menuCommands = oldCollection; + + // Remove references no longer required + _parentControl = null; + _parentMenu = null; + + // Return the direction key that caused dismissal + returnDir = _returnDir; + + return ret; + } + + protected MenuCommand InternalTrackPopup(bool selectFirst) + { + return null; + /* + try + { + // MenuCommand to return as method result + _returnCommand = null; + + // No item is being tracked + _trackItem = -1; + + // Flag to indicate when to exit the message loop + _exitLoop = false; + + // Assume the mouse does not start over our window + _mouseOver = false; + + // Direction of key press if this caused dismissal + _returnDir = 0; + + // Flag to indicate if the message should be dispatched + bool leaveMsg = false; + + // First time a submenu is shown we pass in our value + _animateFirst = true; + + // Create and show the popup window (without taking the focus) + CreateAndShowWindow(); + + // Create an object for storing windows message information + Win32.MSG msg = new Win32.MSG(); + + // Pretend user pressed key down to get the first valid item selected + if (selectFirst) + ProcessKeyDown(); + + // Always use the arrow cursor + User32.SetCursor(User32.LoadCursor(IntPtr.Zero, (uint)Win32.Cursors.IDC_ARROW)); + + // Must hide caret so user thinks focus has changed + bool hideCaret = User32.HideCaret(IntPtr.Zero); + + // Process messages until exit condition recognised + while(!_exitLoop) + { + // Suspend thread until a windows message has arrived + if (User32.WaitMessage()) + { + // Take a peek at the message details without removing from queue + while(!_exitLoop && User32.PeekMessage(ref msg, 0, 0, 0, (int)Win32.PeekMessageFlags.PM_NOREMOVE)) + { + // Console.WriteLine("Track {0} {1}", this.Handle, ((Win32.Msgs)msg.message).ToString()); + + bool eatMessage = false; + + int localWidth = _currentSize.Width - _position[(int)_style, (int)PI.ShadowWidth]; + int localHeight = _currentSize.Height - _position[(int)_style, (int)PI.ShadowHeight]; + + // Mouse was pressed in a window of this application + if ((msg.message == (int)Win32.Msgs.WM_LBUTTONUP) || + (msg.message == (int)Win32.Msgs.WM_MBUTTONUP) || + (msg.message == (int)Win32.Msgs.WM_RBUTTONUP) || + (msg.message == (int)Win32.Msgs.WM_XBUTTONUP) || + (msg.message == (int)Win32.Msgs.WM_NCLBUTTONUP) || + (msg.message == (int)Win32.Msgs.WM_NCMBUTTONUP) || + (msg.message == (int)Win32.Msgs.WM_NCRBUTTONUP) || + (msg.message == (int)Win32.Msgs.WM_NCXBUTTONUP)) + { + Win32.POINT screenPos = MousePositionToScreen(msg); + + // Is the POINT inside the Popup window rectangle + if ((screenPos.x >= _currentPoint.X) && (screenPos.x <= (_currentPoint.X + localWidth)) && + (screenPos.y >= _currentPoint.Y) && (screenPos.y <= (_currentPoint.Y + localHeight))) + { + OnWM_YBUTTONUP(screenPos.x, screenPos.y); + + // Eat the message to prevent the intended destination getting it + eatMessage = true; + } + else + { + PopupMenu target = ParentPopupMenuWantsMouseMessage(screenPos, ref msg); + + // Let the parent chain of PopupMenu's decide if they want it + if (target != null) + { + target.OnWM_YBUTTONUP(screenPos.x, screenPos.y); + + // Eat the message to prevent the intended destination getting it + eatMessage = true; + } + } + } + + // Mouse was pressed in a window of this application + if ((msg.message == (int)Win32.Msgs.WM_LBUTTONDOWN) || + (msg.message == (int)Win32.Msgs.WM_MBUTTONDOWN) || + (msg.message == (int)Win32.Msgs.WM_RBUTTONDOWN) || + (msg.message == (int)Win32.Msgs.WM_XBUTTONDOWN) || + (msg.message == (int)Win32.Msgs.WM_NCLBUTTONDOWN) || + (msg.message == (int)Win32.Msgs.WM_NCMBUTTONDOWN) || + (msg.message == (int)Win32.Msgs.WM_NCRBUTTONDOWN) || + (msg.message == (int)Win32.Msgs.WM_NCXBUTTONDOWN)) + { + Win32.POINT screenPos = MousePositionToScreen(msg); + + // Is the POINT inside the Popup window rectangle + if ((screenPos.x >= _currentPoint.X) && (screenPos.x <= (_currentPoint.X + localWidth)) && + (screenPos.y >= _currentPoint.Y) && (screenPos.y <= (_currentPoint.Y + localHeight))) + { + // Eat the message to prevent the intended destination getting it + eatMessage = true; + } + else + { + // Let the parent chain of PopupMenu's decide if they want it + if (ParentPopupMenuWantsMouseMessage(screenPos, ref msg) == null) + { + if (ParentControlWantsMouseMessage(screenPos, ref msg)) + { + // Let the MenuControl do its business + _parentControl.OnWM_MOUSEDOWN(screenPos); + + // Eat the message to prevent the intended destination getting it + eatMessage = true; + } + else + { + // No, then we need to exit the popup menu tracking + _exitLoop = true; + + // DO NOT process the message, leave it on the queue + // and let the real destination window handle it. + leaveMsg = true; + + // Is a parent control specified? + if (_parentControl != null) + { + // Is the mouse event destination the parent control? + if (msg.hwnd == _parentControl.Handle) + { + // Then we want to consume the message so it does not get processed + // by the parent control. Otherwise, pressing down will cause this + // popup to disappear but the message will then get processed by + // the parent and cause a popup to reappear again. When we actually + // want the popup to disappear and nothing more. + leaveMsg = false; + } + } + } + } + else + { + // Eat the message to prevent the intended destination getting it + eatMessage = true; + } + } + } + + // Mouse move occured + if (msg.message == (int)Win32.Msgs.WM_MOUSEMOVE) + { + Win32.POINT screenPos = MousePositionToScreen(msg); + + // Is the POINT inside the Popup window rectangle + if ((screenPos.x >= _currentPoint.X) && (screenPos.x <= (_currentPoint.X + localWidth)) && + (screenPos.y >= _currentPoint.Y) && (screenPos.y <= (_currentPoint.Y + localHeight))) + { + OnWM_MOUSEMOVE(screenPos.x, screenPos.y); + } + else + { + // Do we still think the mouse is over our window? + if (_mouseOver) + { + // Process mouse leaving situation + OnWM_MOUSELEAVE(); + } + + // Let the parent chain of PopupMenu's decide if they want it + PopupMenu target = ParentPopupMenuWantsMouseMessage(screenPos, ref msg); + + if (target != null) + { + // Let parent target process the message + target.OnWM_MOUSEMOVE(screenPos.x, screenPos.y); + } + else + { + if (ParentControlWantsMouseMessage(screenPos, ref msg)) + { + // Let the MenuControl do its business + _parentControl.OnWM_MOUSEMOVE(screenPos); + } + } + } + + // Eat the message to prevent the intended destination getting it + eatMessage = true; + } + + if (msg.message == (int)Win32.Msgs.WM_SETCURSOR) + { + OnWM_SETCURSOR(); + + // Eat the message to prevent the intended destination getting it + eatMessage = true; + } + + // Was the alt key pressed? + if (msg.message == (int)Win32.Msgs.WM_SYSKEYDOWN) + { + // Alt key pressed on its own + if((int)msg.wParam == (int)Win32.VirtualKeys.VK_MENU) // ALT key + { + // Then we should dimiss ourself + _exitLoop = true; + } + else + { + // Pretend it is a normal keypress for processing + msg.message = (int)Win32.Msgs.WM_KEYDOWN; + } + } + + // Was a non-alt key pressed? + if (msg.message == (int)Win32.Msgs.WM_KEYDOWN) + { + switch((int)msg.wParam) + { + case (int)Win32.VirtualKeys.VK_UP: + ProcessKeyUp(); + break; + + case (int)Win32.VirtualKeys.VK_DOWN: + ProcessKeyDown(); + break; + + case (int)Win32.VirtualKeys.VK_LEFT: + ProcessKeyLeft(); + break; + + case (int)Win32.VirtualKeys.VK_RIGHT: + if(ProcessKeyRight()) + { + // Do not attempt to pull a message off the queue as the + // ProcessKeyRight has eaten the message for us + leaveMsg = true; + } + break; + + case (int)Win32.VirtualKeys.VK_RETURN: + // Is an item currently selected + if (_trackItem != -1) + { + DrawCommand dc = _drawCommands[_trackItem] as DrawCommand; + + // Does this item have a submenu? + if (dc.SubMenu) + { + // Handle the submenu + OperateSubMenu(_trackItem, false); + + // Do not attempt to pull a message off the queue as it has already + // been eaten by us in the above code + leaveMsg = true; + } + else + { + // Is this item the expansion command? + if (dc.Expansion) + { + RegenerateExpansion(); + } + else + { + // Define the selection to return to caller + _returnCommand = dc.MenuCommand; + + // Finish processing messages + _exitLoop = true; + } + } + } + break; + + case (int)Win32.VirtualKeys.VK_ESCAPE: + // User wants to exit the menu, so set the flag to exit the message loop but + // let the message get processed. This way the key press is thrown away. + _exitLoop = true; + break; + + default: + // Any other key is treated as a possible mnemonic + int selectItem = ProcessMnemonicKey((char)msg.wParam); + + if (selectItem != -1) + { + DrawCommand dc = _drawCommands[selectItem] as DrawCommand; + + // Define the selection to return to caller + _returnCommand = dc.MenuCommand; + + // Finish processing messages + _exitLoop = true; + + // Do not attempt to pull a message off the queue as it has already + // been eaten by us in the above code + leaveMsg = true; + } + break; + } + } + + // We consume all keyboard input + if ((msg.message == (int)Win32.Msgs.WM_KEYDOWN) || + (msg.message == (int)Win32.Msgs.WM_KEYUP) || + (msg.message == (int)Win32.Msgs.WM_SYSKEYDOWN) || + (msg.message == (int)Win32.Msgs.WM_SYSKEYUP)) + { + // Eat the message to prevent the intended destination getting it + eatMessage = true; + } + + // Should the message be eaten to prevent intended destination getting it? + if (eatMessage) + { + Win32.MSG eat = new Win32.MSG(); + User32.GetMessage(ref eat, 0, 0, 0); + } + else + { + // Should the message we pulled from the queue? + if (!leaveMsg) + { + if (User32.GetMessage(ref msg, 0, 0, 0)) + { + User32.TranslateMessage(ref msg); + User32.DispatchMessage(ref msg); + } + } + else + leaveMsg = false; + } + } + } + } + + // If caret was hidden then show it again now + if (hideCaret) + User32.ShowCaret(IntPtr.Zero); + + // Remove tracking of any item, this ensure 'Deselected' event is generated if required + SwitchSelection(_trackItem, -1, false, false); + + // Hide the window from view before killing it, as sometimes there is a + // short delay between killing it and it disappearing because of the time + // it takes for the destroy messages to get processed + HideMenuWindow(); + + // Commit suicide + DestroyHandle(); + + // Was a command actually selected in a top level PopupMenu AND we + // are not here at the request of a MenuControl + if ((_parentMenu == null) && (_returnCommand != null) && (_parentControl == null)) + { + // Pulse the selected event for the command + _returnCommand.OnClick(EventArgs.Empty); + } + + return _returnCommand; + } + catch(Exception) + { + return null; + } + */ + } + + public void Dismiss() + { + if (this.Handle != IntPtr.Zero) + { + // Prevent the timer from expiring + _timer.Stop(); + + // Kill any child menu + if (_childMenu != null) + _childMenu.Dismiss(); + + // Finish processing messages + _exitLoop = true; + + // Hide ourself + HideMenuWindow(); + + // Cause our own message loop to exit + //User32.PostMessage(this.Handle, WM_DISMISS, 0, 0); + } + } + + protected void HideMenuWindow() + { + //User32.ShowWindow(this.Handle, (short)Win32.ShowWindowStyles.SW_HIDE); + } + + protected void ManualAnimateBlend(bool show) + { + // Set the image to be completely transparent so the following command + // to show the window does not actual show anything. + UpdateLayeredWindow(0); + + // Show the window without activating it (i.e. do not take focus) + //User32.ShowWindow(this.Handle, (short)Win32.ShowWindowStyles.SW_SHOWNOACTIVATE); + + int stepDelay = (int)(_animateTime / _blendSteps); + + for (int i = 0; i < _blendSteps; i++) + { + // Calculate increasing values of opaqueness + byte alpha = (byte)(63 + (192 / _blendSteps * (i + 1))); + + DateTime beforeTime = DateTime.Now; + + // Update the image for display + UpdateLayeredWindow(alpha); + + DateTime afterTime = DateTime.Now; + + // Need to subtract elapsed time from required step delay + TimeSpan elapsed = afterTime.Subtract(beforeTime); + + // Short delay before showing next frame, but test if delay is actually needed + // because sometimes the time to update layered window is longer than delay + if ((_animateTime > 0) && (elapsed.Milliseconds < stepDelay)) + System.Threading.Thread.Sleep(stepDelay - elapsed.Milliseconds); + } + } + + protected void CreateAndShowWindow() + { + // Decide if we need layered windows + _layered = (_supportsLayered && (_style == VisualStyle.IDE)); + + // Process the menu commands to determine where each one needs to be + // drawn and return the size of the window needed to display it. + Size winSize = GenerateDrawPositions(); + + Point screenPos = CorrectPositionForScreen(winSize); + + // Special case, if there are no menu options to show then show nothing by + // making the window 0,0 in size. + if (_menuCommands.Count == 0) + winSize = new Size(0, 0); + + CreateParams cp = new CreateParams(); + + // Any old title will do as it will not be shown + cp.Caption = "NativePopupMenu"; + + // Define the screen position/size + cp.X = screenPos.X; + cp.Y = screenPos.Y; + cp.Height = winSize.Height; + cp.Width = winSize.Width; + + // As a top-level window it has no parent + cp.Parent = IntPtr.Zero; + + // Appear as a top-level window + cp.Style = unchecked((int)(uint)Win32.WindowStyles.WS_POPUP); + + // Set styles so that it does not have a caption bar and is above all other + // windows in the ZOrder, i.e. TOPMOST + cp.ExStyle = (int)Win32.WindowExStyles.WS_EX_TOPMOST + + (int)Win32.WindowExStyles.WS_EX_TOOLWINDOW; + + // OS specific style + if (_layered) + { + // If not on NT then we are going to use alpha blending on the shadow border + // and so we need to specify the layered window style so the OS can handle it + cp.ExStyle += (int)Win32.WindowExStyles.WS_EX_LAYERED; + } + + // Is this the plain style of appearance? + if (_style == VisualStyle.Plain) + { + // We want the tradiditonal 3D border + cp.Style += unchecked((int)(uint)Win32.WindowStyles.WS_DLGFRAME); + } + + // Create the actual window + this.CreateHandle(cp); + + // Update the window clipping region + if (!_layered) + SetWindowRegion(winSize); + + // Remember the correct screen drawing details + _currentSize = winSize; + _currentPoint = screenPos; + + bool animated = false; + + if (_layered) + { + // Update the image for display + UpdateLayeredWindow(); + + bool animate = false; + + switch (_animate) + { + case Animate.No: + animate = false; + break; + + case Animate.Yes: + animate = true; + break; + + case Animate.System: + int bRetValue = 0; + + // Does the system want animation to occur? + //User32.SystemParametersInfo((uint)Win32.SPIActions.SPI_GETMENUANIMATION, 0, ref bRetValue, 0); + + animate = (bRetValue != 0); + break; + } + + // Should the menu be shown with animation? + if (animate && _animateIn) + { + uint animateFlags = (uint)_animateStyle; + + if (_animateStyle == Animation.System) + { + int bRetValue = 0; + + // Does the system want fading or sliding? + //User32.SystemParametersInfo((uint)Win32.SPIActions.SPI_GETMENUFADE, 0, ref bRetValue, 0); + + // Use appropriate flags to match request + if (bRetValue != 0) + animateFlags = (uint)Animation.Blend; + else + animateFlags = (uint)Animation.SlideHorVerPositive; + } + + // Animate the appearance of the window + if ((animateFlags & (uint)Win32.AnimateFlags.AW_BLEND) != 0) + { + // Cannot use Win32.AnimateWindow to blend a layered window + ManualAnimateBlend(true); + } + else + { + // Animate the appearance of the window + //User32.AnimateWindow(this.Handle, (uint)_animateTime, animateFlags); + } + + animated = true; + } + } + + // Did any animation take place? + if (!animated) + { + // Show the window without activating it (i.e. do not take focus) + //User32.ShowWindow(this.Handle, (short)Win32.ShowWindowStyles.SW_SHOWNOACTIVATE); + } + } + + protected void UpdateLayeredWindow() + { + UpdateLayeredWindow(_currentPoint, _currentSize, 255); + } + + protected void UpdateLayeredWindow(byte alpha) + { + UpdateLayeredWindow(_currentPoint, _currentSize, alpha); + } + + protected void UpdateLayeredWindow(Point point, Size size, byte alpha) + { + /* + // Create bitmap for drawing onto + Bitmap memoryBitmap = new Bitmap(size.Width, size.Height, PixelFormat.Format32bppArgb); + + using(Graphics g = Graphics.FromImage(memoryBitmap)) + { + Rectangle area = new Rectangle(0, 0, size.Width, size.Height); + + // Draw the background area + DrawBackground(g, area); + + // Draw the actual menu items + DrawAllCommands(g); + + // Get hold of the screen DC + IntPtr hDC = User32.GetDC(IntPtr.Zero); + + // Create a memory based DC compatible with the screen DC + IntPtr memoryDC = Gdi32.CreateCompatibleDC(hDC); + + // Get access to the bitmap handle contained in the Bitmap object + IntPtr hBitmap = memoryBitmap.GetHbitmap(Color.FromArgb(0)); + + // Select this bitmap for updating the window presentation + IntPtr oldBitmap = Gdi32.SelectObject(memoryDC, hBitmap); + + // New window size + Win32.SIZE ulwsize; + ulwsize.cx = size.Width; + ulwsize.cy = size.Height; + + // New window position + Win32.POINT topPos; + topPos.x = point.X; + topPos.y = point.Y; + + // Offset into memory bitmap is always zero + Win32.POINT pointSource; + pointSource.x = 0; + pointSource.y = 0; + + // We want to make the entire bitmap opaque + Win32.BLENDFUNCTION blend = new Win32.BLENDFUNCTION(); + blend.BlendOp = (byte)Win32.AlphaFlags.AC_SRC_OVER; + blend.BlendFlags = 0; + blend.SourceConstantAlpha = alpha; + blend.AlphaFormat = (byte)Win32.AlphaFlags.AC_SRC_ALPHA; + + // Tell operating system to use our bitmap for painting + User32.UpdateLayeredWindow(Handle, hDC, ref topPos, ref ulwsize, + memoryDC, ref pointSource, 0, ref blend, + (int)Win32.UpdateLayeredWindowsFlags.ULW_ALPHA); + + // Put back the old bitmap handle + Gdi32.SelectObject(memoryDC, oldBitmap); + + // Cleanup resources + User32.ReleaseDC(IntPtr.Zero, hDC); + Gdi32.DeleteObject(hBitmap); + Gdi32.DeleteDC(memoryDC); + } + */ + } + + protected void SetWindowRegion(Size winSize) + { + // Style specific handling + if (_style == VisualStyle.IDE) + { + int shadowHeight = _position[(int)_style, (int)PI.ShadowHeight]; + int shadowWidth = _position[(int)_style, (int)PI.ShadowWidth]; + + // Create a new region object + Region drawRegion = new Region(); + + // Can draw anywhere + drawRegion.MakeInfinite(); + + // Remove the area above the right hand shadow + drawRegion.Xor(new Rectangle(winSize.Width - shadowWidth, 0, shadowWidth, shadowHeight)); + + // When drawing upwards from a vertical menu we need to allow a connection between the + // MenuControl selection box and the PopupMenu shadow + if (!((_direction == Direction.Vertical) && !_excludeTop)) + { + // Remove the area left of the bottom shadow + drawRegion.Xor(new Rectangle(0, winSize.Height - shadowHeight, shadowWidth, shadowHeight)); + } + + // Define a region to prevent drawing over exposed corners of shadows + //using(Graphics g = Graphics.FromHwnd(this.Handle)) + // User32.SetWindowRgn(this.Handle, drawRegion.GetHrgn(g), false); + } + } + + protected Point CorrectPositionForScreen(Size winSize) + { + Rectangle screenRect = Screen.GetWorkingArea(_screenPos); + Point screenPos = _screenPos; + + int screenWidth = screenRect.Width; + int screenLeft = screenRect.Left; + int screenRight = screenRect.Right; + int screenHeight = screenRect.Height; + int screenBottom = screenRect.Bottom; + int screenTop = screenRect.Top; + + // Default to excluding menu border from top + _excludeTop = true; + _excludeOffset = 0; + + // Shadow area does not count as part of width + winSize.Width -= _position[(int)_style, (int)PI.ShadowWidth]; + + // Calculate the downward position first + if (_popupDown) + { + // Ensure the end of the menu is not off the bottom of the screen + if ((screenPos.Y + winSize.Height) > screenBottom) + { + // If the parent control exists then try and position upwards instead + if ((_parentControl != null) && (_parentMenu == null)) + { + // Is there space above the required position? + if ((_aboveScreenPos.Y - winSize.Height) > screenTop) + { + // Great...do that instead + screenPos.Y = _aboveScreenPos.Y - winSize.Height; + + // Reverse direction of drawing this and submenus + _popupDown = false; + + // Remember to exclude border from bottom of menu and not the top + _excludeTop = false; + + // Inform parent it needs to redraw the selection upwards + _parentControl.DrawSelectionUpwards(); + } + } + + // Did the above logic still fail? + if ((screenPos.Y + winSize.Height) > screenBottom) + { + // If not a top level PopupMenu then.. + if (_parentMenu != null) + { + // Reverse direction of drawing this and submenus + _popupDown = false; + + // Is there space above the required position? + if ((_aboveScreenPos.Y - winSize.Height) > screenTop) + screenPos.Y = _aboveScreenPos.Y - winSize.Height; + else + screenPos.Y = screenTop; + } + else + screenPos.Y = screenBottom - winSize.Height - 1; + } + } + } + else + { + // Ensure the end of the menu is not off the top of the screen + if ((screenPos.Y - winSize.Height) < screenTop) + { + // Reverse direction + _popupDown = true; + + // Is there space below the required position? + if ((screenPos.Y + winSize.Height) > screenBottom) + screenPos.Y = screenBottom - winSize.Height - 1; + } + else + screenPos.Y -= winSize.Height; + } + + // Calculate the across position next + if (_popupRight) + { + // Ensure that right edge of menu is not off right edge of screen + if ((screenPos.X + winSize.Width) > screenRight) + { + // If not a top level PopupMenu then... + if (_parentMenu != null) + { + // Reverse direction + _popupRight = false; + + // Adjust across position + screenPos.X = _leftScreenPos.X - winSize.Width; + + if (screenPos.X < screenLeft) + screenPos.X = screenLeft; + } + else + { + // Find new position of X coordinate + int newX = screenRight - winSize.Width - 1; + + // Modify the adjust needed when drawing top/bottom border + _excludeOffset = screenPos.X - newX; + + // Use new position for popping up menu + screenPos.X = newX; + } + } + } + else + { + // Start by using the left screen pos instead + screenPos.X = _leftScreenPos.X; + + // Ensure the left edge of the menu is not off the left of the screen + if ((screenPos.X - winSize.Width) < screenLeft) + { + // Reverse direction + _popupRight = true; + + // Is there space below the required position? + if ((_screenPos.X + winSize.Width) > screenRight) + screenPos.X = screenRight - winSize.Width - 1; + else + screenPos.X = _screenPos.X; + } + else + screenPos.X -= winSize.Width; + } + + return screenPos; + } + + protected void RegenerateExpansion() + { + // Remove all existing draw commands + _drawCommands.Clear(); + + // Move into the expanded mode + _showInfrequent = true; + + // Show we remember the expansion to the collection? + if (_rememberExpansion) + _menuCommands.ShowInfrequent = true; + + // Generate new ones + Size newSize = GenerateDrawPositions(); + + // Find the new screen location for the window + Point newPos = CorrectPositionForScreen(newSize); + + // Remember the correct screen drawing details + _currentPoint = newPos; + _currentSize = newSize; + + // Update the window clipping region + if (!_layered) + { + SetWindowRegion(newSize); + + // Alter size and location of window + //User32.MoveWindow(this.Handle, newPos.X, newPos.Y, newSize.Width, newSize.Height, true); + + Win32.RECT clientRect = new Win32.RECT(); + + clientRect.left = 0; + clientRect.top = 0; + clientRect.right = newSize.Width; + clientRect.bottom = newSize.Height; + + // Get the client area redrawn after MoveWindow has been processed + //User32.InvalidateRect(this.Handle, ref clientRect, true); + } + else + { + // Update the image for display + UpdateLayeredWindow(); + + // Lets repaint everything + RefreshAllCommands(); + } + } + + protected Size GenerateDrawPositions() + { + return new Size(); + /* + // Create a collection of drawing objects + _drawCommands = new ArrayList(); + + // Calculate the minimum cell width and height + int cellMinHeight = _position[(int)_style, (int)PI.ImageGapTop] + + _imageHeight + + _position[(int)_style, (int)PI.ImageGapBottom]; + + int cellMinWidth = _position[(int)_style, (int)PI.ImageGapLeft] + + _imageWidth + + _position[(int)_style, (int)PI.ImageGapRight] + + _position[(int)_style, (int)PI.TextGapLeft] + + _position[(int)_style, (int)PI.TextGapRight] + + _position[(int)_style, (int)PI.SubMenuGapLeft] + + _position[(int)_style, (int)PI.SubMenuWidth] + + _position[(int)_style, (int)PI.SubMenuGapRight]; + + // Find cell height needed to draw text + int textHeight = _textFont.Height; + + // If height needs to be more to handle image then use image height + if (textHeight < cellMinHeight) + textHeight = cellMinHeight; + + // Make sure no column in the menu is taller than the screen + int screenHeight = SystemInformation.WorkingArea.Height; + + // Define the starting positions for calculating cells + int xStart = _position[(int)_style, (int)PI.BorderLeft]; + int yStart =_position[(int)_style, (int)PI.BorderTop]; + int yPosition = yStart; + + // Largest cell for column defaults to minimum cell width + int xColumnMaxWidth = cellMinWidth; + + int xPreviousColumnWidths = 0; + int xMaximumColumnHeight = 0; + + // Track the row/col of each cell + int row = 0; + int col = 0; + + // Are there any infrequent items + bool infrequent = false; + bool previousInfrequent = false; + + // Get hold of the DC for the desktop + IntPtr hDC = User32.GetDC(IntPtr.Zero); + + // Contains the collection of items in the current column + ArrayList columnItems = new ArrayList(); + + using(Graphics g = Graphics.FromHdc(hDC)) + { + // Handle any extra text drawing + if (_menuCommands.ExtraText.Length > 0) + { + // Calculate the column width needed to show this text + SizeF dimension = g.MeasureString(_menuCommands.ExtraText, _menuCommands.ExtraFont); + + // Always add 1 to ensure that rounding is up and not down + int extraHeight = (int)dimension.Height + 1; + + // Find the total required as the text requirement plus style specific spacers + _extraSize = extraHeight + + _position[(int)_style, (int)PI.ExtraRightGap] + + _position[(int)_style, (int)PI.ExtraWidthGap] * 2; + + // Push first column of items across from the extra text + xStart += _extraSize; + + // Add this extra width to the total width of the window + xPreviousColumnWidths = _extraSize; + } + + foreach(MenuCommand command in _menuCommands) + { + // Give the command a chance to update its state + command.OnUpdate(EventArgs.Empty); + + // Ignore items that are marked as hidden + if (!command.Visible) + continue; + + // If this command has menu items (and so it a submenu item) then check + // if any of the submenu items are visible. If none are visible then there + // is no point in showing this submenu item + if ((command.MenuCommands.Count > 0) && (!command.MenuCommands.VisibleItems())) + continue; + + // Ignore infrequent items unless flag set to show them + if (command.Infrequent && !_showInfrequent) + { + infrequent = true; + continue; + } + + int cellWidth = 0; + int cellHeight = 0; + + // Shift across to the next column? + if (command.Break) + { + // Move row/col tracking to the next column + row = 0; + col++; + + // Apply cell width to the current column entries + ApplySizeToColumnList(columnItems, xColumnMaxWidth); + + // Move cell position across to start of separator position + xStart += xColumnMaxWidth; + + // Get width of the separator area + int xSeparator = _position[(int)_style, (int)PI.SeparatorWidth]; + + DrawCommand dcSep = new DrawCommand(new Rectangle(xStart, 0, xSeparator, 0), false); + + // Add to list of items for drawing + _drawCommands.Add(dcSep); + + // Move over the separator + xStart += xSeparator; + + // Reset cell position to top of column + yPosition = yStart; + + // Accumulate total width of previous columns + xPreviousColumnWidths += xColumnMaxWidth + xSeparator; + + // Largest cell for column defaults to minimum cell width + xColumnMaxWidth = cellMinWidth; + } + + // Is this a horizontal separator? + if (command.Text == "-") + { + cellWidth = cellMinWidth; + cellHeight = _position[(int)_style, (int)PI.SeparatorHeight]; + } + else + { + // Use precalculated height + cellHeight = textHeight; + + // Calculate the text width portion of the cell + SizeF dimension = g.MeasureString(command.Text, _textFont); + + // Always add 1 to ensure that rounding is up and not down + cellWidth = cellMinWidth + (int)dimension.Width + 1; + + // Does the menu command have a shortcut defined? + if (command.Shortcut != Shortcut.None) + { + // Find the width of the shortcut text + dimension = g.MeasureString(GetShortcutText(command.Shortcut), _textFont); + + // Add to the width of the cell + cellWidth += _position[(int)_style, (int)PI.ShortcutGap] + (int)dimension.Width + 1; + } + } + + // If the new cell expands past the end of the screen... + if ((yPosition + cellHeight) >= screenHeight) + { + // .. then need to insert a column break + + // Move row/col tracking to the next column + row = 0; + col++; + + // Apply cell width to the current column entries + ApplySizeToColumnList(columnItems, xColumnMaxWidth); + + // Move cell position across to start of separator position + xStart += xColumnMaxWidth; + + // Get width of the separator area + int xSeparator = _position[(int)_style, (int)PI.SeparatorWidth]; + + DrawCommand dcSep = new DrawCommand(new Rectangle(xStart, yStart, xSeparator, 0), false); + + // Add to list of items for drawing + _drawCommands.Add(dcSep); + + // Move over the separator + xStart += xSeparator; + + // Reset cell position to top of column + yPosition = yStart; + + // Accumulate total width of previous columns + xPreviousColumnWidths += xColumnMaxWidth + xSeparator; + + // Largest cell for column defaults to minimum cell width + xColumnMaxWidth = cellMinWidth; + + // Show this be drawn in the infrequent colors + dcSep.Infrequent = previousInfrequent; + } + + // Create a new position rectangle (the width will be reset later once the + // width of the column has been determined but the other values are correct) + Rectangle cellRect = new Rectangle(xStart, yPosition, cellWidth, cellHeight); + + // Create a drawing object + DrawCommand dc = new DrawCommand(command, cellRect, row, col); + + // Is the infrequent state different from previous commands? + if (previousInfrequent != command.Infrequent) + { + // If was not infrequent but now is + if (command.Infrequent) + { + // Then draw this infrequent item with a top border + dc.TopBorder = true; + } + else + { + if (_drawCommands.Count > 0) + { + // Find the previous command (excluding separators) and make it as needed a border + for(int index = _drawCommands.Count - 1; index>=0; index--) + { + if (!( _drawCommands[index] as DrawCommand).Separator) + { + (_drawCommands[index] as DrawCommand).BottomBorder = true; + break; + } + } + } + } + } + + // Remember the state of previous command only if not a separator + if (!dc.Separator) + previousInfrequent = command.Infrequent; + + // Add to list of items for drawing + _drawCommands.Add(dc); + + // Add to list of items in this column + columnItems.Add(dc); + + // Remember the biggest cell width in this column + if (cellWidth > xColumnMaxWidth) + xColumnMaxWidth = cellWidth; + + // Move down to start of next cell in column + yPosition += cellHeight; + + // Remember the tallest column in the menu + if (yPosition > xMaximumColumnHeight) + xMaximumColumnHeight = yPosition; + + row++; + } + + // Check if we need to add an infrequent expansion item + if (infrequent) + { + // Create a minimum size cell + Rectangle cellRect = new Rectangle(xStart, yPosition, cellMinWidth, cellMinHeight); + + // Create a draw command to represent the drawing of the expansion item + DrawCommand dc = new DrawCommand(cellRect, true); + + // Must be last item + _drawCommands.Add(dc); + + // Add to list of items in this column + columnItems.Add(dc); + + yPosition += cellMinHeight; + + // Remember the tallest column in the menu + if (yPosition > xMaximumColumnHeight) + xMaximumColumnHeight = yPosition; + } + + // Apply cell width to the current column entries + ApplySizeToColumnList(columnItems, xColumnMaxWidth); + } + + // Must remember to release the HDC resource! + User32.ReleaseDC(IntPtr.Zero, hDC); + + // Find width/height of window + int windowWidth = _position[(int)_style, (int)PI.BorderLeft] + + xPreviousColumnWidths + + xColumnMaxWidth + + _position[(int)_style, (int)PI.BorderRight]; + + int windowHeight = _position[(int)_style, (int)PI.BorderTop] + + xMaximumColumnHeight + + _position[(int)_style, (int)PI.BorderBottom]; + + // Define the height of the vertical separators + ApplyVerticalSeparators(xMaximumColumnHeight); + + // Style specific modification of window size + int xAdd = _position[(int)_style, (int)PI.ShadowHeight]; + int yAdd = _position[(int)_style, (int)PI.ShadowWidth]; + + if (_style == VisualStyle.Plain) + { + xAdd += SystemInformation.Border3DSize.Width * 2; + yAdd += SystemInformation.Border3DSize.Height * 2; + } + + return new Size(windowWidth + xAdd, windowHeight + yAdd); + */ + } + + protected void DefineHighlightColors(Color baseColor) + { + _highlightColor = baseColor; + + if (_highlightColor == SystemColors.Highlight) + { + _highlightColorDark = SystemColors.Highlight; + _highlightColorLight = Color.FromArgb(70, _highlightColorDark); + _highlightColorLightLight = Color.FromArgb(20, _highlightColorDark); + } + else + { + _highlightColorDark = ControlPaint.Dark(baseColor); + _highlightColorLight = baseColor; + _highlightColorLightLight = Color.FromArgb(70, baseColor); + } + } + + protected void DefineColors(Color backColor) + { + _backColor = backColor; + _controlLL = ColorHelper.CalculateColor(SystemColors.Window, _backColor, 220); + _controlLBrush = new SolidBrush(ColorHelper.CalculateColor(_backColor, Color.White, 200)); + _controlEBrush = new SolidBrush(ColorHelper.CalculateColor(_backColor, Color.White, 150)); + _controlLLBrush = new SolidBrush(_controlLL); + } + + protected Color CalculateColor(Color front, Color back, int alpha) + { + // Use alpha blending to brigthen the colors but don't use it + // directly. Instead derive an opaque color that we can use. + Color frontColor = Color.FromArgb(255, front); + Color backColor = Color.FromArgb(255, back); + + float frontRed = frontColor.R; + float frontGreen = frontColor.G; + float frontBlue = frontColor.B; + float backRed = backColor.R; + float backGreen = backColor.G; + float backBlue = backColor.B; + + float fRed = (frontRed * alpha / 255) + backRed * ((float)(255 - alpha) / 255); + float fGreen = (frontGreen * alpha / 255) + backGreen * ((float)(255 - alpha) / 255); + float fBlue = (frontBlue * alpha / 255) + backBlue * ((float)(255 - alpha) / 255); + + byte newRed = (byte)fRed; + byte newGreen = (byte)fGreen; + byte newBlue = (byte)fBlue; + + return Color.FromArgb(255, newRed, newGreen, newBlue); + } + + protected void ApplyVerticalSeparators(int sepHeight) + { + // Each vertical separator needs to be the same height, this has already + // been calculated and passed in from the tallest column in the menu + foreach (DrawCommand dc in _drawCommands) + { + if (dc.VerticalSeparator) + { + // Grab the current drawing rectangle + Rectangle cellRect = dc.DrawRect; + + // Modify the height to that requested + dc.DrawRect = new Rectangle(cellRect.Left, cellRect.Top, cellRect.Width, sepHeight); + } + } + } + + protected void ApplySizeToColumnList(ArrayList columnList, int cellWidth) + { + // Each cell in the same column needs to be the same width, this has already + // been calculated and passed in as the widest cell in the column + foreach (DrawCommand dc in columnList) + { + // Grab the current drawing rectangle + Rectangle cellRect = dc.DrawRect; + + // Modify the width to that requested + dc.DrawRect = new Rectangle(cellRect.Left, cellRect.Top, cellWidth, cellRect.Height); + } + + // Clear collection out ready for reuse + columnList.Clear(); + } + + protected void RefreshAllCommands() + { + Win32.RECT rectRaw = new Win32.RECT(); + + // Grab the screen rectangle of the window + //User32.GetWindowRect(this.Handle, ref rectRaw); + + // Convert from screen to client sizing + Rectangle rectWin = new Rectangle(0, 0, + rectRaw.right - rectRaw.left, + rectRaw.bottom - rectRaw.top); + + using (Graphics g = Graphics.FromHwnd(this.Handle)) + { + // Draw the background area + DrawBackground(g, rectWin); + + // Draw the actual menu items + DrawAllCommands(g); + } + } + + protected void DrawBackground(Graphics g, Rectangle rectWin) + { + Rectangle main = new Rectangle(0, 0, + rectWin.Width - 1 - _position[(int)_style, (int)PI.ShadowWidth], + rectWin.Height - 1 - _position[(int)_style, (int)PI.ShadowHeight]); + + // Style specific drawing + switch (_style) + { + case VisualStyle.IDE: + // Calculate some common values + int imageColWidth = _position[(int)_style, (int)PI.ImageGapLeft] + + _imageWidth + + _position[(int)_style, (int)PI.ImageGapRight]; + + int xStart = _position[(int)_style, (int)PI.BorderLeft]; + int yStart = _position[(int)_style, (int)PI.BorderTop]; + int yHeight = main.Height - yStart - _position[(int)_style, (int)PI.BorderBottom] - 1; + + // Paint the main area background + g.FillRectangle(_controlLLBrush, main); + + // Draw single line border around the main area + using (Pen mainBorder = new Pen(ControlPaint.Dark(_backColor))) + { + g.DrawRectangle(mainBorder, main); + + // Should the border be drawn with part of the border missing? + if (_borderGap > 0) + { + // Remove the appropriate section of the border + if (_direction == Direction.Horizontal) + { + if (_excludeTop) + { + g.FillRectangle(Brushes.White, main.Left + 1 + _excludeOffset, main.Top, _borderGap - 1, 1); + g.FillRectangle(_controlLBrush, main.Left + 1 + _excludeOffset, main.Top, _borderGap - 1, 1); + } + else + { + g.FillRectangle(Brushes.White, main.Left + 1 + _excludeOffset, main.Bottom, _borderGap - 1, 1); + g.FillRectangle(_controlLBrush, main.Left + 1 + _excludeOffset, main.Bottom, _borderGap - 1, 1); + } + } + else + { + if (_excludeTop) + { + g.FillRectangle(Brushes.White, main.Left, main.Top + 1 + _excludeOffset, 1, _borderGap - 1); + g.FillRectangle(_controlLBrush, main.Left, main.Top + 1 + _excludeOffset, 1, _borderGap - 1); + } + else + { + if (_popupDown) + { + g.FillRectangle(Brushes.White, main.Left, main.Bottom - 1 - _excludeOffset, 1, _borderGap - 1); + g.FillRectangle(_controlLBrush, main.Left, main.Bottom - 1 - _excludeOffset, 1, _borderGap - 1); + } + else + { + g.FillRectangle(Brushes.White, main.Left, main.Bottom - _borderGap + 1, 1, _borderGap - 1); + g.FillRectangle(_controlLBrush, main.Left, main.Bottom - _borderGap + 1, 1, _borderGap - 1); + } + } + } + } + } + + // Draw the first image column + Rectangle imageRect = new Rectangle(xStart, yStart, imageColWidth, yHeight); + + g.FillRectangle(Brushes.White, imageRect); + g.FillRectangle(_controlLBrush, imageRect); + + // Draw image column after each vertical separator + foreach (DrawCommand dc in _drawCommands) + { + if (dc.Separator && dc.VerticalSeparator) + { + // Recalculate starting position (but height remains the same) + imageRect.X = dc.DrawRect.Right; + + g.FillRectangle(Brushes.White, imageRect); + g.FillRectangle(_controlLBrush, imageRect); + } + } + + // Draw shadow around borders + int rightLeft = main.Right + 1; + int rightTop = main.Top + _position[(int)_style, (int)PI.ShadowHeight]; + int rightBottom = main.Bottom + 1; + int leftLeft = main.Left + _position[(int)_style, (int)PI.ShadowWidth]; + int xExcludeStart = main.Left + _excludeOffset; + int xExcludeEnd = main.Left + _excludeOffset + _borderGap; + + if ((_borderGap > 0) && (!_excludeTop) && (_direction == Direction.Horizontal)) + { + int rightright = rectWin.Width; + + if (xExcludeStart >= leftLeft) + DrawShadowHorizontal(g, leftLeft, rightBottom, xExcludeStart - leftLeft, _position[(int)_style, (int)PI.ShadowHeight], Shadow.Left); + + if (xExcludeEnd <= rightright) + DrawShadowHorizontal(g, xExcludeEnd, rightBottom, rightright - xExcludeEnd, _position[(int)_style, (int)PI.ShadowHeight], Shadow.Right); + } + else + { + if ((_direction == Direction.Vertical) && (!_excludeTop)) + leftLeft = 0; + + DrawShadowHorizontal(g, leftLeft, rightBottom, rightLeft, _position[(int)_style, (int)PI.ShadowHeight], Shadow.All); + } + + DrawShadowVertical(g, rightLeft, rightTop, _position[(int)_style, (int)PI.ShadowWidth], rightBottom - rightTop - 1); + break; + + case VisualStyle.Plain: + // Paint the main area background + using (SolidBrush mainBrush = new SolidBrush(_backColor)) + g.FillRectangle(mainBrush, rectWin); + break; + } + + // Is there an extra title text to be drawn? + if (_menuCommands.ExtraText.Length > 0) + DrawColumn(g, main); + } + + protected void DrawShadowVertical(Graphics g, int left, int top, int width, int height) + { + if (_layered) + { + Color extraColor = Color.FromArgb(64, 0, 0, 0); + Color darkColor = Color.FromArgb(48, 0, 0, 0); + Color lightColor = Color.FromArgb(0, 0, 0, 0); + + // Enough room for top and bottom shades? + if (height >= _shadowLength) + { + using (LinearGradientBrush topBrush = new LinearGradientBrush(new Point(left - _shadowLength, top + _shadowLength), + new Point(left + _shadowLength, top), + extraColor, lightColor)) + { + // Draw top shade + g.FillRectangle(topBrush, left, top, _shadowLength, _shadowLength); + + top += _shadowLength; + height -= _shadowLength; + } + } + + using (LinearGradientBrush middleBrush = new LinearGradientBrush(new Point(left, 0), + new Point(left + width, 0), + darkColor, lightColor)) + { + // Draw middle shade + g.FillRectangle(middleBrush, left, top, width, height + 1); + } + } + else + { + using (SolidBrush shadowBrush = new SolidBrush(ControlPaint.Dark(_backColor))) + g.FillRectangle(shadowBrush, left, top, width, height + 1); + } + } + + protected void DrawShadowHorizontal(Graphics g, int left, int top, int width, int height, Shadow op) + { + if (_layered) + { + Color extraColor = Color.FromArgb(64, 0, 0, 0); + Color darkColor = Color.FromArgb(48, 0, 0, 0); + Color lightColor = Color.FromArgb(0, 0, 0, 0); + + // Do we need to draw the left shadow? + if (op != Shadow.Right) + { + if (width >= _shadowLength) + { + // Draw the remaining middle + using (LinearGradientBrush leftBrush = new LinearGradientBrush(new Point(left + _shadowLength, top - _shadowLength), + new Point(left, top + height), + extraColor, lightColor)) + { + // Draw middle shade + g.FillRectangle(leftBrush, left, top, _shadowLength, height); + + left += _shadowLength; + width -= _shadowLength; + } + } + } + + // Do we need to draw the right shadow? + if (op != Shadow.Left) + { + if (width >= _shadowLength) + { + try + { + g.DrawImageUnscaled(GetShadowCache(_shadowLength, height), left + width - _shadowLength, top); + } + catch + { + // just to be on the safe side... + } + width -= _shadowLength; + } + } + + // Draw the remaining middle + using (LinearGradientBrush middleBrush = new LinearGradientBrush(new Point(9999, top), + new Point(9999, top + height), + darkColor, lightColor)) + { + // Draw middle shade + g.FillRectangle(middleBrush, left, top, width, height); + } + } + else + { + using (SolidBrush shadowBrush = new SolidBrush(ControlPaint.Dark(_backColor))) + g.FillRectangle(shadowBrush, left, top, width, height); + } + } + + protected void DrawColumn(Graphics g, Rectangle main) + { + // Create the rectangle that encloses the drawing + Rectangle rectText = new Rectangle(main.Left, + main.Top, + _extraSize - _position[(int)_style, (int)PI.ExtraRightGap], + main.Height); + + Brush backBrush = null; + bool disposeBack = true; + + if (_menuCommands.ExtraBackBrush != null) + { + backBrush = _menuCommands.ExtraBackBrush; + disposeBack = false; + rectText.Width++; + } + else + backBrush = new SolidBrush(_menuCommands.ExtraBackColor); + + // Fill background using brush + g.FillRectangle(backBrush, rectText); + + // Do we need to dispose of the brush? + if (disposeBack) + backBrush.Dispose(); + + // Adjust rectangle for drawing the text into + rectText.X += _position[(int)_style, (int)PI.ExtraWidthGap]; + rectText.Y += _position[(int)_style, (int)PI.ExtraHeightGap]; + rectText.Width -= _position[(int)_style, (int)PI.ExtraWidthGap] * 2; + rectText.Height -= _position[(int)_style, (int)PI.ExtraHeightGap] * 2; + + // For Plain style we need to take into account the border sizes + if (_style == VisualStyle.Plain) + rectText.Height -= SystemInformation.Border3DSize.Height * 2; + + // Draw the text into this rectangle + StringFormat format = new StringFormat(); + format.FormatFlags = StringFormatFlags.DirectionVertical | + StringFormatFlags.NoClip | + StringFormatFlags.NoWrap; + format.Alignment = StringAlignment.Near; + format.LineAlignment = StringAlignment.Center; + + Brush textBrush = null; + bool disposeText = true; + + if (_menuCommands.ExtraTextBrush != null) + { + textBrush = _menuCommands.ExtraTextBrush; + disposeText = false; + } + else + textBrush = new SolidBrush(_menuCommands.ExtraTextColor); + + // Draw string from bottom of area towards the top using the given Font/Brush + DrawHelper.DrawReverseString(g, _menuCommands.ExtraText, _menuCommands.ExtraFont, rectText, textBrush, format); + + // Do we need to dispose of the brush? + if (disposeText) + textBrush.Dispose(); + } + + internal void DrawSingleCommand(Graphics g, DrawCommand dc, bool hotCommand) + { + Rectangle drawRect = dc.DrawRect; + MenuCommand mc = dc.MenuCommand; + + // Remember some often used values + int textGapLeft = _position[(int)_style, (int)PI.TextGapLeft]; + int imageGapLeft = _position[(int)_style, (int)PI.ImageGapLeft]; + int imageGapRight = _position[(int)_style, (int)PI.ImageGapRight]; + int imageLeft = drawRect.Left + imageGapLeft; + + // Calculate some common values + int imageColWidth = imageGapLeft + _imageWidth + imageGapRight; + + int subMenuWidth = _position[(int)_style, (int)PI.SubMenuGapLeft] + + _position[(int)_style, (int)PI.SubMenuWidth] + + _position[(int)_style, (int)PI.SubMenuGapRight]; + + int subMenuX = drawRect.Right - + _position[(int)_style, (int)PI.SubMenuGapRight] - + _position[(int)_style, (int)PI.SubMenuWidth]; + + // Text drawing rectangle needs to know the right most position for drawing + // to stop. This is the width of the window minus the relevant values + int shortCutX = subMenuX - + _position[(int)_style, (int)PI.SubMenuGapLeft] - + _position[(int)_style, (int)PI.TextGapRight]; + + // Is this item an expansion command? + if (dc.Expansion) + { + Rectangle box = drawRect; + + // In IDE style the box is next to the image column + if (_style == VisualStyle.IDE) + { + // Reduce the box to take into account the column + box.X += imageColWidth; + box.Width -= imageColWidth; + } + + // Find centre for drawing the image + int xPos = box.Left + ((box.Width - _imageHeight) / 2); + int yPos = box.Top + ((box.Height - _imageHeight) / 2); + + // Should the item look selected + if (hotCommand) + { + switch (_style) + { + case VisualStyle.IDE: + Rectangle selectArea = new Rectangle(drawRect.Left + 1, drawRect.Top, + drawRect.Width - 3, drawRect.Height - 1); + + using (Pen selectPen = new Pen(_highlightColorDark)) + { + // Draw the selection area white, because we are going to use an alpha brush + using (SolidBrush whiteBrush = new SolidBrush(Color.White)) + g.FillRectangle(whiteBrush, selectArea); + + using (SolidBrush selectBrush = new SolidBrush(_highlightColorLight)) + { + // Draw the selection area + g.FillRectangle(selectBrush, selectArea); + + // Draw a border around the selection area + g.DrawRectangle(selectPen, selectArea); + } + } + break; + + case VisualStyle.Plain: + // Shrink the box to provide a small border + box.Inflate(-2, -2); + + using (Pen lightPen = new Pen(ControlPaint.LightLight(_backColor)), + darkPen = new Pen(ControlPaint.DarkDark(_backColor))) + { + g.DrawLine(lightPen, box.Right, box.Top, box.Left, box.Top); + g.DrawLine(lightPen, box.Left, box.Top, box.Left, box.Bottom); + g.DrawLine(darkPen, box.Left, box.Bottom, box.Right, box.Bottom); + g.DrawLine(darkPen, box.Right, box.Bottom, box.Right, box.Top); + } + break; + } + } + else + { + switch (_style) + { + case VisualStyle.IDE: + // Fill the entire drawing area with white + g.FillRectangle(_controlLLBrush, new Rectangle(drawRect.Left + 1, drawRect.Top, + drawRect.Width - 1, drawRect.Height)); + + // Draw the image column background + g.FillRectangle(Brushes.White, new Rectangle(drawRect.Left, drawRect.Top, + imageColWidth, drawRect.Height)); + + g.FillRectangle(_controlLBrush, new Rectangle(drawRect.Left, drawRect.Top, + imageColWidth, drawRect.Height)); + break; + + case VisualStyle.Plain: + using (SolidBrush drawBrush = new SolidBrush(_backColor)) + g.FillRectangle(drawBrush, new Rectangle(drawRect.Left, drawRect.Top, + drawRect.Width, drawRect.Height)); + break; + } + } + + // Always draw the expansion bitmap + g.DrawImage(_menuImages.Images[(int)ImageIndex.Expansion], xPos, yPos); + } + else + { + // Is this item a separator? + if (dc.Separator) + { + if (dc.VerticalSeparator) + { + switch (_style) + { + case VisualStyle.IDE: + // Draw the separator as a single line + using (Pen separatorPen = new Pen(ControlPaint.Dark(_backColor))) + g.DrawLine(separatorPen, drawRect.Left, drawRect.Top, drawRect.Left, drawRect.Bottom); + break; + + case VisualStyle.Plain: + ButtonBorderStyle bsInset = ButtonBorderStyle.Inset; + ButtonBorderStyle bsNone = ButtonBorderStyle.Inset; + + Rectangle sepRect = new Rectangle(drawRect.Left + 1, drawRect.Top, 2, drawRect.Height); + + // Draw the separator as two lines using Inset style + ControlPaint.DrawBorder(g, sepRect, + _backColor, 1, bsInset, _backColor, 0, bsNone, + _backColor, 1, bsInset, _backColor, 0, bsNone); + break; + } + } + else + { + switch (_style) + { + case VisualStyle.IDE: + // Draw the image column background + Rectangle imageCol = new Rectangle(drawRect.Left, drawRect.Top, imageColWidth, drawRect.Height); + + g.FillRectangle(Brushes.White, imageCol); + g.FillRectangle(_controlLBrush, imageCol); + + // Draw a separator + using (Pen separatorPen = new Pen(Color.FromArgb(75, _textColor))) + { + // Draw the separator as a single line + g.DrawLine(separatorPen, + drawRect.Left + imageColWidth + textGapLeft, drawRect.Top + 2, + drawRect.Right, + drawRect.Top + 2); + } + break; + + case VisualStyle.Plain: + if (dc.Infrequent && _highlightInfrequent) + { + // Change background to be a lighter shade + using (Brush drawBrush = new SolidBrush(ControlPaint.Light(_backColor))) + g.FillRectangle(drawBrush, drawRect); + } + + ButtonBorderStyle bsInset = ButtonBorderStyle.Inset; + ButtonBorderStyle bsNone = ButtonBorderStyle.Inset; + + Rectangle sepRect = new Rectangle(drawRect.Left + 2, drawRect.Top + 2, drawRect.Width - 4, 2); + + // Draw the separator as two lines using Inset style + ControlPaint.DrawBorder(g, sepRect, + _backColor, 0, bsNone, _backColor, 1, bsInset, + _backColor, 0, bsNone, _backColor, 1, bsInset); + break; + } + } + } + else + { + int leftPos = drawRect.Left + imageColWidth + textGapLeft; + + // Should the command be drawn selected? + if (hotCommand) + { + switch (_style) + { + case VisualStyle.IDE: + Rectangle selectArea = new Rectangle(drawRect.Left + 1, drawRect.Top, drawRect.Width - 3, drawRect.Height - 1); + + using (Pen selectPen = new Pen(_highlightColorDark)) + { + // Draw the selection area white, because we are going to use an alpha brush + using (SolidBrush whiteBrush = new SolidBrush(Color.White)) + g.FillRectangle(whiteBrush, selectArea); + + using (SolidBrush selectBrush = new SolidBrush(_highlightColorLight)) + { + // Draw the selection area + g.FillRectangle(selectBrush, selectArea); + + // Draw a border around the selection area + g.DrawRectangle(selectPen, selectArea); + } + } + break; + + case VisualStyle.Plain: + using (SolidBrush selectBrush = new SolidBrush(_highlightColorDark)) + g.FillRectangle(selectBrush, drawRect); + break; + } + } + else + { + switch (_style) + { + case VisualStyle.IDE: + // Fill the entire drawing area with ControlLightLight + g.FillRectangle(_controlLLBrush, new Rectangle(drawRect.Left + 1, drawRect.Top, drawRect.Width - 1, drawRect.Height)); + + if (dc.Infrequent && _highlightInfrequent) + { + // Draw the text area in a darker shade + g.FillRectangle(Brushes.White, new Rectangle(leftPos, drawRect.Top, drawRect.Right - leftPos - textGapLeft, drawRect.Height)); + g.FillRectangle(_controlEBrush, new Rectangle(leftPos, drawRect.Top, drawRect.Right - leftPos - textGapLeft, drawRect.Height)); + } + + Rectangle imageCol = new Rectangle(drawRect.Left, drawRect.Top, imageColWidth, drawRect.Height); + + // Draw the image column background + g.FillRectangle(Brushes.White, imageCol); + g.FillRectangle(_controlLBrush, imageCol); + break; + + case VisualStyle.Plain: + if (dc.Infrequent && _highlightInfrequent) + { + using (Brush drawBrush = new SolidBrush(ControlPaint.Light(_backColor))) + g.FillRectangle(drawBrush, new Rectangle(drawRect.Left, drawRect.Top, drawRect.Width, drawRect.Height)); + } + else + { + using (Brush drawBrush = new SolidBrush(_backColor)) + g.FillRectangle(drawBrush, new Rectangle(drawRect.Left, drawRect.Top, drawRect.Width, drawRect.Height)); + } + + if (dc.TopBorder && _highlightInfrequent) + using (Pen drawPen = new Pen(ControlPaint.Dark(_backColor))) + g.DrawLine(drawPen, drawRect.Left, drawRect.Top, drawRect.Right, drawRect.Top); + + if (dc.BottomBorder && _highlightInfrequent) + using (Pen drawPen = new Pen(ControlPaint.LightLight(_backColor))) + g.DrawLine(drawPen, drawRect.Left, drawRect.Bottom - 1, drawRect.Right, drawRect.Bottom - 1); + break; + } + } + + // Calculate text drawing rectangle + Rectangle strRect = new Rectangle(leftPos, drawRect.Top, shortCutX - leftPos, drawRect.Height); + + // Left align the text drawing on a single line centered vertically + // and process the & character to be shown as an underscore on next character + StringFormat format = new StringFormat(); + format.FormatFlags = StringFormatFlags.NoClip | StringFormatFlags.NoWrap; + format.Alignment = StringAlignment.Near; + format.LineAlignment = StringAlignment.Center; + format.HotkeyPrefix = HotkeyPrefix.Show; + + SolidBrush textBrush; + + // Create brush depending on enabled state + if (mc.Enabled) + { + if (!hotCommand || (_style == VisualStyle.IDE)) + textBrush = new SolidBrush(_textColor); + else + textBrush = new SolidBrush(_highlightTextColor); + } + else + textBrush = new SolidBrush(SystemColors.GrayText); + + // Helper values used when drawing grayed text in plain style + Rectangle rectDownRight = strRect; + rectDownRight.Offset(1, 1); + + if (mc.Enabled || (_style == VisualStyle.IDE)) + g.DrawString(mc.Text, _textFont, textBrush, strRect, format); + else + { + if (_style == VisualStyle.Plain) + { + // Draw grayed text by drawing white string offset down and right + using (SolidBrush whiteBrush = new SolidBrush(Color.White)) + g.DrawString(mc.Text, _textFont, whiteBrush, rectDownRight, format); + } + + // And then draw in correct color offset up and left + g.DrawString(mc.Text, _textFont, textBrush, strRect, format); + } + + if (mc.Shortcut != Shortcut.None) + { + // Right align the shortcut drawing + format.Alignment = StringAlignment.Far; + + if (mc.Enabled || (_style == VisualStyle.IDE)) + { + // Draw the shortcut text + g.DrawString(GetShortcutText(mc.Shortcut), _textFont, textBrush, strRect, format); + } + else + { + if (_style == VisualStyle.Plain) + { + // Draw grayed text by drawing white string offset down and right + using (SolidBrush whiteBrush = new SolidBrush(Color.White)) + g.DrawString(GetShortcutText(mc.Shortcut), _textFont, whiteBrush, rectDownRight, format); + } + + // And then draw in corret color offset up and left + g.DrawString(GetShortcutText(mc.Shortcut), _textFont, textBrush, strRect, format); + } + } + + // The image offset from top of cell is half the space left after + // subtracting the height of the image from the cell height + int imageTop = drawRect.Top + (drawRect.Height - _imageHeight) / 2; + + Image image = null; + + // Should a check mark be drawn? + if (mc.Checked) + { + switch (_style) + { + case VisualStyle.IDE: + Pen boxPen; + Brush boxBrush; + + if (mc.Enabled) + { + boxPen = new Pen(_highlightColorDark); + boxBrush = new SolidBrush(_highlightColorLightLight); + } + else + { + boxPen = new Pen(SystemColors.GrayText); + boxBrush = new SolidBrush(Color.FromArgb(20, SystemColors.GrayText)); + } + + Rectangle boxRect = new Rectangle(imageLeft - 1, imageTop - 1, _imageHeight + 2, _imageWidth + 2); + + // Fill the checkbox area very slightly + g.FillRectangle(boxBrush, boxRect); + + // Draw the box around the checkmark area + g.DrawRectangle(boxPen, boxRect); + + boxPen.Dispose(); + boxBrush.Dispose(); + break; + + case VisualStyle.Plain: + break; + } + + // Grab either tick or radio button image + if (mc.RadioCheck) + { + if (hotCommand && (_style == VisualStyle.Plain)) + image = _menuImages.Images[(int)ImageIndex.RadioSelected]; + else + image = _menuImages.Images[(int)ImageIndex.Radio]; + } + else + { + if (hotCommand && (_style == VisualStyle.Plain)) + image = _menuImages.Images[(int)ImageIndex.CheckSelected]; + else + image = _menuImages.Images[(int)ImageIndex.Check]; + } + } + else + { + try + { + // Always use the Image property in preference to the ImageList + if (mc.Image != null) + image = mc.Image; + else + { + if ((mc.ImageList != null) && (mc.ImageIndex >= 0)) + image = mc.ImageList.Images[mc.ImageIndex]; + } + } + catch (Exception) + { + // User supplied ImageList/ImageIndex are invalid, use an error image instead + image = _menuImages.Images[(int)ImageIndex.ImageError]; + } + } + + // Is there an image to be drawn? + if (image != null) + { + if (mc.Enabled) + { + if ((hotCommand) && (!mc.Checked) && (_style == VisualStyle.IDE)) + { + // Draw a gray icon offset down and right + Bitmap shadowImage = new Bitmap((Bitmap)image); + Color shadowColor = Color.FromArgb(154, 156, 146); + Color transparent = Color.FromArgb(0, 0, 0, 0); + + for (int pixelX = 0; pixelX < image.Width; pixelX++) + { + for (int pixelY = 0; pixelY < image.Height; pixelY++) + { + if (shadowImage.GetPixel(pixelX, pixelY) != transparent) + shadowImage.SetPixel(pixelX, pixelY, shadowColor); + } + } + + g.DrawImage(shadowImage, imageLeft + 1, imageTop + 1); + + // Draw an enabled icon offset up and left + g.DrawImage(image, imageLeft - 1, imageTop - 1); + } + else + { + // Draw an faded enabled icon + // A new bitmap so we don't change the actual image + Bitmap fadedImage = new Bitmap(image); + Color transparent = Color.FromArgb(0, 0, 0, 0); + + for (int pixelX = 0; pixelX < image.Width; pixelX++) + { + for (int pixelY = 0; pixelY < image.Height; pixelY++) + { + Color pixelColor = fadedImage.GetPixel(pixelX, pixelY); + if (pixelColor != transparent) + { + Color newPixelColor = Color.FromArgb((pixelColor.R + 76) - (((pixelColor.R + 32) / 64) * 19), + (pixelColor.G + 76) - (((pixelColor.G + 32) / 64) * 19), + (pixelColor.B + 76) - (((pixelColor.B + 32) / 64) * 19)); + + fadedImage.SetPixel(pixelX, pixelY, newPixelColor); + } + } + } + + g.DrawImage(fadedImage, imageLeft, imageTop); + + // Draw an enabled icon + //g.DrawImage(image, imageLeft, imageTop); + } + } + else + { + // Draw a image disabled + ControlPaint.DrawImageDisabled(g, image, imageLeft, imageTop, SystemColors.HighlightText); + } + } + + // Does the menu have a submenu defined? + if (dc.SubMenu) + { + // Is the item enabled? + if (mc.Enabled) + { + int subMenuIndex = (int)ImageIndex.SubMenu; + + if (hotCommand && (_style == VisualStyle.Plain)) + subMenuIndex = (int)ImageIndex.SubMenuSelected; + + // Draw the submenu arrow + g.DrawImage(_menuImages.Images[subMenuIndex], subMenuX, imageTop); + } + else + { + // Draw a image disabled + ControlPaint.DrawImageDisabled(g, _menuImages.Images[(int)ImageIndex.SubMenu], + subMenuX, imageTop, _highlightTextColor); + } + } + } + } + } + + protected void DrawAllCommands(Graphics g) + { + for (int i = 0; i < _drawCommands.Count; i++) + { + // Grab some commonly used values + DrawCommand dc = _drawCommands[i] as DrawCommand; + + // Draw this command only + DrawSingleCommand(g, dc, (i == _trackItem)); + } + } + + protected string GetShortcutText(Shortcut shortcut) + { + // Get the key code + char keycode = (char)((int)shortcut & 0x0000FFFF); + + // The type converter does not work for numeric values as it returns + // Alt+D0 instad of Alt+0. So check for numeric keys and construct the + // return string ourself. + if ((keycode >= '0') && (keycode <= '9')) + { + string display = ""; + + // Get the modifier + int modifier = (int)((int)shortcut & 0xFFFF0000); + + if ((modifier & 0x00010000) != 0) + display += "Shift+"; + + if ((modifier & 0x00020000) != 0) + display += "Ctrl+"; + + if ((modifier & 0x00040000) != 0) + display += "Alt+"; + + display += keycode; + + return display; + } + else + { + return TypeDescriptor.GetConverter(typeof(Keys)).ConvertToString((Keys)shortcut); + } + } + + protected bool ProcessKeyUp() + { + int newItem = _trackItem; + int startItem = newItem; + + for (int i = 0; i < _drawCommands.Count; i++) + { + // Move to previous item + newItem--; + + // Have we looped all the way around all the choices + if (newItem == startItem) + return false; + + // Check limits + if (newItem < 0) + newItem = _drawCommands.Count - 1; + + DrawCommand dc = _drawCommands[newItem] as DrawCommand; + + // Can we select this item? + if (!dc.Separator && dc.Enabled) + { + // If a change has occured + if (newItem != _trackItem) + { + // Modify the display of the two items + SwitchSelection(_trackItem, newItem, false, false); + + return true; + } + } + } + + return false; + } + + protected bool ProcessKeyDown() + { + int newItem = _trackItem; + int startItem = newItem; + + for (int i = 0; i < _drawCommands.Count; i++) + { + // Move to previous item + newItem++; + + // Check limits + if (newItem >= _drawCommands.Count) + newItem = 0; + + DrawCommand dc = _drawCommands[newItem] as DrawCommand; + + // Can we select this item? + if (!dc.Separator && dc.Enabled) + { + // If a change has occured + if (newItem != _trackItem) + { + // Modify the display of the two items + SwitchSelection(_trackItem, newItem, false, false); + + return true; + } + } + } + + return false; + } + + protected void ProcessKeyLeft() + { + // Are we the first submenu of a parent control? + bool autoLeft = (_parentMenu != null) || (_parentControl != null); + bool checkKeys = false; + + if (_trackItem != -1) + { + // Get the col this item is in + DrawCommand dc = _drawCommands[_trackItem] as DrawCommand; + + // Grab the current column/row values + int col = dc.Col; + int row = dc.Row; + + // If not in the first column then move left one + if (col > 0) + { + int newItem = -1; + int newRow = -1; + int findCol = col - 1; + DrawCommand newDc = null; + + for (int i = 0; i < _drawCommands.Count; i++) + { + DrawCommand listDc = _drawCommands[i] as DrawCommand; + + // Interested in cells in the required column + if (listDc.Col == findCol) + { + // Is this Row nearer to the one required than those found so far? + if ((listDc.Row <= row) && (listDc.Row > newRow) && + !listDc.Separator && listDc.Enabled) + { + // Remember this item + newRow = listDc.Row; + newDc = listDc; + newItem = i; + } + } + } + + if (newDc != null) + { + // Track the new item + // Modify the display of the two items + SwitchSelection(_trackItem, newItem, false, false); + } + else + checkKeys = true; + } + else + checkKeys = true; + } + else + { + if (_parentMenu != null) + { + if (!ProcessKeyUp()) + checkKeys = true; + } + else + checkKeys = true; + } + + // If we have a parent control and nothing to move right into + if (autoLeft && checkKeys) + { + _returnCommand = null; + + // Finish processing messages + _timer.Stop(); + _exitLoop = true; + + // Only a top level PopupMenu should cause the MenuControl to select the + // next left menu command. A submenu should just become dismissed. + if (_parentMenu == null) + _returnDir = -1; + } + } + + protected bool ProcessKeyRight() + { + // Are we the first submenu of a parent control? + bool autoRight = (_parentControl != null); + bool checkKeys = false; + bool ret = false; + + // Is an item currently selected? + if (_trackItem != -1) + { + DrawCommand dc = _drawCommands[_trackItem] as DrawCommand; + + // Does this item have a submenu? + if (dc.SubMenu) + { + // Handle the submenu + OperateSubMenu(_trackItem, true); + + ret = true; + } + else + { + // Grab the current column/row values + int col = dc.Col; + int row = dc.Row; + + // If not in the first column then move left one + int newItem = -1; + int newRow = -1; + int findCol = col + 1; + DrawCommand newDc = null; + + for (int i = 0; i < _drawCommands.Count; i++) + { + DrawCommand listDc = _drawCommands[i] as DrawCommand; + + // Interesting in cells in the required column + if (listDc.Col == findCol) + { + // Is this Row nearer to the one required than those found so far? + if ((listDc.Row <= row) && (listDc.Row > newRow) && + !listDc.Separator && listDc.Enabled) + { + // Remember this item + newRow = listDc.Row; + newDc = listDc; + newItem = i; + } + } + } + + if (newDc != null) + { + // Track the new item + // Modify the display of the two items + SwitchSelection(_trackItem, newItem, false, false); + } + else + checkKeys = true; + } + } + else + { + if (_parentMenu != null) + { + if (!ProcessKeyDown()) + checkKeys = true; + } + else + checkKeys = true; + } + + // If we have a parent control and nothing to move right into + if (autoRight && checkKeys) + { + _returnCommand = null; + + // Finish processing messages + _timer.Stop(); + _exitLoop = true; + + _returnDir = 1; + } + + return ret; + } + + protected int ProcessMnemonicKey(char key) + { + // Check against each draw command mnemonic + for (int i = 0; i < _drawCommands.Count; i++) + { + DrawCommand dc = _drawCommands[i] as DrawCommand; + + if (dc.Enabled) + { + // Does the character match? + if (key == dc.Mnemonic) + { + // Does this have any submenu? + if (dc.SubMenu) + { + // Is there a change in selected item? + if (_trackItem != i) + { + // Modify the display of the two items + SwitchSelection(_trackItem, i, true, false); + } + + return -1; + } + else + { + // No submenu so just selected the item which + // will cause the PopupMenu to exit + return i; + } + } + } + } + + // No match found + return -1; + } + + /* + protected Win32.POINT MousePositionToScreen(Win32.MSG msg) + { + Win32.POINT screenPos; + screenPos.x = (short)((uint)msg.lParam & 0x0000FFFFU); + screenPos.y = (short)(((uint)msg.lParam & 0xFFFF0000U) >> 16); + + // Convert the mouse position to screen coordinates, + // but not for non-client messages + if ((msg.message != (int)Win32.Msgs.WM_NCLBUTTONUP) && + (msg.message != (int)Win32.Msgs.WM_NCMBUTTONUP) && + (msg.message != (int)Win32.Msgs.WM_NCRBUTTONUP) && + (msg.message != (int)Win32.Msgs.WM_NCXBUTTONUP) && + (msg.message != (int)Win32.Msgs.WM_NCLBUTTONDOWN) && + (msg.message != (int)Win32.Msgs.WM_NCMBUTTONDOWN) && + (msg.message != (int)Win32.Msgs.WM_NCRBUTTONDOWN) && + (msg.message != (int)Win32.Msgs.WM_NCXBUTTONDOWN)) + { + // Convert the mouse position to screen coordinates + User32.ClientToScreen(msg.hwnd, ref screenPos); + } + + return screenPos; + } + + protected bool ParentControlWantsMouseMessage(Win32.POINT screenPos, ref Win32.MSG msg) + { + // Special case the MOUSEMOVE so if we are part of a MenuControl + // then we should let the MenuControl process that message + if ((msg.message == (int)Win32.Msgs.WM_MOUSEMOVE) && (_parentControl != null)) + { + Win32.RECT rectRaw = new Win32.RECT(); + + // Grab the screen rectangle of the parent control + User32.GetWindowRect(_parentControl.Handle, ref rectRaw); + + if ((screenPos.x >= rectRaw.left) && (screenPos.x <= rectRaw.right) && + (screenPos.y >= rectRaw.top) && (screenPos.y <= rectRaw.bottom)) + return true; + } + + return false; + } + + internal PopupMenu ParentPopupMenuWantsMouseMessage(Win32.POINT screenPos, ref Win32.MSG msg) + { + if (_parentMenu != null) + return _parentMenu.WantMouseMessage(screenPos); + + return null; + } + + protected PopupMenu WantMouseMessage(Win32.POINT screenPos) + { + Win32.RECT rectRaw = new Win32.RECT(); + + // Grab the screen rectangle of the window + User32.GetWindowRect(this.Handle, ref rectRaw); + + if ((screenPos.x >= rectRaw.left) && (screenPos.x <= rectRaw.right) && + (screenPos.y >= rectRaw.top) && (screenPos.y <= rectRaw.bottom)) + return this; + + if (_parentMenu != null) + return _parentMenu.WantMouseMessage(screenPos); + + return null; + } + */ + + protected void SwitchSelection(int oldItem, int newItem, bool mouseChange, bool reverting) + { + bool updateWindow = false; + + // Create a graphics object for drawing with + using (Graphics g = Graphics.FromHwnd(this.Handle)) + { + // Deselect the old draw command + if (oldItem != -1) + { + DrawCommand dc = _drawCommands[oldItem] as DrawCommand; + + // Draw old item not selected + if (_layered) + updateWindow = true; + else + DrawSingleCommand(g, _drawCommands[oldItem] as DrawCommand, false); + + // Generate an unselect event + if (dc.MenuCommand != null) + OnDeselected(dc.MenuCommand); + } + + if (newItem != -1) + { + // Stop the timer as a new selection has occured + _timer.Stop(); + + // Do we have a child menu? + if (!reverting && (_childMenu != null)) + { + // Start timer to test if it should be dismissed + _timer.Interval = _selectionDelay; + _timer.Start(); + } + + DrawCommand dc = _drawCommands[newItem] as DrawCommand; + + // Select the new draw command + if (!dc.Separator && dc.Enabled) + { + // Draw the newly selected item + if (_layered) + updateWindow = true; + else + DrawSingleCommand(g, dc, true); + + // Only is mouse movement caused the selection change... + if (!reverting && mouseChange) + { + //...should we start a timer to test for sub menu displaying + if (dc.Expansion) + _timer.Interval = _expansionDelay; + else + _timer.Interval = _selectionDelay; + + _timer.Start(); + } + + // Generate an unselect event + if (dc.MenuCommand != null) + OnSelected(dc.MenuCommand); + } + else + { + // Cannot become selected + newItem = -1; + } + } + + // Remember the new selection + _trackItem = newItem; + + if (_layered && updateWindow) + { + // Update the image for display + UpdateLayeredWindow(); + } + } + } + + protected void OnTimerExpire(object sender, EventArgs e) + { + // Prevent it expiring again + _timer.Stop(); + + bool showPopup = true; + + // Is a popup menu already being displayed? + if (_childMenu != null) + { + // If the submenu popup is for a different item? + if (_popupItem != _trackItem) + { + // Then need to kill the submenu + //User32.PostMessage(_childMenu.Handle, WM_DISMISS, 0, 0); + } + else + showPopup = false; + } + + // Should we show the popup for this item + if (showPopup) + { + // Check an item really is selected + if (_trackItem != -1) + { + DrawCommand dc = _drawCommands[_trackItem] as DrawCommand; + + // Does this item have a submenu? + if (dc.SubMenu) + OperateSubMenu(_trackItem, false); + else + { + if (dc.Expansion) + RegenerateExpansion(); + } + } + } + } + + protected void OperateSubMenu(int popupItem, bool selectFirst) + { + //User32.PostMessage(this.Handle, WM_OPERATE_SUBMENU, (uint)popupItem, (uint)(selectFirst ? 1 : 0)); + } + + protected void OnWM_OPERATE_SUBMENU(ref Message m) + { + int popupItem = (int)m.WParam; + bool selectFirst = (m.LParam != IntPtr.Zero); + + _popupItem = popupItem; + _childMenu = new PopupMenu(); + + DrawCommand dc = _drawCommands[popupItem] as DrawCommand; + + // Find screen coordinate of Top right of item cell + Win32.POINT screenPosTR; + screenPosTR.x = dc.DrawRect.Right; + screenPosTR.y = dc.DrawRect.Top; + //User32.ClientToScreen(this.Handle, ref screenPosTR); + + // Find screen coordinate of top left of item cell + Win32.POINT screenPosTL; + screenPosTL.x = dc.DrawRect.Left; + screenPosTL.y = dc.DrawRect.Top; + //User32.ClientToScreen(this.Handle, ref screenPosTL); + + // Ensure the child has the same properties as ourself + _childMenu.Style = this.Style; + _childMenu.Font = this.Font; + _childMenu.BackColor = this.BackColor; + _childMenu.TextColor = this.TextColor; + _childMenu.HighlightTextColor = this.HighlightTextColor; + _childMenu.HighlightColor = this.HighlightColor; + _childMenu.Animate = this.Animate; + _childMenu.AnimateStyle = this.AnimateStyle; + _childMenu.AnimateTime = this.AnimateTime; + + // Record keyboard direction + int returnDir = 0; + + // Propogate the remembering of expansion state + _childMenu.RememberExpansion = _rememberExpansion; + + // Honour the collections request for showing infrequent items + _childMenu._showInfrequent = dc.MenuCommand.MenuCommands.ShowInfrequent; + + // Propogate the highlight property + _childMenu.HighlightInfrequent = _highlightInfrequent; + + // Generate event so that caller has chance to modify MenuCommand contents + dc.MenuCommand.OnPopupStart(); + + _returnCommand = _childMenu.InternalTrackPopup(new Point(screenPosTR.x, screenPosTR.y), + new Point(screenPosTL.x, screenPosTL.y), + dc.MenuCommand.MenuCommands, + this, + selectFirst, + _parentControl, + _popupRight, + _popupDown, + _animateFirst, + ref returnDir); + + // Generate event so that caller has chance to modify MenuCommand contents + dc.MenuCommand.OnPopupEnd(); + + _popupItem = -1; ; + _childMenu = null; + + // Subsequent times a submenu is shown we do not want it to animate + _animateFirst = false; + + if ((_returnCommand != null) || (returnDir != 0)) + { + // Finish processing messages + _timer.Stop(); + _exitLoop = true; + _returnDir = returnDir; + } + } + + public virtual void OnSelected(MenuCommand mc) + { + // If initiated by a MenuControl item then let the control handle this + if (_parentControl != null) + _parentControl.OnSelected(mc); + else + { + // If we have an event defined then fire it + if (Selected != null) + Selected(mc); + else + { + // Maybe our parent has an event defined instead + if (_parentMenu != null) + _parentMenu.OnSelected(mc); + } + } + } + + public virtual void OnDeselected(MenuCommand mc) + { + // If initiated by a MenuControl item then let the control handle this + if (_parentControl != null) + _parentControl.OnDeselected(mc); + else + { + // If we have an event defined then fire it + if (Deselected != null) + Deselected(mc); + else + { + // Maybe our parent has an event defined instead + if (_parentMenu != null) + _parentMenu.OnDeselected(mc); + } + } + } + + protected void OnWM_PAINT(ref Message m) + { + /* + Win32.PAINTSTRUCT ps = new Win32.PAINTSTRUCT(); + + // Have to call BeginPaint whenever processing a WM_PAINT message + IntPtr hDC = User32.BeginPaint(m.HWnd, ref ps); + + Win32.RECT rectRaw = new Win32.RECT(); + + // Grab the screen rectangle of the window + User32.GetWindowRect(this.Handle, ref rectRaw); + + // Convert to a client size rectangle + Rectangle rectWin = new Rectangle(0, 0, + rectRaw.right - rectRaw.left, + rectRaw.bottom - rectRaw.top); + + // Create a graphics object for drawing + using(Graphics g = Graphics.FromHdc(hDC)) + { + // Create bitmap for drawing onto + Bitmap memoryBitmap = new Bitmap(rectWin.Width, rectWin.Height); + + using(Graphics h = Graphics.FromImage(memoryBitmap)) + { + // Draw the background area + DrawBackground(h, rectWin); + + // Draw the actual menu items + DrawAllCommands(h); + } + + // Blit bitmap onto the screen + g.DrawImageUnscaled(memoryBitmap, 0, 0); + } + + // Don't forget to end the paint operation! + User32.EndPaint(m.HWnd, ref ps); + */ + } + + protected void OnWM_ACTIVATEAPP(ref Message m) + { + // Another application has been activated, so we need to kill ourself + _timer.Stop(); + _exitLoop = true; + } + + protected void SubMenuMovement() + { + // Cancel timer to prevent auto closing of an open submenu + _timer.Stop(); + + // Has the selected item changed since child menu shown? + if (_popupItem != _trackItem) + { + // Need to put it back again + SwitchSelection(_trackItem, _popupItem, false, true); + } + + // Are we a submenu? + if (_parentMenu != null) + { + // Inform parent that we have movement and so do not + // use a timer to close us up + _parentMenu.SubMenuMovement(); + } + } + + protected void OnWM_MOUSEMOVE(int xPos, int yPos) + { + // Convert from screen to client coordinates + xPos -= _currentPoint.X; + yPos -= _currentPoint.Y; + + // Are we a submenu? + if (_parentMenu != null) + { + // Inform parent that we have movement and so do not + // use a timer to close us up + _parentMenu.SubMenuMovement(); + } + + // Yes, we know the mouse is over window + _mouseOver = true; + + Point pos = new Point(xPos, yPos); + + // Has mouse position really changed since last time? + if (_lastMousePos != pos) + { + for (int i = 0; i < _drawCommands.Count; i++) + { + DrawCommand dc = _drawCommands[i] as DrawCommand; + + if (dc.DrawRect.Contains(pos)) + { + // Is there a change in selected item? + if (_trackItem != i) + { + // Modify the display of the two items + SwitchSelection(_trackItem, i, true, false); + } + } + } + + // Remember for next time around + _lastMousePos = pos; + } + } + + protected void OnWM_MOUSELEAVE() + { + // Deselect the old draw command if not showing a child menu + if ((_trackItem != -1) && (_childMenu == null)) + { + // Modify the display of the two items + SwitchSelection(_trackItem, -1, false, false); + } + + // Reset flag so that next mouse move start monitor for mouse leave message + _mouseOver = false; + + // No point having a last mouse position + _lastMousePos = new Point(-1, -1); + } + + protected void OnWM_YBUTTONUP(int xPos, int yPos) + { + // Convert from screen to client coordinates + xPos -= _currentPoint.X; + yPos -= _currentPoint.Y; + + Point pos = new Point(xPos, yPos); + + for (int i = 0; i < _drawCommands.Count; i++) + { + DrawCommand dc = _drawCommands[i] as DrawCommand; + + if (dc.DrawRect.Contains(pos)) + { + // Is there a change in selected item? + if (_trackItem != i) + { + // Modify the display of the two items + SwitchSelection(_trackItem, i, false, false); + } + } + } + + // Is an item selected? + if (_trackItem != -1) + { + DrawCommand dc = _drawCommands[_trackItem] as DrawCommand; + + // Does this item have a submenu? + if (dc.SubMenu) + { + // If we are not already showing this submenu... + if (_popupItem != _trackItem) + { + // Is a submenu for a different item showing? + if (_childMenu != null) + { + // Inform the child menu it is no longer needed + //User32.PostMessage(_childMenu.Handle, WM_DISMISS, 0, 0); + } + + // Handle the submenu + OperateSubMenu(_trackItem, false); + } + } + else + { + if (dc.Expansion) + RegenerateExpansion(); + else + { + // Kill any child menus open + if (_childMenu != null) + { + // Inform the child menu it is no longer needed + //User32.PostMessage(_childMenu.Handle, WM_DISMISS, 0, 0); + } + + // Define the selection to return to caller + _returnCommand = dc.MenuCommand; + + // Finish processing messages + _timer.Stop(); + _exitLoop = true; + } + } + } + } + + protected void OnWM_MOUSEACTIVATE(ref Message m) + { + // Do not allow the mouse down to activate the window, but eat + // the message as we still want the mouse down for processing + m.Result = (IntPtr)Win32.MouseActivateFlags.MA_NOACTIVATE; + } + + protected void OnWM_SETCURSOR() + { + // Always use the arrow cursor + //User32.SetCursor(User32.LoadCursor(IntPtr.Zero, (uint)Win32.Cursors.IDC_ARROW)); + } + + protected void OnWM_DISMISS() + { + // Pass on to any child menu of ours + if (_childMenu != null) + { + // Inform the child menu it is no longer needed + //User32.PostMessage(_childMenu.Handle, WM_DISMISS, 0, 0); + } + + // Define the selection to return to caller + _returnCommand = null; + + // Finish processing messages + _timer.Stop(); + _exitLoop = true; + + // Hide ourself + HideMenuWindow(); + + // Kill ourself + DestroyHandle(); + } + + protected bool OnWM_NCHITTEST(ref Message m) + { + // Get mouse coordinates + Win32.POINT screenPos; + screenPos.x = (short)((uint)m.LParam & 0x0000FFFFU); + screenPos.y = (short)(((uint)m.LParam & 0xFFFF0000U) >> 16); + + // Only the IDE style has shadows + if (_style == VisualStyle.IDE) + { + Win32.POINT popupPos; + popupPos.x = _currentSize.Width - _position[(int)_style, (int)PI.ShadowWidth]; + popupPos.y = _currentSize.Height - _position[(int)_style, (int)PI.ShadowHeight]; + + // Convert the mouse position to screen coordinates + //User32.ClientToScreen(this.Handle, ref popupPos); + + // Is the mouse in the shadow areas? + if ((screenPos.x > popupPos.x) || + (screenPos.y > popupPos.y)) + { + // Allow actions to occur to window beneath us + m.Result = (IntPtr)Win32.HitTest.HTTRANSPARENT; + + return true; + } + } + + return false; + } + + protected override void WndProc(ref Message m) + { + // Console.WriteLine("WndProc(PopupMenu) {0} {1}", this.Handle, ((Win32.Msgs)m.Msg).ToString()); + + // WM_DISMISS is not a constant and so cannot be in a switch + if (m.Msg == WM_DISMISS) + OnWM_DISMISS(); + else if (m.Msg == WM_OPERATE_SUBMENU) + OnWM_OPERATE_SUBMENU(ref m); + else + { + // Want to notice when the window is maximized + switch (m.Msg) + { + case (int)Win32.Msgs.WM_ACTIVATEAPP: + OnWM_ACTIVATEAPP(ref m); + break; + + case (int)Win32.Msgs.WM_MOUSEACTIVATE: + OnWM_MOUSEACTIVATE(ref m); + break; + + case (int)Win32.Msgs.WM_PAINT: + OnWM_PAINT(ref m); + break; + + case (int)Win32.Msgs.WM_SETCURSOR: + OnWM_SETCURSOR(); + break; + + case (int)Win32.Msgs.WM_NCHITTEST: + if (!OnWM_NCHITTEST(ref m)) + base.WndProc(ref m); + break; + + default: + base.WndProc(ref m); + break; + } + } + } + + protected static Bitmap GetShadowCache(int width, int height) + { + // Do we already have a cached bitmap of the correct size? + if ((_shadowCacheWidth == width) && (_shadowCacheHeight == height) && (_shadowCache != null)) + return _shadowCache; + + // Dispose of any previously cached bitmap + if (_shadowCache != null) + _shadowCache.Dispose(); + + // Create our new bitmap with 32bpp so we have an alpha channel + Bitmap image = new Bitmap(width, height, PixelFormat.Format32bppArgb); + + // We want direct access to the bits so we can change values + BitmapData data = image.LockBits(new System.Drawing.Rectangle(0, 0, width, height), ImageLockMode.WriteOnly, PixelFormat.Format32bppArgb); + + unsafe + { + // Direct pointer to first line + uint* pixptr = (uint*)(data.Scan0); + + // For each row + for (int y = 0; y < height; y++) + { + int offset = data.Stride * y / 4; + + // Fade each line as we go down + int alphay = 64 * (height - y) / (height + 1); + + // For each column pixel + for (int x = 0; x < width; x++) + { + // Fade each pixel as we go across + int alphax = alphay * (width - x) / (width + 1); + pixptr[offset + x] = (uint)alphax << 24; + } + } + } + + image.UnlockBits(data); + + // Cache values for next time around + _shadowCache = image; + _shadowCacheWidth = width; + _shadowCacheHeight = height; + + return _shadowCache; + } + } +} \ No newline at end of file diff --git a/Labyrinth3/Crownwood.Magic/Resources/ImagesCaptionIDE.bmp b/Labyrinth3/Crownwood.Magic/Resources/ImagesCaptionIDE.bmp new file mode 100644 index 0000000..acd92c9 Binary files /dev/null and b/Labyrinth3/Crownwood.Magic/Resources/ImagesCaptionIDE.bmp differ diff --git a/Labyrinth3/Crownwood.Magic/Resources/ImagesCaptionPlain.bmp b/Labyrinth3/Crownwood.Magic/Resources/ImagesCaptionPlain.bmp new file mode 100644 index 0000000..9e5d76c Binary files /dev/null and b/Labyrinth3/Crownwood.Magic/Resources/ImagesCaptionPlain.bmp differ diff --git a/Labyrinth3/Crownwood.Magic/Resources/ImagesMenuControl.bmp b/Labyrinth3/Crownwood.Magic/Resources/ImagesMenuControl.bmp new file mode 100644 index 0000000..b0b0c53 Binary files /dev/null and b/Labyrinth3/Crownwood.Magic/Resources/ImagesMenuControl.bmp differ diff --git a/Labyrinth3/Crownwood.Magic/Resources/ImagesPopupMenu.bmp b/Labyrinth3/Crownwood.Magic/Resources/ImagesPopupMenu.bmp new file mode 100644 index 0000000..f175c2d Binary files /dev/null and b/Labyrinth3/Crownwood.Magic/Resources/ImagesPopupMenu.bmp differ diff --git a/Labyrinth3/Crownwood.Magic/Resources/ImagesTabControl.bmp b/Labyrinth3/Crownwood.Magic/Resources/ImagesTabControl.bmp new file mode 100644 index 0000000..a7f2649 Binary files /dev/null and b/Labyrinth3/Crownwood.Magic/Resources/ImagesTabControl.bmp differ diff --git a/Labyrinth3/Crownwood.Magic/Resources/ImagesTabbedGroups.bmp b/Labyrinth3/Crownwood.Magic/Resources/ImagesTabbedGroups.bmp new file mode 100644 index 0000000..c7ae2c4 Binary files /dev/null and b/Labyrinth3/Crownwood.Magic/Resources/ImagesTabbedGroups.bmp differ diff --git a/Labyrinth3/Crownwood.Magic/Resources/LibraryIcon.ico b/Labyrinth3/Crownwood.Magic/Resources/LibraryIcon.ico new file mode 100644 index 0000000..288312f Binary files /dev/null and b/Labyrinth3/Crownwood.Magic/Resources/LibraryIcon.ico differ diff --git a/Labyrinth3/Crownwood.Magic/Resources/TabbedInvalid.cur b/Labyrinth3/Crownwood.Magic/Resources/TabbedInvalid.cur new file mode 100644 index 0000000..ce1e7b0 Binary files /dev/null and b/Labyrinth3/Crownwood.Magic/Resources/TabbedInvalid.cur differ diff --git a/Labyrinth3/Crownwood.Magic/Resources/TabbedValid.cur b/Labyrinth3/Crownwood.Magic/Resources/TabbedValid.cur new file mode 100644 index 0000000..f8933de Binary files /dev/null and b/Labyrinth3/Crownwood.Magic/Resources/TabbedValid.cur differ diff --git a/Labyrinth3/Crownwood.Magic/Resources/WizardPicture.bmp b/Labyrinth3/Crownwood.Magic/Resources/WizardPicture.bmp new file mode 100644 index 0000000..0d5abcd Binary files /dev/null and b/Labyrinth3/Crownwood.Magic/Resources/WizardPicture.bmp differ diff --git a/Labyrinth3/Crownwood.Magic/Win32/Enums.cs b/Labyrinth3/Crownwood.Magic/Win32/Enums.cs new file mode 100644 index 0000000..4e4f1a1 --- /dev/null +++ b/Labyrinth3/Crownwood.Magic/Win32/Enums.cs @@ -0,0 +1,780 @@ +// ***************************************************************************** +// +// (c) Crownwood Consulting Limited 2002-2003 +// All rights reserved. The software and associated documentation +// supplied hereunder are the proprietary information of Crownwood Consulting +// Limited, Crownwood, Bracknell, Berkshire, England and are supplied subject +// to licence terms. +// +// Magic Version 1.7.4.0 www.dotnetmagic.com +// ***************************************************************************** + +namespace Crownwood.Magic.Win32 +{ + public enum PeekMessageFlags + { + PM_NOREMOVE = 0, + PM_REMOVE = 1, + PM_NOYIELD = 2 + } + + public enum SetWindowPosFlags : uint + { + SWP_NOSIZE = 0x0001, + SWP_NOMOVE = 0x0002, + SWP_NOZORDER = 0x0004, + SWP_NOREDRAW = 0x0008, + SWP_NOACTIVATE = 0x0010, + SWP_FRAMECHANGED = 0x0020, + SWP_SHOWWINDOW = 0x0040, + SWP_HIDEWINDOW = 0x0080, + SWP_NOCOPYBITS = 0x0100, + SWP_NOOWNERZORDER = 0x0200, + SWP_NOSENDCHANGING = 0x0400, + SWP_DRAWFRAME = 0x0020, + SWP_NOREPOSITION = 0x0200, + SWP_DEFERERASE = 0x2000, + SWP_ASYNCWINDOWPOS = 0x4000 + } + + public enum SetWindowPosZ + { + HWND_TOP = 0, + HWND_BOTTOM = 1, + HWND_TOPMOST = -1, + HWND_NOTOPMOST = -2 + } + + public enum ShowWindowStyles : short + { + SW_HIDE = 0, + SW_SHOWNORMAL = 1, + SW_NORMAL = 1, + SW_SHOWMINIMIZED = 2, + SW_SHOWMAXIMIZED = 3, + SW_MAXIMIZE = 3, + SW_SHOWNOACTIVATE = 4, + SW_SHOW = 5, + SW_MINIMIZE = 6, + SW_SHOWMINNOACTIVE = 7, + SW_SHOWNA = 8, + SW_RESTORE = 9, + SW_SHOWDEFAULT = 10, + SW_FORCEMINIMIZE = 11, + SW_MAX = 11 + } + + public enum WindowStyles : uint + { + WS_OVERLAPPED = 0x00000000, + WS_POPUP = 0x80000000, + WS_CHILD = 0x40000000, + WS_MINIMIZE = 0x20000000, + WS_VISIBLE = 0x10000000, + WS_DISABLED = 0x08000000, + WS_CLIPSIBLINGS = 0x04000000, + WS_CLIPCHILDREN = 0x02000000, + WS_MAXIMIZE = 0x01000000, + WS_CAPTION = 0x00C00000, + WS_BORDER = 0x00800000, + WS_DLGFRAME = 0x00400000, + WS_VSCROLL = 0x00200000, + WS_HSCROLL = 0x00100000, + WS_SYSMENU = 0x00080000, + WS_THICKFRAME = 0x00040000, + WS_GROUP = 0x00020000, + WS_TABSTOP = 0x00010000, + WS_MINIMIZEBOX = 0x00020000, + WS_MAXIMIZEBOX = 0x00010000, + WS_TILED = 0x00000000, + WS_ICONIC = 0x20000000, + WS_SIZEBOX = 0x00040000, + WS_POPUPWINDOW = 0x80880000, + WS_OVERLAPPEDWINDOW = 0x00CF0000, + WS_TILEDWINDOW = 0x00CF0000, + WS_CHILDWINDOW = 0x40000000 + } + + public enum WindowExStyles + { + WS_EX_DLGMODALFRAME = 0x00000001, + WS_EX_NOPARENTNOTIFY = 0x00000004, + WS_EX_TOPMOST = 0x00000008, + WS_EX_ACCEPTFILES = 0x00000010, + WS_EX_TRANSPARENT = 0x00000020, + WS_EX_MDICHILD = 0x00000040, + WS_EX_TOOLWINDOW = 0x00000080, + WS_EX_WINDOWEDGE = 0x00000100, + WS_EX_CLIENTEDGE = 0x00000200, + WS_EX_CONTEXTHELP = 0x00000400, + WS_EX_RIGHT = 0x00001000, + WS_EX_LEFT = 0x00000000, + WS_EX_RTLREADING = 0x00002000, + WS_EX_LTRREADING = 0x00000000, + WS_EX_LEFTSCROLLBAR = 0x00004000, + WS_EX_RIGHTSCROLLBAR = 0x00000000, + WS_EX_CONTROLPARENT = 0x00010000, + WS_EX_STATICEDGE = 0x00020000, + WS_EX_APPWINDOW = 0x00040000, + WS_EX_OVERLAPPEDWINDOW = 0x00000300, + WS_EX_PALETTEWINDOW = 0x00000188, + WS_EX_LAYERED = 0x00080000 + } + + public enum VirtualKeys + { + VK_LBUTTON = 0x01, + VK_CANCEL = 0x03, + VK_BACK = 0x08, + VK_TAB = 0x09, + VK_CLEAR = 0x0C, + VK_RETURN = 0x0D, + VK_SHIFT = 0x10, + VK_CONTROL = 0x11, + VK_MENU = 0x12, + VK_CAPITAL = 0x14, + VK_ESCAPE = 0x1B, + VK_SPACE = 0x20, + VK_PRIOR = 0x21, + VK_NEXT = 0x22, + VK_END = 0x23, + VK_HOME = 0x24, + VK_LEFT = 0x25, + VK_UP = 0x26, + VK_RIGHT = 0x27, + VK_DOWN = 0x28, + VK_SELECT = 0x29, + VK_EXECUTE = 0x2B, + VK_SNAPSHOT = 0x2C, + VK_HELP = 0x2F, + VK_0 = 0x30, + VK_1 = 0x31, + VK_2 = 0x32, + VK_3 = 0x33, + VK_4 = 0x34, + VK_5 = 0x35, + VK_6 = 0x36, + VK_7 = 0x37, + VK_8 = 0x38, + VK_9 = 0x39, + VK_A = 0x41, + VK_B = 0x42, + VK_C = 0x43, + VK_D = 0x44, + VK_E = 0x45, + VK_F = 0x46, + VK_G = 0x47, + VK_H = 0x48, + VK_I = 0x49, + VK_J = 0x4A, + VK_K = 0x4B, + VK_L = 0x4C, + VK_M = 0x4D, + VK_N = 0x4E, + VK_O = 0x4F, + VK_P = 0x50, + VK_Q = 0x51, + VK_R = 0x52, + VK_S = 0x53, + VK_T = 0x54, + VK_U = 0x55, + VK_V = 0x56, + VK_W = 0x57, + VK_X = 0x58, + VK_Y = 0x59, + VK_Z = 0x5A, + VK_NUMPAD0 = 0x60, + VK_NUMPAD1 = 0x61, + VK_NUMPAD2 = 0x62, + VK_NUMPAD3 = 0x63, + VK_NUMPAD4 = 0x64, + VK_NUMPAD5 = 0x65, + VK_NUMPAD6 = 0x66, + VK_NUMPAD7 = 0x67, + VK_NUMPAD8 = 0x68, + VK_NUMPAD9 = 0x69, + VK_MULTIPLY = 0x6A, + VK_ADD = 0x6B, + VK_SEPARATOR = 0x6C, + VK_SUBTRACT = 0x6D, + VK_DECIMAL = 0x6E, + VK_DIVIDE = 0x6F, + VK_ATTN = 0xF6, + VK_CRSEL = 0xF7, + VK_EXSEL = 0xF8, + VK_EREOF = 0xF9, + VK_PLAY = 0xFA, + VK_ZOOM = 0xFB, + VK_NONAME = 0xFC, + VK_PA1 = 0xFD, + VK_OEM_CLEAR = 0xFE, + VK_LWIN = 0x5B, + VK_RWIN = 0x5C, + VK_APPS = 0x5D, + VK_LSHIFT = 0xA0, + VK_RSHIFT = 0xA1, + VK_LCONTROL = 0xA2, + VK_RCONTROL = 0xA3, + VK_LMENU = 0xA4, + VK_RMENU = 0xA5 + } + + public enum Msgs + { + WM_NULL = 0x0000, + WM_CREATE = 0x0001, + WM_DESTROY = 0x0002, + WM_MOVE = 0x0003, + WM_SIZE = 0x0005, + WM_ACTIVATE = 0x0006, + WM_SETFOCUS = 0x0007, + WM_KILLFOCUS = 0x0008, + WM_ENABLE = 0x000A, + WM_SETREDRAW = 0x000B, + WM_SETTEXT = 0x000C, + WM_GETTEXT = 0x000D, + WM_GETTEXTLENGTH = 0x000E, + WM_PAINT = 0x000F, + WM_CLOSE = 0x0010, + WM_QUERYENDSESSION = 0x0011, + WM_QUIT = 0x0012, + WM_QUERYOPEN = 0x0013, + WM_ERASEBKGND = 0x0014, + WM_SYSCOLORCHANGE = 0x0015, + WM_ENDSESSION = 0x0016, + WM_SHOWWINDOW = 0x0018, + WM_WININICHANGE = 0x001A, + WM_SETTINGCHANGE = 0x001A, + WM_DEVMODECHANGE = 0x001B, + WM_ACTIVATEAPP = 0x001C, + WM_FONTCHANGE = 0x001D, + WM_TIMECHANGE = 0x001E, + WM_CANCELMODE = 0x001F, + WM_SETCURSOR = 0x0020, + WM_MOUSEACTIVATE = 0x0021, + WM_CHILDACTIVATE = 0x0022, + WM_QUEUESYNC = 0x0023, + WM_GETMINMAXINFO = 0x0024, + WM_PAINTICON = 0x0026, + WM_ICONERASEBKGND = 0x0027, + WM_NEXTDLGCTL = 0x0028, + WM_SPOOLERSTATUS = 0x002A, + WM_DRAWITEM = 0x002B, + WM_MEASUREITEM = 0x002C, + WM_DELETEITEM = 0x002D, + WM_VKEYTOITEM = 0x002E, + WM_CHARTOITEM = 0x002F, + WM_SETFONT = 0x0030, + WM_GETFONT = 0x0031, + WM_SETHOTKEY = 0x0032, + WM_GETHOTKEY = 0x0033, + WM_QUERYDRAGICON = 0x0037, + WM_COMPAREITEM = 0x0039, + WM_GETOBJECT = 0x003D, + WM_COMPACTING = 0x0041, + WM_COMMNOTIFY = 0x0044, + WM_WINDOWPOSCHANGING = 0x0046, + WM_WINDOWPOSCHANGED = 0x0047, + WM_POWER = 0x0048, + WM_COPYDATA = 0x004A, + WM_CANCELJOURNAL = 0x004B, + WM_NOTIFY = 0x004E, + WM_INPUTLANGCHANGEREQUEST = 0x0050, + WM_INPUTLANGCHANGE = 0x0051, + WM_TCARD = 0x0052, + WM_HELP = 0x0053, + WM_USERCHANGED = 0x0054, + WM_NOTIFYFORMAT = 0x0055, + WM_CONTEXTMENU = 0x007B, + WM_STYLECHANGING = 0x007C, + WM_STYLECHANGED = 0x007D, + WM_DISPLAYCHANGE = 0x007E, + WM_GETICON = 0x007F, + WM_SETICON = 0x0080, + WM_NCCREATE = 0x0081, + WM_NCDESTROY = 0x0082, + WM_NCCALCSIZE = 0x0083, + WM_NCHITTEST = 0x0084, + WM_NCPAINT = 0x0085, + WM_NCACTIVATE = 0x0086, + WM_GETDLGCODE = 0x0087, + WM_SYNCPAINT = 0x0088, + WM_NCMOUSEMOVE = 0x00A0, + WM_NCLBUTTONDOWN = 0x00A1, + WM_NCLBUTTONUP = 0x00A2, + WM_NCLBUTTONDBLCLK = 0x00A3, + WM_NCRBUTTONDOWN = 0x00A4, + WM_NCRBUTTONUP = 0x00A5, + WM_NCRBUTTONDBLCLK = 0x00A6, + WM_NCMBUTTONDOWN = 0x00A7, + WM_NCMBUTTONUP = 0x00A8, + WM_NCMBUTTONDBLCLK = 0x00A9, + WM_NCXBUTTONDOWN = 0x00AB, + WM_NCXBUTTONUP = 0x00AC, + WM_KEYDOWN = 0x0100, + WM_KEYUP = 0x0101, + WM_CHAR = 0x0102, + WM_DEADCHAR = 0x0103, + WM_SYSKEYDOWN = 0x0104, + WM_SYSKEYUP = 0x0105, + WM_SYSCHAR = 0x0106, + WM_SYSDEADCHAR = 0x0107, + WM_KEYLAST = 0x0108, + WM_IME_STARTCOMPOSITION = 0x010D, + WM_IME_ENDCOMPOSITION = 0x010E, + WM_IME_COMPOSITION = 0x010F, + WM_IME_KEYLAST = 0x010F, + WM_INITDIALOG = 0x0110, + WM_COMMAND = 0x0111, + WM_SYSCOMMAND = 0x0112, + WM_TIMER = 0x0113, + WM_HSCROLL = 0x0114, + WM_VSCROLL = 0x0115, + WM_INITMENU = 0x0116, + WM_INITMENUPOPUP = 0x0117, + WM_MENUSELECT = 0x011F, + WM_MENUCHAR = 0x0120, + WM_ENTERIDLE = 0x0121, + WM_MENURBUTTONUP = 0x0122, + WM_MENUDRAG = 0x0123, + WM_MENUGETOBJECT = 0x0124, + WM_UNINITMENUPOPUP = 0x0125, + WM_MENUCOMMAND = 0x0126, + WM_CTLCOLORMSGBOX = 0x0132, + WM_CTLCOLOREDIT = 0x0133, + WM_CTLCOLORLISTBOX = 0x0134, + WM_CTLCOLORBTN = 0x0135, + WM_CTLCOLORDLG = 0x0136, + WM_CTLCOLORSCROLLBAR = 0x0137, + WM_CTLCOLORSTATIC = 0x0138, + WM_MOUSEMOVE = 0x0200, + WM_LBUTTONDOWN = 0x0201, + WM_LBUTTONUP = 0x0202, + WM_LBUTTONDBLCLK = 0x0203, + WM_RBUTTONDOWN = 0x0204, + WM_RBUTTONUP = 0x0205, + WM_RBUTTONDBLCLK = 0x0206, + WM_MBUTTONDOWN = 0x0207, + WM_MBUTTONUP = 0x0208, + WM_MBUTTONDBLCLK = 0x0209, + WM_MOUSEWHEEL = 0x020A, + WM_XBUTTONDOWN = 0x020B, + WM_XBUTTONUP = 0x020C, + WM_XBUTTONDBLCLK = 0x020D, + WM_PARENTNOTIFY = 0x0210, + WM_ENTERMENULOOP = 0x0211, + WM_EXITMENULOOP = 0x0212, + WM_NEXTMENU = 0x0213, + WM_SIZING = 0x0214, + WM_CAPTURECHANGED = 0x0215, + WM_MOVING = 0x0216, + WM_DEVICECHANGE = 0x0219, + WM_MDICREATE = 0x0220, + WM_MDIDESTROY = 0x0221, + WM_MDIACTIVATE = 0x0222, + WM_MDIRESTORE = 0x0223, + WM_MDINEXT = 0x0224, + WM_MDIMAXIMIZE = 0x0225, + WM_MDITILE = 0x0226, + WM_MDICASCADE = 0x0227, + WM_MDIICONARRANGE = 0x0228, + WM_MDIGETACTIVE = 0x0229, + WM_MDISETMENU = 0x0230, + WM_ENTERSIZEMOVE = 0x0231, + WM_EXITSIZEMOVE = 0x0232, + WM_DROPFILES = 0x0233, + WM_MDIREFRESHMENU = 0x0234, + WM_IME_SETCONTEXT = 0x0281, + WM_IME_NOTIFY = 0x0282, + WM_IME_CONTROL = 0x0283, + WM_IME_COMPOSITIONFULL = 0x0284, + WM_IME_SELECT = 0x0285, + WM_IME_CHAR = 0x0286, + WM_IME_REQUEST = 0x0288, + WM_IME_KEYDOWN = 0x0290, + WM_IME_KEYUP = 0x0291, + WM_MOUSEHOVER = 0x02A1, + WM_MOUSELEAVE = 0x02A3, + WM_CUT = 0x0300, + WM_COPY = 0x0301, + WM_PASTE = 0x0302, + WM_CLEAR = 0x0303, + WM_UNDO = 0x0304, + WM_RENDERFORMAT = 0x0305, + WM_RENDERALLFORMATS = 0x0306, + WM_DESTROYCLIPBOARD = 0x0307, + WM_DRAWCLIPBOARD = 0x0308, + WM_PAINTCLIPBOARD = 0x0309, + WM_VSCROLLCLIPBOARD = 0x030A, + WM_SIZECLIPBOARD = 0x030B, + WM_ASKCBFORMATNAME = 0x030C, + WM_CHANGECBCHAIN = 0x030D, + WM_HSCROLLCLIPBOARD = 0x030E, + WM_QUERYNEWPALETTE = 0x030F, + WM_PALETTEISCHANGING = 0x0310, + WM_PALETTECHANGED = 0x0311, + WM_HOTKEY = 0x0312, + WM_PRINT = 0x0317, + WM_PRINTCLIENT = 0x0318, + WM_HANDHELDFIRST = 0x0358, + WM_HANDHELDLAST = 0x035F, + WM_AFXFIRST = 0x0360, + WM_AFXLAST = 0x037F, + WM_PENWINFIRST = 0x0380, + WM_PENWINLAST = 0x038F, + WM_APP = 0x8000, + WM_USER = 0x0400 + } + + public enum Cursors : uint + { + IDC_ARROW = 32512U, + IDC_IBEAM = 32513U, + IDC_WAIT = 32514U, + IDC_CROSS = 32515U, + IDC_UPARROW = 32516U, + IDC_SIZE = 32640U, + IDC_ICON = 32641U, + IDC_SIZENWSE = 32642U, + IDC_SIZENESW = 32643U, + IDC_SIZEWE = 32644U, + IDC_SIZENS = 32645U, + IDC_SIZEALL = 32646U, + IDC_NO = 32648U, + IDC_HAND = 32649U, + IDC_APPSTARTING = 32650U, + IDC_HELP = 32651U + } + + public enum TrackerEventFlags : uint + { + TME_HOVER = 0x00000001, + TME_LEAVE = 0x00000002, + TME_QUERY = 0x40000000, + TME_CANCEL = 0x80000000 + } + + public enum MouseActivateFlags + { + MA_ACTIVATE = 1, + MA_ACTIVATEANDEAT = 2, + MA_NOACTIVATE = 3, + MA_NOACTIVATEANDEAT = 4 + } + + public enum DialogCodes + { + DLGC_WANTARROWS = 0x0001, + DLGC_WANTTAB = 0x0002, + DLGC_WANTALLKEYS = 0x0004, + DLGC_WANTMESSAGE = 0x0004, + DLGC_HASSETSEL = 0x0008, + DLGC_DEFPUSHBUTTON = 0x0010, + DLGC_UNDEFPUSHBUTTON = 0x0020, + DLGC_RADIOBUTTON = 0x0040, + DLGC_WANTCHARS = 0x0080, + DLGC_STATIC = 0x0100, + DLGC_BUTTON = 0x2000 + } + + public enum UpdateLayeredWindowsFlags + { + ULW_COLORKEY = 0x00000001, + ULW_ALPHA = 0x00000002, + ULW_OPAQUE = 0x00000004 + } + + public enum AlphaFlags : byte + { + AC_SRC_OVER = 0x00, + AC_SRC_ALPHA = 0x01 + } + + public enum RasterOperations : uint + { + SRCCOPY = 0x00CC0020, + SRCPAINT = 0x00EE0086, + SRCAND = 0x008800C6, + SRCINVERT = 0x00660046, + SRCERASE = 0x00440328, + NOTSRCCOPY = 0x00330008, + NOTSRCERASE = 0x001100A6, + MERGECOPY = 0x00C000CA, + MERGEPAINT = 0x00BB0226, + PATCOPY = 0x00F00021, + PATPAINT = 0x00FB0A09, + PATINVERT = 0x005A0049, + DSTINVERT = 0x00550009, + BLACKNESS = 0x00000042, + WHITENESS = 0x00FF0062 + } + + public enum BrushStyles + { + BS_SOLID = 0, + BS_NULL = 1, + BS_HOLLOW = 1, + BS_HATCHED = 2, + BS_PATTERN = 3, + BS_INDEXED = 4, + BS_DIBPATTERN = 5, + BS_DIBPATTERNPT = 6, + BS_PATTERN8X8 = 7, + BS_DIBPATTERN8X8 = 8, + BS_MONOPATTERN = 9 + } + + public enum HatchStyles + { + HS_HORIZONTAL = 0, + HS_VERTICAL = 1, + HS_FDIAGONAL = 2, + HS_BDIAGONAL = 3, + HS_CROSS = 4, + HS_DIAGCROSS = 5 + } + + public enum CombineFlags + { + RGN_AND = 1, + RGN_OR = 2, + RGN_XOR = 3, + RGN_DIFF = 4, + RGN_COPY = 5 + } + + public enum HitTest + { + HTERROR = -2, + HTTRANSPARENT = -1, + HTNOWHERE = 0, + HTCLIENT = 1, + HTCAPTION = 2, + HTSYSMENU = 3, + HTGROWBOX = 4, + HTSIZE = 4, + HTMENU = 5, + HTHSCROLL = 6, + HTVSCROLL = 7, + HTMINBUTTON = 8, + HTMAXBUTTON = 9, + HTLEFT = 10, + HTRIGHT = 11, + HTTOP = 12, + HTTOPLEFT = 13, + HTTOPRIGHT = 14, + HTBOTTOM = 15, + HTBOTTOMLEFT = 16, + HTBOTTOMRIGHT = 17, + HTBORDER = 18, + HTREDUCE = 8, + HTZOOM = 9, + HTSIZEFIRST = 10, + HTSIZELAST = 17, + HTOBJECT = 19, + HTCLOSE = 20, + HTHELP = 21 + } + + public enum AnimateFlags + { + AW_HOR_POSITIVE = 0x00000001, + AW_HOR_NEGATIVE = 0x00000002, + AW_VER_POSITIVE = 0x00000004, + AW_VER_NEGATIVE = 0x00000008, + AW_CENTER = 0x00000010, + AW_HIDE = 0x00010000, + AW_ACTIVATE = 0x00020000, + AW_SLIDE = 0x00040000, + AW_BLEND = 0x00080000 + } + + public enum GetWindowLongFlags + { + GWL_WNDPROC = -4, + GWL_HINSTANCE = -6, + GWL_HWNDPARENT = -8, + GWL_STYLE = -16, + GWL_EXSTYLE = -20, + GWL_USERDATA = -21, + GWL_ID = -12 + } + + public enum SPIActions + { + SPI_GETBEEP = 0x0001, + SPI_SETBEEP = 0x0002, + SPI_GETMOUSE = 0x0003, + SPI_SETMOUSE = 0x0004, + SPI_GETBORDER = 0x0005, + SPI_SETBORDER = 0x0006, + SPI_GETKEYBOARDSPEED = 0x000A, + SPI_SETKEYBOARDSPEED = 0x000B, + SPI_LANGDRIVER = 0x000C, + SPI_ICONHORIZONTALSPACING = 0x000D, + SPI_GETSCREENSAVETIMEOUT = 0x000E, + SPI_SETSCREENSAVETIMEOUT = 0x000F, + SPI_GETSCREENSAVEACTIVE = 0x0010, + SPI_SETSCREENSAVEACTIVE = 0x0011, + SPI_GETGRIDGRANULARITY = 0x0012, + SPI_SETGRIDGRANULARITY = 0x0013, + SPI_SETDESKWALLPAPER = 0x0014, + SPI_SETDESKPATTERN = 0x0015, + SPI_GETKEYBOARDDELAY = 0x0016, + SPI_SETKEYBOARDDELAY = 0x0017, + SPI_ICONVERTICALSPACING = 0x0018, + SPI_GETICONTITLEWRAP = 0x0019, + SPI_SETICONTITLEWRAP = 0x001A, + SPI_GETMENUDROPALIGNMENT = 0x001B, + SPI_SETMENUDROPALIGNMENT = 0x001C, + SPI_SETDOUBLECLKWIDTH = 0x001D, + SPI_SETDOUBLECLKHEIGHT = 0x001E, + SPI_GETICONTITLELOGFONT = 0x001F, + SPI_SETDOUBLECLICKTIME = 0x0020, + SPI_SETMOUSEBUTTONSWAP = 0x0021, + SPI_SETICONTITLELOGFONT = 0x0022, + SPI_GETFASTTASKSWITCH = 0x0023, + SPI_SETFASTTASKSWITCH = 0x0024, + SPI_SETDRAGFULLWINDOWS = 0x0025, + SPI_GETDRAGFULLWINDOWS = 0x0026, + SPI_GETNONCLIENTMETRICS = 0x0029, + SPI_SETNONCLIENTMETRICS = 0x002A, + SPI_GETMINIMIZEDMETRICS = 0x002B, + SPI_SETMINIMIZEDMETRICS = 0x002C, + SPI_GETICONMETRICS = 0x002D, + SPI_SETICONMETRICS = 0x002E, + SPI_SETWORKAREA = 0x002F, + SPI_GETWORKAREA = 0x0030, + SPI_SETPENWINDOWS = 0x0031, + SPI_GETHIGHCONTRAST = 0x0042, + SPI_SETHIGHCONTRAST = 0x0043, + SPI_GETKEYBOARDPREF = 0x0044, + SPI_SETKEYBOARDPREF = 0x0045, + SPI_GETSCREENREADER = 0x0046, + SPI_SETSCREENREADER = 0x0047, + SPI_GETANIMATION = 0x0048, + SPI_SETANIMATION = 0x0049, + SPI_GETFONTSMOOTHING = 0x004A, + SPI_SETFONTSMOOTHING = 0x004B, + SPI_SETDRAGWIDTH = 0x004C, + SPI_SETDRAGHEIGHT = 0x004D, + SPI_SETHANDHELD = 0x004E, + SPI_GETLOWPOWERTIMEOUT = 0x004F, + SPI_GETPOWEROFFTIMEOUT = 0x0050, + SPI_SETLOWPOWERTIMEOUT = 0x0051, + SPI_SETPOWEROFFTIMEOUT = 0x0052, + SPI_GETLOWPOWERACTIVE = 0x0053, + SPI_GETPOWEROFFACTIVE = 0x0054, + SPI_SETLOWPOWERACTIVE = 0x0055, + SPI_SETPOWEROFFACTIVE = 0x0056, + SPI_SETCURSORS = 0x0057, + SPI_SETICONS = 0x0058, + SPI_GETDEFAULTINPUTLANG = 0x0059, + SPI_SETDEFAULTINPUTLANG = 0x005A, + SPI_SETLANGTOGGLE = 0x005B, + SPI_GETWINDOWSEXTENSION = 0x005C, + SPI_SETMOUSETRAILS = 0x005D, + SPI_GETMOUSETRAILS = 0x005E, + SPI_SETSCREENSAVERRUNNING = 0x0061, + SPI_SCREENSAVERRUNNING = 0x0061, + SPI_GETFILTERKEYS = 0x0032, + SPI_SETFILTERKEYS = 0x0033, + SPI_GETTOGGLEKEYS = 0x0034, + SPI_SETTOGGLEKEYS = 0x0035, + SPI_GETMOUSEKEYS = 0x0036, + SPI_SETMOUSEKEYS = 0x0037, + SPI_GETSHOWSOUNDS = 0x0038, + SPI_SETSHOWSOUNDS = 0x0039, + SPI_GETSTICKYKEYS = 0x003A, + SPI_SETSTICKYKEYS = 0x003B, + SPI_GETACCESSTIMEOUT = 0x003C, + SPI_SETACCESSTIMEOUT = 0x003D, + SPI_GETSERIALKEYS = 0x003E, + SPI_SETSERIALKEYS = 0x003F, + SPI_GETSOUNDSENTRY = 0x0040, + SPI_SETSOUNDSENTRY = 0x0041, + SPI_GETSNAPTODEFBUTTON = 0x005F, + SPI_SETSNAPTODEFBUTTON = 0x0060, + SPI_GETMOUSEHOVERWIDTH = 0x0062, + SPI_SETMOUSEHOVERWIDTH = 0x0063, + SPI_GETMOUSEHOVERHEIGHT = 0x0064, + SPI_SETMOUSEHOVERHEIGHT = 0x0065, + SPI_GETMOUSEHOVERTIME = 0x0066, + SPI_SETMOUSEHOVERTIME = 0x0067, + SPI_GETWHEELSCROLLLINES = 0x0068, + SPI_SETWHEELSCROLLLINES = 0x0069, + SPI_GETMENUSHOWDELAY = 0x006A, + SPI_SETMENUSHOWDELAY = 0x006B, + SPI_GETSHOWIMEUI = 0x006E, + SPI_SETSHOWIMEUI = 0x006F, + SPI_GETMOUSESPEED = 0x0070, + SPI_SETMOUSESPEED = 0x0071, + SPI_GETSCREENSAVERRUNNING = 0x0072, + SPI_GETDESKWALLPAPER = 0x0073, + SPI_GETACTIVEWINDOWTRACKING = 0x1000, + SPI_SETACTIVEWINDOWTRACKING = 0x1001, + SPI_GETMENUANIMATION = 0x1002, + SPI_SETMENUANIMATION = 0x1003, + SPI_GETCOMBOBOXANIMATION = 0x1004, + SPI_SETCOMBOBOXANIMATION = 0x1005, + SPI_GETLISTBOXSMOOTHSCROLLING = 0x1006, + SPI_SETLISTBOXSMOOTHSCROLLING = 0x1007, + SPI_GETGRADIENTCAPTIONS = 0x1008, + SPI_SETGRADIENTCAPTIONS = 0x1009, + SPI_GETKEYBOARDCUES = 0x100A, + SPI_SETKEYBOARDCUES = 0x100B, + SPI_GETMENUUNDERLINES = 0x100A, + SPI_SETMENUUNDERLINES = 0x100B, + SPI_GETACTIVEWNDTRKZORDER = 0x100C, + SPI_SETACTIVEWNDTRKZORDER = 0x100D, + SPI_GETHOTTRACKING = 0x100E, + SPI_SETHOTTRACKING = 0x100F, + SPI_GETMENUFADE = 0x1012, + SPI_SETMENUFADE = 0x1013, + SPI_GETSELECTIONFADE = 0x1014, + SPI_SETSELECTIONFADE = 0x1015, + SPI_GETTOOLTIPANIMATION = 0x1016, + SPI_SETTOOLTIPANIMATION = 0x1017, + SPI_GETTOOLTIPFADE = 0x1018, + SPI_SETTOOLTIPFADE = 0x1019, + SPI_GETCURSORSHADOW = 0x101A, + SPI_SETCURSORSHADOW = 0x101B, + SPI_GETMOUSESONAR = 0x101C, + SPI_SETMOUSESONAR = 0x101D, + SPI_GETMOUSECLICKLOCK = 0x101E, + SPI_SETMOUSECLICKLOCK = 0x101F, + SPI_GETMOUSEVANISH = 0x1020, + SPI_SETMOUSEVANISH = 0x1021, + SPI_GETFLATMENU = 0x1022, + SPI_SETFLATMENU = 0x1023, + SPI_GETDROPSHADOW = 0x1024, + SPI_SETDROPSHADOW = 0x1025, + SPI_GETUIEFFECTS = 0x103E, + SPI_SETUIEFFECTS = 0x103F, + SPI_GETFOREGROUNDLOCKTIMEOUT = 0x2000, + SPI_SETFOREGROUNDLOCKTIMEOUT = 0x2001, + SPI_GETACTIVEWNDTRKTIMEOUT = 0x2002, + SPI_SETACTIVEWNDTRKTIMEOUT = 0x2003, + SPI_GETFOREGROUNDFLASHCOUNT = 0x2004, + SPI_SETFOREGROUNDFLASHCOUNT = 0x2005, + SPI_GETCARETWIDTH = 0x2006, + SPI_SETCARETWIDTH = 0x2007, + SPI_GETMOUSECLICKLOCKTIME = 0x2008, + SPI_SETMOUSECLICKLOCKTIME = 0x2009, + SPI_GETFONTSMOOTHINGTYPE = 0x200A, + SPI_SETFONTSMOOTHINGTYPE = 0x200B, + SPI_GETFONTSMOOTHINGCONTRAST = 0x200C, + SPI_SETFONTSMOOTHINGCONTRAST = 0x200D, + SPI_GETFOCUSBORDERWIDTH = 0x200E, + SPI_SETFOCUSBORDERWIDTH = 0x200F, + SPI_GETFOCUSBORDERHEIGHT = 0x2010, + SPI_SETFOCUSBORDERHEIGHT = 0x2011 + } + + public enum SPIWinINIFlags + { + SPIF_UPDATEINIFILE = 0x0001, + SPIF_SENDWININICHANGE = 0x0002, + SPIF_SENDCHANGE = 0x0002 + } +} \ No newline at end of file diff --git a/Labyrinth3/Crownwood.Magic/Win32/Gdi32.cs b/Labyrinth3/Crownwood.Magic/Win32/Gdi32.cs new file mode 100644 index 0000000..16eb129 --- /dev/null +++ b/Labyrinth3/Crownwood.Magic/Win32/Gdi32.cs @@ -0,0 +1,49 @@ +// ***************************************************************************** +// +// (c) Crownwood Consulting Limited 2002-2003 +// All rights reserved. The software and associated documentation +// supplied hereunder are the proprietary information of Crownwood Consulting +// Limited, Crownwood, Bracknell, Berkshire, England and are supplied subject +// to licence terms. +// +// Magic Version 1.7.4.0 www.dotnetmagic.com +// ***************************************************************************** + +using System; +using System.Runtime.InteropServices; + +namespace Crownwood.Magic.Win32 +{ + public class Gdi32 + { + [DllImport("gdi32.dll", CharSet = CharSet.Auto)] + public static extern int CombineRgn(IntPtr dest, IntPtr src1, IntPtr src2, int flags); + + [DllImport("gdi32.dll", CharSet = CharSet.Auto)] + public static extern IntPtr CreateRectRgnIndirect(ref Win32.RECT rect); + + [DllImport("gdi32.dll", CharSet = CharSet.Auto)] + public static extern int GetClipBox(IntPtr hDC, ref Win32.RECT rectBox); + + [DllImport("gdi32.dll", CharSet = CharSet.Auto)] + public static extern int SelectClipRgn(IntPtr hDC, IntPtr hRgn); + + [DllImport("gdi32.dll", CharSet = CharSet.Auto)] + public static extern IntPtr CreateBrushIndirect(ref LOGBRUSH brush); + + [DllImport("gdi32.dll", CharSet = CharSet.Auto)] + public static extern bool PatBlt(IntPtr hDC, int x, int y, int width, int height, uint flags); + + [DllImport("gdi32.dll", CharSet = CharSet.Auto)] + public static extern IntPtr DeleteObject(IntPtr hObject); + + [DllImport("gdi32.dll", CharSet = CharSet.Auto)] + public static extern bool DeleteDC(IntPtr hDC); + + [DllImport("gdi32.dll", CharSet = CharSet.Auto)] + public static extern IntPtr SelectObject(IntPtr hDC, IntPtr hObject); + + [DllImport("gdi32.dll", CharSet = CharSet.Auto)] + public static extern IntPtr CreateCompatibleDC(IntPtr hDC); + } +} \ No newline at end of file diff --git a/Labyrinth3/Crownwood.Magic/Win32/Structs.cs b/Labyrinth3/Crownwood.Magic/Win32/Structs.cs new file mode 100644 index 0000000..34e3d48 --- /dev/null +++ b/Labyrinth3/Crownwood.Magic/Win32/Structs.cs @@ -0,0 +1,96 @@ +// ***************************************************************************** +// +// (c) Crownwood Consulting Limited 2002-2003 +// All rights reserved. The software and associated documentation +// supplied hereunder are the proprietary information of Crownwood Consulting +// Limited, Crownwood, Bracknell, Berkshire, England and are supplied subject +// to licence terms. +// +// Magic Version 1.7.4.0 www.dotnetmagic.com +// ***************************************************************************** + +using System; +using System.Drawing; +using System.Runtime.InteropServices; + +namespace Crownwood.Magic.Win32 +{ + [StructLayout(LayoutKind.Sequential)] + public struct MSG + { + public IntPtr hwnd; + public int message; + public IntPtr wParam; + public IntPtr lParam; + public int time; + public int pt_x; + public int pt_y; + } + + [StructLayout(LayoutKind.Sequential)] + public struct PAINTSTRUCT + { + public IntPtr hdc; + public int fErase; + public Rectangle rcPaint; + public int fRestore; + public int fIncUpdate; + public int Reserved1; + public int Reserved2; + public int Reserved3; + public int Reserved4; + public int Reserved5; + public int Reserved6; + public int Reserved7; + public int Reserved8; + } + + [StructLayout(LayoutKind.Sequential)] + public struct RECT + { + public int left; + public int top; + public int right; + public int bottom; + } + + [StructLayout(LayoutKind.Sequential)] + public struct POINT + { + public int x; + public int y; + } + + [StructLayout(LayoutKind.Sequential)] + public struct SIZE + { + public int cx; + public int cy; + } + + [StructLayout(LayoutKind.Sequential, Pack = 1)] + public struct BLENDFUNCTION + { + public byte BlendOp; + public byte BlendFlags; + public byte SourceConstantAlpha; + public byte AlphaFormat; + } + + [StructLayout(LayoutKind.Sequential)] + public struct TRACKMOUSEEVENTS + { + public uint cbSize; + public uint dwFlags; + public IntPtr hWnd; + public uint dwHoverTime; + } + + [StructLayout(LayoutKind.Sequential)] + public struct LOGBRUSH + { + public uint lbStyle; + public uint lbColor; + public uint lbHatch; + } +} \ No newline at end of file diff --git a/Labyrinth3/Crownwood.Magic/Win32/User32.cs b/Labyrinth3/Crownwood.Magic/Win32/User32.cs new file mode 100644 index 0000000..ddd63a5 --- /dev/null +++ b/Labyrinth3/Crownwood.Magic/Win32/User32.cs @@ -0,0 +1,124 @@ +// ***************************************************************************** +// +// (c) Crownwood Consulting Limited 2002-2003 +// All rights reserved. The software and associated documentation +// supplied hereunder are the proprietary information of Crownwood Consulting +// Limited, Crownwood, Bracknell, Berkshire, England and are supplied subject +// to licence terms. +// +// Magic Version 1.7.4.0 www.dotnetmagic.com +// ***************************************************************************** + +using System; +using System.Runtime.InteropServices; + +namespace Crownwood.Magic.Win32 +{ + public class User32 + { + [DllImport("User32.dll", CharSet = CharSet.Auto)] + public static extern int GetWindowLong(IntPtr hWnd, int nIndex); + + [DllImport("User32.dll", CharSet = CharSet.Auto)] + public static extern int SetWindowLong(IntPtr hWnd, int nIndex, int newLong); + + [DllImport("User32.dll", CharSet = CharSet.Auto)] + public static extern bool SystemParametersInfo(uint uiAction, uint uiParam, ref int bRetValue, uint fWinINI); + + [DllImport("User32.dll", CharSet = CharSet.Auto)] + public static extern bool AnimateWindow(IntPtr hWnd, uint dwTime, uint dwFlags); + + [DllImport("User32.dll", CharSet = CharSet.Auto)] + public static extern bool InvalidateRect(IntPtr hWnd, ref RECT rect, bool erase); + + [DllImport("User32.dll", CharSet = CharSet.Auto)] + public static extern IntPtr LoadCursor(IntPtr hInstance, uint cursor); + + [DllImport("User32.dll", CharSet = CharSet.Auto)] + public static extern IntPtr SetCursor(IntPtr hCursor); + + [DllImport("User32.dll", CharSet = CharSet.Auto)] + public static extern IntPtr GetFocus(); + + [DllImport("User32.dll", CharSet = CharSet.Auto)] + public static extern IntPtr SetFocus(IntPtr hWnd); + + [DllImport("User32.dll", CharSet = CharSet.Auto)] + public static extern bool ReleaseCapture(); + + [DllImport("User32.dll", CharSet = CharSet.Auto)] + public static extern bool WaitMessage(); + + [DllImport("User32.dll", CharSet = CharSet.Auto)] + public static extern bool TranslateMessage(ref MSG msg); + + [DllImport("User32.dll", CharSet = CharSet.Auto)] + public static extern bool DispatchMessage(ref MSG msg); + + [DllImport("User32.dll", CharSet = CharSet.Auto)] + public static extern bool PostMessage(IntPtr hWnd, int Msg, uint wParam, uint lParam); + + [DllImport("User32.dll", CharSet = CharSet.Auto)] + public static extern uint SendMessage(IntPtr hWnd, int Msg, uint wParam, uint lParam); + + [DllImport("User32.dll", CharSet = CharSet.Auto)] + public static extern bool GetMessage(ref MSG msg, int hWnd, uint wFilterMin, uint wFilterMax); + + [DllImport("User32.dll", CharSet = CharSet.Auto)] + public static extern bool PeekMessage(ref MSG msg, int hWnd, uint wFilterMin, uint wFilterMax, uint wFlag); + + [DllImport("User32.dll", CharSet = CharSet.Auto)] + public static extern IntPtr BeginPaint(IntPtr hWnd, ref PAINTSTRUCT ps); + + [DllImport("User32.dll", CharSet = CharSet.Auto)] + public static extern bool EndPaint(IntPtr hWnd, ref PAINTSTRUCT ps); + + [DllImport("User32.dll", CharSet = CharSet.Auto)] + public static extern IntPtr GetDC(IntPtr hWnd); + + [DllImport("User32.dll", CharSet = CharSet.Auto)] + public static extern int ReleaseDC(IntPtr hWnd, IntPtr hDC); + + [DllImport("User32.dll", CharSet = CharSet.Auto)] + public static extern int ShowWindow(IntPtr hWnd, short cmdShow); + + [DllImport("User32.dll", CharSet = CharSet.Auto)] + public static extern bool MoveWindow(IntPtr hWnd, int x, int y, int width, int height, bool repaint); + + [DllImport("User32.dll", CharSet = CharSet.Auto)] + public static extern int SetWindowPos(IntPtr hWnd, IntPtr hWndAfter, int X, int Y, int Width, int Height, uint flags); + + [DllImport("User32.dll", CharSet = CharSet.Auto)] + public static extern bool UpdateLayeredWindow(IntPtr hwnd, IntPtr hdcDst, ref POINT pptDst, ref SIZE psize, IntPtr hdcSrc, ref POINT pprSrc, Int32 crKey, ref BLENDFUNCTION pblend, Int32 dwFlags); + + [DllImport("User32.dll", CharSet = CharSet.Auto)] + public static extern bool GetWindowRect(IntPtr hWnd, ref RECT rect); + + [DllImport("User32.dll", CharSet = CharSet.Auto)] + public static extern bool ClientToScreen(IntPtr hWnd, ref POINT pt); + + [DllImport("User32.dll", CharSet = CharSet.Auto)] + public static extern bool ScreenToClient(IntPtr hWnd, ref POINT pt); + + [DllImport("User32.dll", CharSet = CharSet.Auto)] + public static extern bool TrackMouseEvent(ref TRACKMOUSEEVENTS tme); + + [DllImport("User32.dll", CharSet = CharSet.Auto)] + public static extern bool SetWindowRgn(IntPtr hWnd, IntPtr hRgn, bool redraw); + + [DllImport("User32.dll", CharSet = CharSet.Auto)] + public static extern ushort GetKeyState(int virtKey); + + [DllImport("User32.dll", CharSet = CharSet.Auto)] + public static extern IntPtr GetParent(IntPtr hWnd); + + [DllImport("User32.dll", CharSet = CharSet.Auto)] + public static extern bool DrawFocusRect(IntPtr hWnd, ref RECT rect); + + [DllImport("User32.dll", CharSet = CharSet.Auto)] + public static extern bool HideCaret(IntPtr hWnd); + + [DllImport("User32.dll", CharSet = CharSet.Auto)] + public static extern bool ShowCaret(IntPtr hWnd); + } +} \ No newline at end of file diff --git a/Labyrinth3/Data/Collections/AnnotationCollection.cs b/Labyrinth3/Data/Collections/AnnotationCollection.cs new file mode 100644 index 0000000..1005a8c --- /dev/null +++ b/Labyrinth3/Data/Collections/AnnotationCollection.cs @@ -0,0 +1,39 @@ +using Labyrinth.Plot; +using System; +using System.Collections.Generic; + +namespace Labyrinth.Collections +{ + public static class AnnotationExtensions + { + /// + /// Returns the 0-based index of the Annotation with the specified ID. + /// + /// The Guid to search for. + /// The 0-based index of the item, or -1 if the item is not present. + public static int IndexOf(this List l, Guid id) + { + for (int index = 0; index != l.Count; ++index) + { + if (l[index].ID == id) + return index; + } + return -1; + } + + /// + /// Returns the 0-based index of the Annotation with the specified title. + /// + /// The title to search for. + /// The 0-based index of the item, or -1 if the item is not present. + public static int IndexOf(this List l, string title) + { + for (int index = 0; index != l.Count; ++index) + { + if (l[index].Title == title) + return index; + } + return -1; + } + } +} \ No newline at end of file diff --git a/Labyrinth3/Data/Collections/ElementCollection.cs b/Labyrinth3/Data/Collections/ElementCollection.cs new file mode 100644 index 0000000..7b5827e --- /dev/null +++ b/Labyrinth3/Data/Collections/ElementCollection.cs @@ -0,0 +1,39 @@ +using Labyrinth.Plot; +using System; +using System.Collections.Generic; + +namespace Labyrinth.Collections +{ + public static class ElementExtensions + { + /// + /// Returns the 0-based index of the Element with the specified ID. + /// + /// The Guid to search for. + /// The 0-based index of the item, or -1 if the item is not present. + public static int IndexOf(this List l, Guid id) + { + for (int index = 0; index != l.Count; ++index) + { + if (l[index].ID == id) + return index; + } + return -1; + } + + /// + /// Returns the 0-based index of the Element with the specified name. + /// + /// The name to search for. + /// The 0-based index of the item, or -1 if the item is not present. + public static int IndexOf(this List l, string name) + { + for (int index = 0; index != l.Count; ++index) + { + if (l[index].Name == name) + return index; + } + return -1; + } + } +} \ No newline at end of file diff --git a/Labyrinth3/Data/Collections/LinkCollection.cs b/Labyrinth3/Data/Collections/LinkCollection.cs new file mode 100644 index 0000000..c0622aa --- /dev/null +++ b/Labyrinth3/Data/Collections/LinkCollection.cs @@ -0,0 +1,39 @@ +using Labyrinth.Plot; +using System; +using System.Collections.Generic; + +namespace Labyrinth.Collections +{ + public static class LinkExtensions + { + /// + /// Returns the 0-based index of the Link with the specified ID. + /// + /// The Guid to search for. + /// The 0-based index of the item, or -1 if the item is not present. + public static int IndexOf(this List l, Guid id) + { + for (int index = 0; index != l.Count; ++index) + { + if (l[index].ID == id) + return index; + } + return -1; + } + + /// + /// Returns the 0-based index of the Link with the specified text. + /// + /// The text to search for. + /// The 0-based index of the item, or -1 if the item is not present. + public static int IndexOf(this List l, string desc) + { + for (int index = 0; index != l.Count; ++index) + { + if (l[index].Description == desc) + return index; + } + return -1; + } + } +} \ No newline at end of file diff --git a/Labyrinth3/Data/Collections/NoteCollection.cs b/Labyrinth3/Data/Collections/NoteCollection.cs new file mode 100644 index 0000000..122d5b2 --- /dev/null +++ b/Labyrinth3/Data/Collections/NoteCollection.cs @@ -0,0 +1,39 @@ +using Labyrinth.Plot; +using System; +using System.Collections.Generic; + +namespace Labyrinth.Collections +{ + public static class NoteExtensions + { + /// + /// Returns the 0-based index of the Note with the specified ID. + /// + /// The Guid to search for. + /// The 0-based index of the item, or -1 if the item is not present. + public static int IndexOf(this List l, Guid id) + { + for (int index = 0; index != l.Count; ++index) + { + if (l[index].ID == id) + return index; + } + return -1; + } + + /// + /// Returns the 0-based index of the Note with the specified title. + /// + /// The title to search for. + /// The 0-based index of the item, or -1 if the item is not present. + public static int IndexOf(this List l, string title) + { + for (int index = 0; index != l.Count; ++index) + { + if (l[index].Title == title) + return index; + } + return -1; + } + } +} \ No newline at end of file diff --git a/Labyrinth3/Data/Collections/StructureCollection.cs b/Labyrinth3/Data/Collections/StructureCollection.cs new file mode 100644 index 0000000..f16b4ba --- /dev/null +++ b/Labyrinth3/Data/Collections/StructureCollection.cs @@ -0,0 +1,39 @@ +using Labyrinth.Plot; +using System; +using System.Collections.Generic; + +namespace Labyrinth.Collections +{ + public static class StructureExtensions + { + /// + /// Returns the 0-based index of the Structure with the specified ID. + /// + /// The Guid to search for. + /// The 0-based index of the item, or -1 if the item is not present. + public static int IndexOf(this List l, Guid id) + { + for (int index = 0; index != l.Count; ++index) + { + if (l[index].ID == id) + return index; + } + return -1; + } + + /// + /// Returns the 0-based index of the Structure with the specified name. + /// + /// The name to search for. + /// The 0-based index of the item, or -1 if the item is not present. + public static int IndexOf(this List l, string name) + { + for (int index = 0; index != l.Count; ++index) + { + if (l[index].Name == name) + return index; + } + return -1; + } + } +} \ No newline at end of file diff --git a/Labyrinth3/Data/Collections/TaskCollection.cs b/Labyrinth3/Data/Collections/TaskCollection.cs new file mode 100644 index 0000000..cd7e66e --- /dev/null +++ b/Labyrinth3/Data/Collections/TaskCollection.cs @@ -0,0 +1,39 @@ +using Labyrinth.Plot; +using System; +using System.Collections.Generic; + +namespace Labyrinth.Collections +{ + public static class TaskExtensions + { + /// + /// Returns the 0-based index of the Task with the specified ID. + /// + /// The Guid to search for. + /// The 0-based index of the item, or -1 if the item is not present. + public static int IndexOf(this List l, Guid id) + { + for (int index = 0; index != l.Count; ++index) + { + if (l[index].ID == id) + return index; + } + return -1; + } + + /// + /// Returns the 0-based index of the Task with the specified title. + /// + /// The name to search for. + /// The 0-based index of the item, or -1 if the item is not present. + public static int IndexOf(this List l, string title) + { + for (int index = 0; index != l.Count; ++index) + { + if (l[index].Title == title) + return index; + } + return -1; + } + } +} \ No newline at end of file diff --git a/Labyrinth3/Data/Collections/TimelineCollection.cs b/Labyrinth3/Data/Collections/TimelineCollection.cs new file mode 100644 index 0000000..ac1ccc1 --- /dev/null +++ b/Labyrinth3/Data/Collections/TimelineCollection.cs @@ -0,0 +1,39 @@ +using Labyrinth.Plot; +using System; +using System.Collections.Generic; + +namespace Labyrinth.Collections +{ + public static class TimelineExtensions + { + /// + /// Returns the 0-based index of the Timeline with the specified ID. + /// + /// The Guid to search for. + /// The 0-based index of the item, or -1 if the item is not present. + public static int IndexOf(this List l, Guid id) + { + for (int index = 0; index != l.Count; ++index) + { + if (l[index].ID == id) + return index; + } + return -1; + } + + /// + /// Returns the 0-based index of the Timeline with the specified name. + /// + /// The name to search for. + /// The 0-based index of the item, or -1 if the item is not present. + public static int IndexOf(this List l, string name) + { + for (int index = 0; index != l.Count; ++index) + { + if (l[index].Name == name) + return index; + } + return -1; + } + } +} \ No newline at end of file diff --git a/Labyrinth3/Data/Collections/TimelineItemCollection.cs b/Labyrinth3/Data/Collections/TimelineItemCollection.cs new file mode 100644 index 0000000..aafa3d8 --- /dev/null +++ b/Labyrinth3/Data/Collections/TimelineItemCollection.cs @@ -0,0 +1,24 @@ +using Labyrinth.Plot; +using System; +using System.Collections.Generic; + +namespace Labyrinth.Extensions +{ + public static class TimelineItemExtensions + { + /// + /// Returns the 0-based index of the TimelineItem with the specified ID. + /// + /// The Guid to search for. + /// The 0-based index of the item, or -1 if the item is not present. + public static int IndexOf(this List l, Guid id) + { + for (int index = 0; index != l.Count; ++index) + { + if (l[index].ID == id) + return index; + } + return -1; + } + } +} \ No newline at end of file diff --git a/Labyrinth3/Data/Collections/TimelinePointCollection.cs b/Labyrinth3/Data/Collections/TimelinePointCollection.cs new file mode 100644 index 0000000..e62a74c --- /dev/null +++ b/Labyrinth3/Data/Collections/TimelinePointCollection.cs @@ -0,0 +1,39 @@ +using Labyrinth.Plot; +using System; +using System.Collections.Generic; + +namespace Labyrinth.Collections +{ + public static class TimelinePointExtensions + { + /// + /// Returns the 0-based index of the TimelinePoint with the specified ID. + /// + /// The Guid to search for. + /// The 0-based index of the item, or -1 if the item is not present. + public static int IndexOf(this List l, Guid id) + { + for (int index = 0; index != l.Count; ++index) + { + if (l[index].ID == id) + return index; + } + return -1; + } + + /// + /// Returns the 0-based index of the TimelinePoint with the specified name. + /// + /// The name to search for. + /// The 0-based index of the item, or -1 if the item is not present. + public static int IndexOf(this List l, string name) + { + for (int index = 0; index != l.Count; ++index) + { + if (l[index].Name == name) + return index; + } + return -1; + } + } +} \ No newline at end of file diff --git a/Labyrinth3/Data/Events/ElementEventArgs.cs b/Labyrinth3/Data/Events/ElementEventArgs.cs new file mode 100644 index 0000000..795d35f --- /dev/null +++ b/Labyrinth3/Data/Events/ElementEventArgs.cs @@ -0,0 +1,29 @@ +using Labyrinth.Plot; +using System; + +namespace Labyrinth.Events +{ + /// + /// Event data for events which take an element as an argument. + /// + public class ElementEventArgs : EventArgs + { + private Element fElement = (Element)null; + + /// Constructor. + /// The element. + public ElementEventArgs(Element e) + { + this.fElement = e; + } + + /// The element specified by the event. + public Element Element + { + get + { + return this.fElement; + } + } + } +} \ No newline at end of file diff --git a/Labyrinth3/Data/Events/ElementEventHandler.cs b/Labyrinth3/Data/Events/ElementEventHandler.cs new file mode 100644 index 0000000..4c31945 --- /dev/null +++ b/Labyrinth3/Data/Events/ElementEventHandler.cs @@ -0,0 +1,13 @@ +// Decompiled with JetBrains decompiler +// Type: Labyrinth.Events.ElementEventHandler +// Assembly: Data, Version=3.6.1928.15689, Culture=neutral, PublicKeyToken=null +// MVID: DD3860A9-34AC-4A51-A3EB-CBA78B243957 +// Assembly location: C:\Dropbox\Workspace\Programs\Labyrinth\Data.dll + +namespace Labyrinth.Events +{ + /// + /// Delegate for events which take an element as an argument. + /// + public delegate void ElementEventHandler(object sender, ElementEventArgs e); +} \ No newline at end of file diff --git a/Labyrinth3/Data/Events/NoteEventArgs.cs b/Labyrinth3/Data/Events/NoteEventArgs.cs new file mode 100644 index 0000000..91438e9 --- /dev/null +++ b/Labyrinth3/Data/Events/NoteEventArgs.cs @@ -0,0 +1,35 @@ +// Decompiled with JetBrains decompiler +// Type: Labyrinth.Events.NoteEventArgs +// Assembly: Data, Version=3.6.1928.15689, Culture=neutral, PublicKeyToken=null +// MVID: DD3860A9-34AC-4A51-A3EB-CBA78B243957 +// Assembly location: C:\Dropbox\Workspace\Programs\Labyrinth\Data.dll + +using Labyrinth.Plot; +using System; + +namespace Labyrinth.Events +{ + /// + /// Event data for events which take a timeline as an argument. + /// + public class NoteEventArgs : EventArgs + { + private Note fNote = (Note)null; + + /// Constructor. + /// The note. + public NoteEventArgs(Note n) + { + this.fNote = n; + } + + /// The note specified by the event. + public Note Note + { + get + { + return this.fNote; + } + } + } +} \ No newline at end of file diff --git a/Labyrinth3/Data/Events/NoteEventHandler.cs b/Labyrinth3/Data/Events/NoteEventHandler.cs new file mode 100644 index 0000000..8fd52ad --- /dev/null +++ b/Labyrinth3/Data/Events/NoteEventHandler.cs @@ -0,0 +1,11 @@ +// Decompiled with JetBrains decompiler +// Type: Labyrinth.Events.NoteEventHandler +// Assembly: Data, Version=3.6.1928.15689, Culture=neutral, PublicKeyToken=null +// MVID: DD3860A9-34AC-4A51-A3EB-CBA78B243957 +// Assembly location: C:\Dropbox\Workspace\Programs\Labyrinth\Data.dll + +namespace Labyrinth.Events +{ + /// Delegate for events which take a note as an argument. + public delegate void NoteEventHandler(object sender, NoteEventArgs e); +} \ No newline at end of file diff --git a/Labyrinth3/Data/Events/StructureEventArgs.cs b/Labyrinth3/Data/Events/StructureEventArgs.cs new file mode 100644 index 0000000..7be0e98 --- /dev/null +++ b/Labyrinth3/Data/Events/StructureEventArgs.cs @@ -0,0 +1,35 @@ +// Decompiled with JetBrains decompiler +// Type: Labyrinth.Events.StructureEventArgs +// Assembly: Data, Version=3.6.1928.15689, Culture=neutral, PublicKeyToken=null +// MVID: DD3860A9-34AC-4A51-A3EB-CBA78B243957 +// Assembly location: C:\Dropbox\Workspace\Programs\Labyrinth\Data.dll + +using Labyrinth.Plot; +using System; + +namespace Labyrinth.Events +{ + /// + /// Event data for events which take a structure as an argument. + /// + public class StructureEventArgs : EventArgs + { + private Structure fStructure = (Structure)null; + + /// Constructor. + /// The structure. + public StructureEventArgs(Structure s) + { + this.fStructure = s; + } + + /// The structure specified by the event. + public Structure Structure + { + get + { + return this.fStructure; + } + } + } +} \ No newline at end of file diff --git a/Labyrinth3/Data/Events/StructureEventHandler.cs b/Labyrinth3/Data/Events/StructureEventHandler.cs new file mode 100644 index 0000000..7dc437d --- /dev/null +++ b/Labyrinth3/Data/Events/StructureEventHandler.cs @@ -0,0 +1,13 @@ +// Decompiled with JetBrains decompiler +// Type: Labyrinth.Events.StructureEventHandler +// Assembly: Data, Version=3.6.1928.15689, Culture=neutral, PublicKeyToken=null +// MVID: DD3860A9-34AC-4A51-A3EB-CBA78B243957 +// Assembly location: C:\Dropbox\Workspace\Programs\Labyrinth\Data.dll + +namespace Labyrinth.Events +{ + /// + /// Delegate for events which take a structure as an argument. + /// + public delegate void StructureEventHandler(object sender, StructureEventArgs e); +} \ No newline at end of file diff --git a/Labyrinth3/Data/Events/TimelineEventArgs.cs b/Labyrinth3/Data/Events/TimelineEventArgs.cs new file mode 100644 index 0000000..fbf0c7c --- /dev/null +++ b/Labyrinth3/Data/Events/TimelineEventArgs.cs @@ -0,0 +1,35 @@ +// Decompiled with JetBrains decompiler +// Type: Labyrinth.Events.TimelineEventArgs +// Assembly: Data, Version=3.6.1928.15689, Culture=neutral, PublicKeyToken=null +// MVID: DD3860A9-34AC-4A51-A3EB-CBA78B243957 +// Assembly location: C:\Dropbox\Workspace\Programs\Labyrinth\Data.dll + +using Labyrinth.Plot; +using System; + +namespace Labyrinth.Events +{ + /// + /// Event data for events which take a timeline as an argument. + /// + public class TimelineEventArgs : EventArgs + { + private Timeline fTimeline = (Timeline)null; + + /// Constructor. + /// The timeline. + public TimelineEventArgs(Timeline tl) + { + this.fTimeline = tl; + } + + /// The timeline specified by the event. + public Timeline Timeline + { + get + { + return this.fTimeline; + } + } + } +} \ No newline at end of file diff --git a/Labyrinth3/Data/Events/TimelineEventHandler.cs b/Labyrinth3/Data/Events/TimelineEventHandler.cs new file mode 100644 index 0000000..48aa59b --- /dev/null +++ b/Labyrinth3/Data/Events/TimelineEventHandler.cs @@ -0,0 +1,13 @@ +// Decompiled with JetBrains decompiler +// Type: Labyrinth.Events.TimelineEventHandler +// Assembly: Data, Version=3.6.1928.15689, Culture=neutral, PublicKeyToken=null +// MVID: DD3860A9-34AC-4A51-A3EB-CBA78B243957 +// Assembly location: C:\Dropbox\Workspace\Programs\Labyrinth\Data.dll + +namespace Labyrinth.Events +{ + /// + /// Delegate for events which take a timeline as an argument. + /// + public delegate void TimelineEventHandler(object sender, TimelineEventArgs e); +} \ No newline at end of file diff --git a/Labyrinth3/Data/Extensibility/IAddIn.cs b/Labyrinth3/Data/Extensibility/IAddIn.cs new file mode 100644 index 0000000..6e8d62e --- /dev/null +++ b/Labyrinth3/Data/Extensibility/IAddIn.cs @@ -0,0 +1,31 @@ +// Decompiled with JetBrains decompiler +// Type: Labyrinth.Extensibility.IAddIn +// Assembly: Data, Version=3.6.1928.15689, Culture=neutral, PublicKeyToken=null +// MVID: DD3860A9-34AC-4A51-A3EB-CBA78B243957 +// Assembly location: C:\Dropbox\Workspace\Programs\Labyrinth\Data.dll + +namespace Labyrinth.Extensibility +{ + /// Interface required for add-ins. + public interface IAddIn + { + /// Gets the name of the add-in. + string Name { get; } + + /// Gets the description of the add-in. + string Description { get; } + + /// + /// Gets the collection of components provided by the add-in. + /// + IAddInComponent[] Components { get; } + + /// Called by the system to initialise the add-in. + /// The application. + /// True if the add-in was initialised successfully, false otherwise + bool Load(IApplication app); + + /// Called by the system to unload the add-in. + void Unload(); + } +} \ No newline at end of file diff --git a/Labyrinth3/Data/Extensibility/IAddInComponent.cs b/Labyrinth3/Data/Extensibility/IAddInComponent.cs new file mode 100644 index 0000000..a66731a --- /dev/null +++ b/Labyrinth3/Data/Extensibility/IAddInComponent.cs @@ -0,0 +1,21 @@ +// Decompiled with JetBrains decompiler +// Type: Labyrinth.Extensibility.IAddInComponent +// Assembly: Data, Version=3.6.1928.15689, Culture=neutral, PublicKeyToken=null +// MVID: DD3860A9-34AC-4A51-A3EB-CBA78B243957 +// Assembly location: C:\Dropbox\Workspace\Programs\Labyrinth\Data.dll + +namespace Labyrinth.Extensibility +{ + /// Interface for add-in functions. + public interface IAddInComponent + { + /// Gets the name of the component. + string Name { get; } + + /// Gets the description of the component. + string Description { get; } + + /// Called by the system when the project data changes. + void UpdateData(); + } +} \ No newline at end of file diff --git a/Labyrinth3/Data/Extensibility/IAnnotationPage.cs b/Labyrinth3/Data/Extensibility/IAnnotationPage.cs new file mode 100644 index 0000000..0a85f50 --- /dev/null +++ b/Labyrinth3/Data/Extensibility/IAnnotationPage.cs @@ -0,0 +1,43 @@ +// Decompiled with JetBrains decompiler +// Type: Labyrinth.Extensibility.IAnnotationPage +// Assembly: Data, Version=3.6.1928.15689, Culture=neutral, PublicKeyToken=null +// MVID: DD3860A9-34AC-4A51-A3EB-CBA78B243957 +// Assembly location: C:\Dropbox\Workspace\Programs\Labyrinth\Data.dll + +using Labyrinth.Events; +using Labyrinth.Plot; + +namespace Labyrinth.Extensibility +{ + /// Interface implemented by annnotation pages. + public interface IAnnotationPage : IPage + { + /// Gets or sets whether text annotations are displayed. + bool ShowTextAnnotations { get; set; } + + /// + /// Gets or sets whether file link annotations are displayed. + /// + bool ShowLinkAnnotations { get; set; } + + /// + /// Gets or sets whether sketch annotations are displayed. + /// + bool ShowSketchAnnotations { get; set; } + + /// Gets the selected annotation. + Annotation SelectedAnnotation { get; } + + /// Occurs when an element is modified. + event ElementEventHandler ElementModified; + + /// Occurs when an element is activated. + event ElementEventHandler ElementActivated; + + /// Occurs when a timeline is modified. + event TimelineEventHandler TimelineModified; + + /// Occurs when a timeline is activated. + event TimelineEventHandler TimelineActivated; + } +} \ No newline at end of file diff --git a/Labyrinth3/Data/Extensibility/IApplication.cs b/Labyrinth3/Data/Extensibility/IApplication.cs new file mode 100644 index 0000000..f585f55 --- /dev/null +++ b/Labyrinth3/Data/Extensibility/IApplication.cs @@ -0,0 +1,187 @@ +// Decompiled with JetBrains decompiler +// Type: Labyrinth.Extensibility.IApplication +// Assembly: Data, Version=3.6.1928.15689, Culture=neutral, PublicKeyToken=null +// MVID: DD3860A9-34AC-4A51-A3EB-CBA78B243957 +// Assembly location: C:\Dropbox\Workspace\Programs\Labyrinth\Data.dll + +using Labyrinth.Events; +using Labyrinth.Plot; +using System; +using System.Drawing.Printing; +using System.Windows.Forms; + +namespace Labyrinth.Extensibility +{ + /// + /// Interface allowing access to the Labyrinth application. + /// + public interface IApplication + { + /// Gets the current project. + Project Project { get; } + + /// Gets or sets the current filename. + string FileName { get; set; } + + /// Gets the application menubar. + MainMenu Menubar { get; } + + /// Gets the application toolbar. + ToolBar Toolbar { get; } + + /// Gets the application statusbar. + StatusBar Statusbar { get; } + + /// Gets the printer page settings. + PageSettings PageSettings { get; } + + /// Gets the printer settings. + PrinterSettings PrinterSettings { get; } + + /// Gets the element currently selected in the explorer. + Element SelectedElement { get; } + + /// + /// Gets the structure currently selected in the explorer. + /// + Structure SelectedStructure { get; } + + /// Gets the timeline currently selected in the explorer. + Timeline SelectedTimeline { get; } + + /// Gets the note currently selected in the explorer. + Note SelectedNote { get; } + + /// Gets the active page. + IPage ActivePage { get; } + + /// Gets the collection of open pages. + IPage[] OpenPages { get; } + + /// Gets the list of installed add-ins. + IAddIn[] AddIns { get; } + + /// Gets the ImageList containing element icons. + ImageList Glyphs { get; } + + /// + /// Opens a page for the given element. + /// If such a page already exists, it is activated. + /// + /// The element to open. + void OpenElement(Element e); + + /// + /// Opens a page for the given structure. + /// If such a page already exists, it is activated. + /// + /// The structure to open. + void OpenStructure(Structure s); + + /// + /// Opens a page for the given timeline. + /// If such a page already exists, it is activated. + /// + /// The timeline to open. + void OpenTimeline(Timeline tl); + + /// + /// Opens a page for the given note. + /// If such a page already exists, it is activated. + /// + /// The note to open. + void OpenNote(Note n); + + /// Opens the search page. + void OpenSearch(); + + /// Opens the annotations page. + void OpenAnnotations(); + + /// Opens the tasks page. + void OpenTasks(); + + /// Opens the calendar page. + void OpenCalendar(); + + /// Opens a blank project. + void NewProject(); + + /// Opens the project from the given file. + /// The file to open. + /// True if the project was opened successfully, false otherwise. + bool OpenProject(string filename); + + /// Saves the project to the given file. + /// The file to save to. + /// True if the project was saved successfully, false otherwise. + bool SaveProject(string filename); + + /// Opens the specified page. + /// The page to Open. + void OpenPage(IPage page); + + /// Closes the specified page. + /// The page to close. + /// True if the page was found and closed, false otherwise. + bool ClosePage(IPage page); + + /// Updates the application UI. + void UpdateUI(); + + /// + /// Returns the index of the glyph used for the given object. + /// + /// The object to find the image for. + /// The index in the Glyphs ImageList, or -1 if no icon exists. + int GetImageIndex(object obj); + + /// Occurs when a new blank project is created. + event EventHandler ProjectCreated; + + /// Occurs when a project file is opened. + event EventHandler ProjectOpened; + + /// Occurs when a project is saved. + event EventHandler ProjectSaved; + + /// Occurs when a project is about to be closed. + event EventHandler ProjectClosing; + + /// Occurs when a new element is added. + event ElementEventHandler ElementAdded; + + /// Occurs when an element is changed. + event ElementEventHandler ElementModified; + + /// Occurs when an element is deleted. + event ElementEventHandler ElementDeleted; + + /// Occurs when a new structure is added. + event StructureEventHandler StructureAdded; + + /// Occurs when a structure is changed. + event StructureEventHandler StructureModified; + + /// Occurs when a structure is deleted. + event StructureEventHandler StructureDeleted; + + /// Occurs when a new timeline is added. + event TimelineEventHandler TimelineAdded; + + /// Occurs when a timeline is changed. + event TimelineEventHandler TimelineModified; + + /// Occurs when a timeline is deleted. + event TimelineEventHandler TimelineDeleted; + + /// Occurs when a new note is added. + event NoteEventHandler NoteAdded; + + /// Occurs when a note is changed. + event NoteEventHandler NoteModified; + + /// Occurs when a note is deleted. + event NoteEventHandler NoteDeleted; + } +} \ No newline at end of file diff --git a/Labyrinth3/Data/Extensibility/ICalendarPage.cs b/Labyrinth3/Data/Extensibility/ICalendarPage.cs new file mode 100644 index 0000000..6e61506 --- /dev/null +++ b/Labyrinth3/Data/Extensibility/ICalendarPage.cs @@ -0,0 +1,34 @@ +// Decompiled with JetBrains decompiler +// Type: Labyrinth.Extensibility.ICalendarPage +// Assembly: Data, Version=3.6.1928.15689, Culture=neutral, PublicKeyToken=null +// MVID: DD3860A9-34AC-4A51-A3EB-CBA78B243957 +// Assembly location: C:\Dropbox\Workspace\Programs\Labyrinth\Data.dll + +using Labyrinth.Events; +using Labyrinth.Plot; +using System; + +namespace Labyrinth.Extensibility +{ + /// Interface implemented by calendar pages. + public interface ICalendarPage : IPage + { + /// Gets the selected date. + DateTime SelectedDate { get; } + + /// Gets the selected timeline item. + TimelineItem SelectedItem { get; } + + /// Occurs when an element is activated. + event ElementEventHandler ElementActivated; + + /// Occurs when an element is modified. + event ElementEventHandler ElementModified; + + /// Occurs when a timeline is activated. + event TimelineEventHandler TimelineActivated; + + /// Occurs when a timeline is modified. + event TimelineEventHandler TimelineModified; + } +} \ No newline at end of file diff --git a/Labyrinth3/Data/Extensibility/ICommand.cs b/Labyrinth3/Data/Extensibility/ICommand.cs new file mode 100644 index 0000000..5a3122e --- /dev/null +++ b/Labyrinth3/Data/Extensibility/ICommand.cs @@ -0,0 +1,29 @@ +// Decompiled with JetBrains decompiler +// Type: Labyrinth.Extensibility.ICommand +// Assembly: Data, Version=3.6.1928.15689, Culture=neutral, PublicKeyToken=null +// MVID: DD3860A9-34AC-4A51-A3EB-CBA78B243957 +// Assembly location: C:\Dropbox\Workspace\Programs\Labyrinth\Data.dll + +using System; + +namespace Labyrinth.Extensibility +{ + /// Interface for add-in commands. + public interface ICommand : IAddInComponent + { + /// + /// Gets a value representing whether the command can be run or not. + /// + bool Available { get; } + + /// + /// Gets a value representing whether the command is running or not. + /// + bool Active { get; } + + /// Occurs when the command is called. + /// The originator of the event. + /// Arguments passed to the event. + void Execute(object sender, EventArgs e); + } +} \ No newline at end of file diff --git a/Labyrinth3/Data/Extensibility/ICustomSearch.cs b/Labyrinth3/Data/Extensibility/ICustomSearch.cs new file mode 100644 index 0000000..2e5e446 --- /dev/null +++ b/Labyrinth3/Data/Extensibility/ICustomSearch.cs @@ -0,0 +1,23 @@ +// Decompiled with JetBrains decompiler +// Type: Labyrinth.Extensibility.ICustomSearch +// Assembly: Data, Version=3.6.1928.15689, Culture=neutral, PublicKeyToken=null +// MVID: DD3860A9-34AC-4A51-A3EB-CBA78B243957 +// Assembly location: C:\Dropbox\Workspace\Programs\Labyrinth\Data.dll + +using System.Windows.Forms; + +namespace Labyrinth.Extensibility +{ + /// Interface for add-in searches. + public interface ICustomSearch : IAddInComponent + { + /// Gets the control presented on the search pane. + Control Control { get; } + + /// Called by the system to initialise the control. + void Init(); + + /// Called by the system to reset the search. + void Clear(); + } +} \ No newline at end of file diff --git a/Labyrinth3/Data/Extensibility/IElementPage.cs b/Labyrinth3/Data/Extensibility/IElementPage.cs new file mode 100644 index 0000000..438754c --- /dev/null +++ b/Labyrinth3/Data/Extensibility/IElementPage.cs @@ -0,0 +1,48 @@ +// Decompiled with JetBrains decompiler +// Type: Labyrinth.Extensibility.IElementPage +// Assembly: Data, Version=3.6.1928.15689, Culture=neutral, PublicKeyToken=null +// MVID: DD3860A9-34AC-4A51-A3EB-CBA78B243957 +// Assembly location: C:\Dropbox\Workspace\Programs\Labyrinth\Data.dll + +using Labyrinth.Events; +using Labyrinth.Plot; + +namespace Labyrinth.Extensibility +{ + /// Interface implemented by plot element pages. + public interface IElementPage : IPage + { + /// Gets the element. + Element Element { get; } + + /// Gets the currently selected annotation. + Annotation SelectedAnnotation { get; } + + /// Gets the currently selected link. + Link SelectedLink { get; } + + /// Gets the currently selected timeline. + Timeline SelectedTimeline { get; } + + /// Gets the currently selected timeline annotation. + Annotation SelectedTimelineAnnotation { get; } + + /// Occurs when an element is opened. + event ElementEventHandler ElementActivated; + + /// Occurs when an element is changed. + event ElementEventHandler ElementModified; + + /// Occurs when a structure is opened. + event StructureEventHandler StructureActivated; + + /// Occurs when a structure is changed. + event StructureEventHandler StructureModified; + + /// Occurs when a timeline is opened. + event TimelineEventHandler TimelineActivated; + + /// Occurs when a timeline is changed. + event TimelineEventHandler TimelineModified; + } +} \ No newline at end of file diff --git a/Labyrinth3/Data/Extensibility/IExplorerPage.cs b/Labyrinth3/Data/Extensibility/IExplorerPage.cs new file mode 100644 index 0000000..72f837a --- /dev/null +++ b/Labyrinth3/Data/Extensibility/IExplorerPage.cs @@ -0,0 +1,21 @@ +// Decompiled with JetBrains decompiler +// Type: Labyrinth.Extensibility.IExplorerPage +// Assembly: Data, Version=3.6.1928.15689, Culture=neutral, PublicKeyToken=null +// MVID: DD3860A9-34AC-4A51-A3EB-CBA78B243957 +// Assembly location: C:\Dropbox\Workspace\Programs\Labyrinth\Data.dll + +using System.Drawing; +using System.Windows.Forms; + +namespace Labyrinth.Extensibility +{ + /// Interface for custom explorer pages. + public interface IExplorerPage : IAddInComponent + { + /// Gets the icon to be displayed on the page tab. + Icon Icon { get; } + + /// Gets the control to be displayed on the page. + Control Control { get; } + } +} \ No newline at end of file diff --git a/Labyrinth3/Data/Extensibility/INotePage.cs b/Labyrinth3/Data/Extensibility/INotePage.cs new file mode 100644 index 0000000..624e111 --- /dev/null +++ b/Labyrinth3/Data/Extensibility/INotePage.cs @@ -0,0 +1,21 @@ +// Decompiled with JetBrains decompiler +// Type: Labyrinth.Extensibility.INotePage +// Assembly: Data, Version=3.6.1928.15689, Culture=neutral, PublicKeyToken=null +// MVID: DD3860A9-34AC-4A51-A3EB-CBA78B243957 +// Assembly location: C:\Dropbox\Workspace\Programs\Labyrinth\Data.dll + +using Labyrinth.Events; +using Labyrinth.Plot; + +namespace Labyrinth.Extensibility +{ + /// Interface implemented by note pages. + public interface INotePage : IPage + { + /// Gets the note. + Note Note { get; } + + /// Occurs when the note is modified. + event NoteEventHandler NoteModified; + } +} \ No newline at end of file diff --git a/Labyrinth3/Data/Extensibility/IPage.cs b/Labyrinth3/Data/Extensibility/IPage.cs new file mode 100644 index 0000000..2134cac --- /dev/null +++ b/Labyrinth3/Data/Extensibility/IPage.cs @@ -0,0 +1,30 @@ +// Decompiled with JetBrains decompiler +// Type: Labyrinth.Extensibility.IPage +// Assembly: Data, Version=3.6.1928.15689, Culture=neutral, PublicKeyToken=null +// MVID: DD3860A9-34AC-4A51-A3EB-CBA78B243957 +// Assembly location: C:\Dropbox\Workspace\Programs\Labyrinth\Data.dll + +namespace Labyrinth.Extensibility +{ + /// + /// Interface implemented by Labyrinth pages. + /// This interface must be implemented by a class derived from + /// System.Windows.Forms.Control. + /// + public interface IPage + { + /// Gets the title of the page. + string Title { get; } + + /// + /// Gets a value indicating whether this page should be closed. + /// + bool IsObsolete { get; } + + /// Called by the system to update UI cues. + void UpdateUI(); + + /// Called by the system when the project changes. + void UpdateData(); + } +} \ No newline at end of file diff --git a/Labyrinth3/Data/Extensibility/ISearchPage.cs b/Labyrinth3/Data/Extensibility/ISearchPage.cs new file mode 100644 index 0000000..7f31ff3 --- /dev/null +++ b/Labyrinth3/Data/Extensibility/ISearchPage.cs @@ -0,0 +1,44 @@ +// Decompiled with JetBrains decompiler +// Type: Labyrinth.Extensibility.ISearchPage +// Assembly: Data, Version=3.6.1928.15689, Culture=neutral, PublicKeyToken=null +// MVID: DD3860A9-34AC-4A51-A3EB-CBA78B243957 +// Assembly location: C:\Dropbox\Workspace\Programs\Labyrinth\Data.dll + +using Labyrinth.Events; +using Labyrinth.Plot; + +namespace Labyrinth.Extensibility +{ + /// Interface implemented by the search page. + public interface ISearchPage : IPage + { + /// Gets or sets the text for the simple search. + string SimpleText { get; set; } + + /// + /// Gets or sets whether the simple search is case-sensitive. + /// + bool SimpleCaseSensitive { get; set; } + + /// Gets the currently selected search result. + SearchResult SelectedResult { get; } + + /// Occurs when an element is opened. + event ElementEventHandler ElementActivated; + + /// Occurs when an element is changed. + event ElementEventHandler ElementModified; + + /// Occurs when a structure is opened. + event StructureEventHandler StructureActivated; + + /// Occurs when a structure is changed. + event StructureEventHandler StructureModified; + + /// Occurs when a timeline is opened. + event TimelineEventHandler TimelineActivated; + + /// Occurs when a timeline is changed. + event TimelineEventHandler TimelineModified; + } +} \ No newline at end of file diff --git a/Labyrinth3/Data/Extensibility/IStructurePage.cs b/Labyrinth3/Data/Extensibility/IStructurePage.cs new file mode 100644 index 0000000..6ea9d9f --- /dev/null +++ b/Labyrinth3/Data/Extensibility/IStructurePage.cs @@ -0,0 +1,33 @@ +// Decompiled with JetBrains decompiler +// Type: Labyrinth.Extensibility.IStructurePage +// Assembly: Data, Version=3.6.1928.15689, Culture=neutral, PublicKeyToken=null +// MVID: DD3860A9-34AC-4A51-A3EB-CBA78B243957 +// Assembly location: C:\Dropbox\Workspace\Programs\Labyrinth\Data.dll + +using Labyrinth.Events; +using Labyrinth.Plot; + +namespace Labyrinth.Extensibility +{ + /// Interface implemented by structure pages. + public interface IStructurePage : IPage + { + /// Gets the structure. + Structure Structure { get; } + + /// Gets the currently selected node. + Node SelectedNode { get; } + + /// Gets the currently selected link. + Link SelectedLink { get; } + + /// Occurs when an element is opened. + event ElementEventHandler ElementActivated; + + /// Occurs when an element is changed. + event ElementEventHandler ElementModified; + + /// Occurs when the structure changes. + event StructureEventHandler StructureModified; + } +} \ No newline at end of file diff --git a/Labyrinth3/Data/Extensibility/ITaskPage.cs b/Labyrinth3/Data/Extensibility/ITaskPage.cs new file mode 100644 index 0000000..9be11c0 --- /dev/null +++ b/Labyrinth3/Data/Extensibility/ITaskPage.cs @@ -0,0 +1,17 @@ +// Decompiled with JetBrains decompiler +// Type: Labyrinth.Extensibility.ITaskPage +// Assembly: Data, Version=3.6.1928.15689, Culture=neutral, PublicKeyToken=null +// MVID: DD3860A9-34AC-4A51-A3EB-CBA78B243957 +// Assembly location: C:\Dropbox\Workspace\Programs\Labyrinth\Data.dll + +using Labyrinth.Plot; + +namespace Labyrinth.Extensibility +{ + /// Interface implemented by task pages. + public interface ITaskPage : IPage + { + /// Gets the selected task. + Task SelectedTask { get; } + } +} \ No newline at end of file diff --git a/Labyrinth3/Data/Extensibility/ITimelinePage.cs b/Labyrinth3/Data/Extensibility/ITimelinePage.cs new file mode 100644 index 0000000..6b22073 --- /dev/null +++ b/Labyrinth3/Data/Extensibility/ITimelinePage.cs @@ -0,0 +1,33 @@ +// Decompiled with JetBrains decompiler +// Type: Labyrinth.Extensibility.ITimelinePage +// Assembly: Data, Version=3.6.1928.15689, Culture=neutral, PublicKeyToken=null +// MVID: DD3860A9-34AC-4A51-A3EB-CBA78B243957 +// Assembly location: C:\Dropbox\Workspace\Programs\Labyrinth\Data.dll + +using Labyrinth.Events; +using Labyrinth.Plot; + +namespace Labyrinth.Extensibility +{ + /// Interface implemented by timeline pages. + public interface ITimelinePage : IPage + { + /// Gets the timeline. + Timeline Timeline { get; } + + /// Gets the currently selected element. + Element SelectedElement { get; } + + /// Gets the currently selected timeline point. + TimelinePoint SelectedPoint { get; } + + /// Occurs when an element is opened. + event ElementEventHandler ElementActivated; + + /// Occurs when an element is changed. + event ElementEventHandler ElementModified; + + /// Occurs when the timeline changes. + event TimelineEventHandler TimelineModified; + } +} \ No newline at end of file diff --git a/Labyrinth3/Data/Plot/Annotation.cs b/Labyrinth3/Data/Plot/Annotation.cs new file mode 100644 index 0000000..68c9886 --- /dev/null +++ b/Labyrinth3/Data/Plot/Annotation.cs @@ -0,0 +1,42 @@ +// Decompiled with JetBrains decompiler +// Type: Labyrinth.Plot.Annotation +// Assembly: Data, Version=3.6.1928.15689, Culture=neutral, PublicKeyToken=null +// MVID: DD3860A9-34AC-4A51-A3EB-CBA78B243957 +// Assembly location: C:\Dropbox\Workspace\Programs\Labyrinth\Data.dll + +using System; + +namespace Labyrinth.Plot +{ + /// A piece of explanatory or expositionary content. + public abstract class Annotation + { + private Guid fID = Guid.NewGuid(); + + /// Gets or sets the ID. + public Guid ID + { + get + { + return this.fID; + } + set + { + this.fID = value; + } + } + + /// Gets or sets the title of the annotation. + public abstract string Title { get; set; } + + /// Gets or sets the content of the annotation. + public abstract string Content { get; set; } + + /// Returns a string representation of the object. + /// Returns a string representation of the object. + public override string ToString() + { + return this.Title; + } + } +} \ No newline at end of file diff --git a/Labyrinth3/Data/Plot/Element.cs b/Labyrinth3/Data/Plot/Element.cs new file mode 100644 index 0000000..259bd3a --- /dev/null +++ b/Labyrinth3/Data/Plot/Element.cs @@ -0,0 +1,79 @@ +// Decompiled with JetBrains decompiler +// Type: Labyrinth.Plot.Element +// Assembly: Data, Version=3.6.1928.15689, Culture=neutral, PublicKeyToken=null +// MVID: DD3860A9-34AC-4A51-A3EB-CBA78B243957 +// Assembly location: C:\Dropbox\Workspace\Programs\Labyrinth\Data.dll + +using System; +using System.Collections.Generic; +using System.Xml.Serialization; + +namespace Labyrinth.Plot +{ + /// A plot element. + public class Element + { + private Guid fID = Guid.NewGuid(); + private string fName = ""; + private ElementType fType = ElementType.Generic; + private List fAnnotations = new List(); + + /// Gets or sets the element's ID. + public Guid ID + { + get + { + return this.fID; + } + set + { + this.fID = value; + } + } + + /// Gets or sets the element's name. + public string Name + { + get + { + return this.fName; + } + set + { + this.fName = value; + } + } + + /// Gets or sets the element's type. + public ElementType Type + { + get + { + return this.fType; + } + set + { + this.fType = value; + } + } + + /// Gets the collection of annotations for the element. + [XmlArrayItem(typeof(TextAnnotation))] + [XmlArrayItem(typeof(SketchAnnotation))] + [XmlArrayItem(typeof(LinkAnnotation))] + public List Annotations + { + get + { + return this.fAnnotations; + } + } + + /// Returns a string representation of the element. + /// Returns a string representation of the element. + public override string ToString() + { + return this.fName; + } + } +} \ No newline at end of file diff --git a/Labyrinth3/Data/Plot/ElementType.cs b/Labyrinth3/Data/Plot/ElementType.cs new file mode 100644 index 0000000..939b0a4 --- /dev/null +++ b/Labyrinth3/Data/Plot/ElementType.cs @@ -0,0 +1,26 @@ +// Decompiled with JetBrains decompiler +// Type: Labyrinth.Plot.ElementType +// Assembly: Data, Version=3.6.1928.15689, Culture=neutral, PublicKeyToken=null +// MVID: DD3860A9-34AC-4A51-A3EB-CBA78B243957 +// Assembly location: C:\Dropbox\Workspace\Programs\Labyrinth\Data.dll + +namespace Labyrinth.Plot +{ + /// Types of plot elements. + public enum ElementType + { + Generic, + Character, + Organisation, + Website, + EmailAccount, + PhoneNumber, + File, + Puzzle, + Location, + Vehicle, + Concept, + Object, + Event, + } +} \ No newline at end of file diff --git a/Labyrinth3/Data/Plot/Importance.cs b/Labyrinth3/Data/Plot/Importance.cs new file mode 100644 index 0000000..5e8ddee --- /dev/null +++ b/Labyrinth3/Data/Plot/Importance.cs @@ -0,0 +1,16 @@ +// Decompiled with JetBrains decompiler +// Type: Labyrinth.Plot.Importance +// Assembly: Data, Version=3.6.1928.15689, Culture=neutral, PublicKeyToken=null +// MVID: DD3860A9-34AC-4A51-A3EB-CBA78B243957 +// Assembly location: C:\Dropbox\Workspace\Programs\Labyrinth\Data.dll + +namespace Labyrinth.Plot +{ + /// The importance of a task. + public enum Importance + { + Low, + Normal, + High, + } +} \ No newline at end of file diff --git a/Labyrinth3/Data/Plot/Link.cs b/Labyrinth3/Data/Plot/Link.cs new file mode 100644 index 0000000..0b2b913 --- /dev/null +++ b/Labyrinth3/Data/Plot/Link.cs @@ -0,0 +1,95 @@ +// Decompiled with JetBrains decompiler +// Type: Labyrinth.Plot.Link +// Assembly: Data, Version=3.6.1928.15689, Culture=neutral, PublicKeyToken=null +// MVID: DD3860A9-34AC-4A51-A3EB-CBA78B243957 +// Assembly location: C:\Dropbox\Workspace\Programs\Labyrinth\Data.dll + +using System; + +namespace Labyrinth.Plot +{ + /// A link between two plot elements. + public class Link + { + private Guid fID = Guid.NewGuid(); + private string fDescription = ""; + private Guid fLHS = Guid.Empty; + private Guid fRHS = Guid.Empty; + private LinkDirection fDirection = LinkDirection.Single; + + /// Gets or sets the link's ID. + public Guid ID + { + get + { + return this.fID; + } + set + { + this.fID = value; + } + } + + /// Gets or sets the text associated with the link. + public string Description + { + get + { + return this.fDescription; + } + set + { + this.fDescription = value; + } + } + + /// The ID of the element the link is from. + public Guid LHS + { + get + { + return this.fLHS; + } + set + { + this.fLHS = value; + } + } + + /// The ID of the element the link is to. + public Guid RHS + { + get + { + return this.fRHS; + } + set + { + this.fRHS = value; + } + } + + /// + /// The direction of the link. + /// This governs the placement of arrowheads. + /// + public LinkDirection Direction + { + get + { + return this.fDirection; + } + set + { + this.fDirection = value; + } + } + + /// Returns a string representation of the link. + /// Returns a string representation of the link. + public override string ToString() + { + return this.fDescription; + } + } +} \ No newline at end of file diff --git a/Labyrinth3/Data/Plot/LinkAnnotation.cs b/Labyrinth3/Data/Plot/LinkAnnotation.cs new file mode 100644 index 0000000..fde5551 --- /dev/null +++ b/Labyrinth3/Data/Plot/LinkAnnotation.cs @@ -0,0 +1,42 @@ +// Decompiled with JetBrains decompiler +// Type: Labyrinth.Plot.LinkAnnotation +// Assembly: Data, Version=3.6.1928.15689, Culture=neutral, PublicKeyToken=null +// MVID: DD3860A9-34AC-4A51-A3EB-CBA78B243957 +// Assembly location: C:\Dropbox\Workspace\Programs\Labyrinth\Data.dll + +using System.IO; + +namespace Labyrinth.Plot +{ + /// An annotation containing a link to a file. + public class LinkAnnotation : Annotation + { + private string fContent = ""; + + /// Gets the name of the file. + public override string Title + { + get + { + FileInfo fileInfo = new FileInfo(this.fContent); + return fileInfo.Exists ? fileInfo.Name : ""; + } + set + { + } + } + + /// Gets or sets the filename. + public override string Content + { + get + { + return this.fContent; + } + set + { + this.fContent = value; + } + } + } +} \ No newline at end of file diff --git a/Labyrinth3/Data/Plot/LinkDirection.cs b/Labyrinth3/Data/Plot/LinkDirection.cs new file mode 100644 index 0000000..ad5c09d --- /dev/null +++ b/Labyrinth3/Data/Plot/LinkDirection.cs @@ -0,0 +1,16 @@ +// Decompiled with JetBrains decompiler +// Type: Labyrinth.Plot.LinkDirection +// Assembly: Data, Version=3.6.1928.15689, Culture=neutral, PublicKeyToken=null +// MVID: DD3860A9-34AC-4A51-A3EB-CBA78B243957 +// Assembly location: C:\Dropbox\Workspace\Programs\Labyrinth\Data.dll + +namespace Labyrinth.Plot +{ + /// Directions for links. + public enum LinkDirection + { + None, + Single, + Double, + } +} \ No newline at end of file diff --git a/Labyrinth3/Data/Plot/Node.cs b/Labyrinth3/Data/Plot/Node.cs new file mode 100644 index 0000000..d1afd66 --- /dev/null +++ b/Labyrinth3/Data/Plot/Node.cs @@ -0,0 +1,44 @@ +// Decompiled with JetBrains decompiler +// Type: Labyrinth.Plot.Node +// Assembly: Data, Version=3.6.1928.15689, Culture=neutral, PublicKeyToken=null +// MVID: DD3860A9-34AC-4A51-A3EB-CBA78B243957 +// Assembly location: C:\Dropbox\Workspace\Programs\Labyrinth\Data.dll + +using System; +using System.Drawing; + +namespace Labyrinth.Plot +{ + /// A node in a structure. + public class Node + { + private Guid fElementID = Guid.Empty; + private PointF fPosition = PointF.Empty; + + /// The ID of the element. + public Guid ElementID + { + get + { + return this.fElementID; + } + set + { + this.fElementID = value; + } + } + + /// The location of the node. + public PointF Position + { + get + { + return this.fPosition; + } + set + { + this.fPosition = value; + } + } + } +} \ No newline at end of file diff --git a/Labyrinth3/Data/Plot/Note.cs b/Labyrinth3/Data/Plot/Note.cs new file mode 100644 index 0000000..44e1ac4 --- /dev/null +++ b/Labyrinth3/Data/Plot/Note.cs @@ -0,0 +1,94 @@ +// Decompiled with JetBrains decompiler +// Type: Labyrinth.Plot.Note +// Assembly: Data, Version=3.6.1928.15689, Culture=neutral, PublicKeyToken=null +// MVID: DD3860A9-34AC-4A51-A3EB-CBA78B243957 +// Assembly location: C:\Dropbox\Workspace\Programs\Labyrinth\Data.dll + +using System; + +namespace Labyrinth.Plot +{ + /// Represents a text note. + public class Note + { + private Guid fID = Guid.NewGuid(); + private string fTitle = ""; + private string fRTF = ""; + private string fText = ""; + private bool fTemplate = false; + + /// Gets or sets the note's ID. + public Guid ID + { + get + { + return this.fID; + } + set + { + this.fID = value; + } + } + + /// Gets or sets the title of the note. + public string Title + { + get + { + return this.fTitle; + } + set + { + this.fTitle = value; + } + } + + /// Gets or sets the note's RTF text. + public string RTF + { + get + { + return this.fRTF; + } + set + { + this.fRTF = value; + } + } + + /// Gets or sets the note's text. + public string Text + { + get + { + return this.fText; + } + set + { + this.fText = value; + } + } + + /// + /// Gets or sets whether the note is an annotation template. + /// + public bool IsTemplate + { + get + { + return this.fTemplate; + } + set + { + this.fTemplate = value; + } + } + + /// Returns a string representation of the object. + /// Returns a string representation of the object. + public override string ToString() + { + return this.fTitle; + } + } +} \ No newline at end of file diff --git a/Labyrinth3/Data/Plot/Project.cs b/Labyrinth3/Data/Plot/Project.cs new file mode 100644 index 0000000..e34ba0e --- /dev/null +++ b/Labyrinth3/Data/Plot/Project.cs @@ -0,0 +1,184 @@ +using System.Collections.Generic; + +namespace Labyrinth.Plot +{ + /// A plot project. + public class Project + { + private string fSaveFormat = "3.5"; + private string fName = ""; + private List fElements = new List(); + private List fStructures = new List(); + private List fTimelines = new List(); + private List fTasks = new List(); + private List fNotes = new List(); + + /// Gets or sets the save format version. + public string SaveFormat + { + get + { + return this.fSaveFormat; + } + set + { + this.fSaveFormat = value; + } + } + + /// Gets or sets the project's name. + public string Name + { + get + { + return this.fName; + } + set + { + this.fName = value; + } + } + + /// Gets the collection of elements in this project. + public List Elements + { + get + { + return this.fElements; + } + } + + /// Gets the collection of structures in this project. + public List Structures + { + get + { + return this.fStructures; + } + } + + /// Gets the collection of timelines in this project. + public List Timelines + { + get + { + return this.fTimelines; + } + } + + /// Gets the collection of task items. + public List Tasks + { + get + { + return this.fTasks; + } + } + + /// Gets the collection of note items. + public List Notes + { + get + { + return this.fNotes; + } + } + + /// + /// Deletes an element from a project. + /// This also removes all references to the element in all structures and timelines. + /// + /// The element to be removed + public void RemoveElement(Element e) + { + this.fElements.Remove(e); + foreach (Structure fStructure in this.fStructures) + fStructure.RemoveElement(e.ID); + foreach (Timeline fTimeline in this.fTimelines) + fTimeline.RemoveElement(e.ID); + } + + /// + /// Merges the content of several elements into a new element. + /// + /// The old elements + /// The new element + public void MergeElements(Element[] oldelements, Element newelement) + { + foreach (Element oldelement in oldelements) + newelement.Annotations.AddRange(oldelement.Annotations); + foreach (Structure fStructure in this.fStructures) + fStructure.MergeElements(oldelements, newelement); + foreach (Timeline fTimeline in this.fTimelines) + fTimeline.MergeElements(oldelements, newelement); + foreach (var oldelement in oldelements) + this.fElements.Remove(oldelement); + } + + /// Performs a simple search on the project. + /// The terms to search for. + /// Whether case is taken into account. + /// Whether a logical NOT is applied to the search. + /// A list of search results. + public SearchResult[] PerformSearch(string[] terms, bool casesensitive, bool negated) + { + var arrayList = new List(); + foreach (Element fElement in this.fElements) + { + if (this.match(fElement.Name, terms, casesensitive, negated)) + arrayList.Add(new SearchResult(fElement, null)); + foreach (Annotation annotation in fElement.Annotations) + { + if (this.match(annotation.Title, terms, casesensitive, negated) || this.match(annotation.Content, terms, casesensitive, negated)) + arrayList.Add(new SearchResult(annotation, fElement)); + } + } + foreach (Structure fStructure in this.fStructures) + { + if (this.match(fStructure.Name, terms, casesensitive, negated)) + arrayList.Add(new SearchResult(fStructure, null)); + foreach (Link link in fStructure.Links) + { + if (this.match(link.Description, terms, casesensitive, negated)) + arrayList.Add(new SearchResult(link, fStructure)); + } + } + foreach (Timeline fTimeline in this.fTimelines) + { + if (this.match(fTimeline.Name, terms, casesensitive, negated)) + arrayList.Add(new SearchResult(fTimeline, null)); + foreach (TimelinePoint point in fTimeline.Points) + { + foreach (TimelineItem timelineItem in point.Items) + { + if (this.match(timelineItem.Annotation.Title, terms, casesensitive, negated) || this.match(timelineItem.Annotation.Content, terms, casesensitive, negated)) + arrayList.Add(new SearchResult(timelineItem.Annotation, fTimeline)); + } + } + } + foreach (Task fTask in this.fTasks) + { + if (this.match(fTask.Title, terms, casesensitive, negated) || this.match(fTask.Details, terms, casesensitive, negated)) + arrayList.Add(new SearchResult(fTask, null)); + } + foreach (Note fNote in this.fNotes) + { + if (this.match(fNote.Title, terms, casesensitive, negated) || this.match(fNote.Text, terms, casesensitive, negated)) + arrayList.Add(new SearchResult(fNote, null)); + } + return arrayList.ToArray(); + } + + private bool match(string source, string[] terms, bool casesensitive, bool negated) + { + string str1 = casesensitive ? source : source.ToLower(); + foreach (string term in terms) + { + string str2 = casesensitive ? term : term.ToLower(); + if (str1.IndexOf(str2) != -1 == negated) + return false; + } + return true; + } + } +} \ No newline at end of file diff --git a/Labyrinth3/Data/Plot/ScheduleType.cs b/Labyrinth3/Data/Plot/ScheduleType.cs new file mode 100644 index 0000000..770141e --- /dev/null +++ b/Labyrinth3/Data/Plot/ScheduleType.cs @@ -0,0 +1,16 @@ +// Decompiled with JetBrains decompiler +// Type: Labyrinth.Plot.ScheduleType +// Assembly: Data, Version=3.6.1928.15689, Culture=neutral, PublicKeyToken=null +// MVID: DD3860A9-34AC-4A51-A3EB-CBA78B243957 +// Assembly location: C:\Dropbox\Workspace\Programs\Labyrinth\Data.dll + +namespace Labyrinth.Plot +{ + /// Types of scheduling. + public enum ScheduleType + { + None, + Date, + DateTime, + } +} \ No newline at end of file diff --git a/Labyrinth3/Data/Plot/SearchResult.cs b/Labyrinth3/Data/Plot/SearchResult.cs new file mode 100644 index 0000000..f2e81f6 --- /dev/null +++ b/Labyrinth3/Data/Plot/SearchResult.cs @@ -0,0 +1,42 @@ +// Decompiled with JetBrains decompiler +// Type: Labyrinth.Plot.SearchResult +// Assembly: Data, Version=3.6.1928.15689, Culture=neutral, PublicKeyToken=null +// MVID: DD3860A9-34AC-4A51-A3EB-CBA78B243957 +// Assembly location: C:\Dropbox\Workspace\Programs\Labyrinth\Data.dll + +namespace Labyrinth.Plot +{ + /// An item returned by a search. + public class SearchResult + { + private object fData; + private object fDetails; + + /// Constructor. + /// The item returned by the search. + /// The secondary information about this result. + public SearchResult(object data, object details) + { + this.fData = data; + this.fDetails = details; + } + + /// Gets the item returned by the search. + public object Data + { + get + { + return this.fData; + } + } + + /// Gets secondary information about this result. + public object Details + { + get + { + return this.fDetails; + } + } + } +} \ No newline at end of file diff --git a/Labyrinth3/Data/Plot/SketchAnnotation.cs b/Labyrinth3/Data/Plot/SketchAnnotation.cs new file mode 100644 index 0000000..1875fe9 --- /dev/null +++ b/Labyrinth3/Data/Plot/SketchAnnotation.cs @@ -0,0 +1,89 @@ +// Decompiled with JetBrains decompiler +// Type: Labyrinth.Plot.SketchAnnotation +// Assembly: Data, Version=3.6.1928.15689, Culture=neutral, PublicKeyToken=null +// MVID: DD3860A9-34AC-4A51-A3EB-CBA78B243957 +// Assembly location: C:\Dropbox\Workspace\Programs\Labyrinth\Data.dll + +using System; +using System.Drawing; +using System.Drawing.Imaging; +using System.IO; +using System.Xml.Serialization; + +namespace Labyrinth.Plot +{ + /// An annotation containing a drawn image. + public class SketchAnnotation : Annotation + { + private string fTitle = ""; + private string fContent = ""; + private Image fSketch = (Image)null; + + /// Constructor. + public SketchAnnotation() + { + this.fSketch = (Image)new Bitmap(1000, 1000); + Graphics.FromImage(this.fSketch).Clear(Color.White); + } + + /// Gets or sets the title of the image. + public override string Title + { + get + { + return this.fTitle; + } + set + { + this.fTitle = value; + } + } + + /// Gets or sets a description of the image. + public override string Content + { + get + { + return this.fContent; + } + set + { + this.fContent = value; + } + } + + /// Gets or sets the image. + [XmlIgnore] + public Image Sketch + { + get + { + return this.fSketch; + } + set + { + this.fSketch = value; + } + } + + /// Gets or sets the image as a byte array. + public byte[] ImageData + { + get + { + MemoryStream memoryStream = new MemoryStream(); + this.fSketch.Save((Stream)memoryStream, ImageFormat.Gif); + int int32 = Convert.ToInt32(memoryStream.Length); + byte[] buffer = new byte[(int)checked((uint)int32)]; + memoryStream.Position = 0L; + memoryStream.Read(buffer, 0, int32); + memoryStream.Close(); + return buffer; + } + set + { + this.fSketch = (Image)new Bitmap((Image)new Bitmap((Stream)new MemoryStream(value))); + } + } + } +} \ No newline at end of file diff --git a/Labyrinth3/Data/Plot/Structure.cs b/Labyrinth3/Data/Plot/Structure.cs new file mode 100644 index 0000000..1a22f65 --- /dev/null +++ b/Labyrinth3/Data/Plot/Structure.cs @@ -0,0 +1,144 @@ +using System; +using System.Collections.Generic; +using System.Drawing; + +namespace Labyrinth.Plot +{ + /// + /// Class holding information on relationships between plot elements. + /// + public class Structure + { + private Guid fID = Guid.NewGuid(); + private string fName = ""; + private List fNodes = new List(); + private List fLinks = new List(); + + /// Gets or sets the structure's ID. + public Guid ID + { + get + { + return this.fID; + } + set + { + this.fID = value; + } + } + + /// Gets or sets the structure's name. + public string Name + { + get + { + return this.fName; + } + set + { + this.fName = value; + } + } + + /// Gets the collection of nodes in this structure. + public List Nodes + { + get + { + return this.fNodes; + } + } + + /// Gets the collection of links in this structure. + public List Links + { + get + { + return this.fLinks; + } + } + + /// Returns a string representation of the structure. + /// Returns a string representation of the structure. + public override string ToString() + { + return this.fName; + } + + /// Removes all references to an element. + /// The element to remove. + public void RemoveElement(Guid element_id) + { + var arrayList1 = new List(); + foreach (Node fNode in this.fNodes) + { + if (fNode.ElementID == element_id) + arrayList1.Add(fNode); + } + foreach (Node node in arrayList1) + this.fNodes.Remove(node); + + var arrayList2 = new List(); + foreach (Link fLink in this.fLinks) + { + if (fLink.LHS == element_id || fLink.RHS == element_id) + arrayList2.Add(fLink); + } + foreach (Link link in arrayList2) + this.fLinks.Remove(link); + } + + /// + /// Merges the content of several elements into a new element. + /// + /// The old elements + /// The new element + public void MergeElements(Element[] oldelements, Element newelement) + { + var arrayList1 = new List(); + foreach (Element oldelement in oldelements) + arrayList1.Add(oldelement.ID); + var arrayList2 = new List(); + float num1 = 0.0f; + float num2 = 0.0f; + foreach (Node fNode in this.fNodes) + { + if (arrayList1.Contains(fNode.ElementID)) + { + arrayList2.Add(fNode); + num1 += fNode.Position.X; + num2 += fNode.Position.Y; + } + } + foreach (Node node in arrayList2) + this.fNodes.Remove(node); + if (arrayList2.Count != 0) + { + Node node = new Node(); + node.ElementID = newelement.ID; + float x = num1 / (float)arrayList2.Count; + float y = num2 / (float)arrayList2.Count; + node.Position = new PointF(x, y); + this.fNodes.Add(node); + } + foreach (Element oldelement in oldelements) + { + foreach (Link fLink in this.fLinks) + { + if (fLink.LHS == oldelement.ID) + fLink.LHS = newelement.ID; + if (fLink.RHS == oldelement.ID) + fLink.RHS = newelement.ID; + } + } + var arrayList3 = new List(); + foreach (Link fLink in this.fLinks) + { + if (fLink.LHS == fLink.RHS) + arrayList3.Add(fLink); + } + foreach (Link link in arrayList3) + this.fLinks.Remove(link); + } + } +} \ No newline at end of file diff --git a/Labyrinth3/Data/Plot/Task.cs b/Labyrinth3/Data/Plot/Task.cs new file mode 100644 index 0000000..81cf118 --- /dev/null +++ b/Labyrinth3/Data/Plot/Task.cs @@ -0,0 +1,120 @@ +// Decompiled with JetBrains decompiler +// Type: Labyrinth.Plot.Task +// Assembly: Data, Version=3.6.1928.15689, Culture=neutral, PublicKeyToken=null +// MVID: DD3860A9-34AC-4A51-A3EB-CBA78B243957 +// Assembly location: C:\Dropbox\Workspace\Programs\Labyrinth\Data.dll + +using System; + +namespace Labyrinth.Plot +{ + /// Represents a task or to-do item. + public class Task + { + private Guid fID = Guid.NewGuid(); + private string fTitle = ""; + private string fDetails = ""; + private bool fCompleted = false; + private Importance fImportance = Importance.Normal; + private bool fHasDeadline = false; + private DateTime fDeadline = DateTime.MinValue; + + /// Gets or sets the task's ID. + public Guid ID + { + get + { + return this.fID; + } + set + { + this.fID = value; + } + } + + /// Gets or sets the title of the task. + public string Title + { + get + { + return this.fTitle; + } + set + { + this.fTitle = value; + } + } + + /// Gets or sets the task's details. + public string Details + { + get + { + return this.fDetails; + } + set + { + this.fDetails = value; + } + } + + /// Gets or sets whether the task has been completed. + public bool Completed + { + get + { + return this.fCompleted; + } + set + { + this.fCompleted = value; + } + } + + /// Gets or sets the task's importance. + public Importance Importance + { + get + { + return this.fImportance; + } + set + { + this.fImportance = value; + } + } + + /// Gets or sets whether the task has a set deadline. + public bool HasDeadline + { + get + { + return this.fHasDeadline; + } + set + { + this.fHasDeadline = value; + } + } + + /// Gets or sets the task's deadline. + public DateTime Deadline + { + get + { + return this.fDeadline; + } + set + { + this.fDeadline = value; + } + } + + /// Returns a string representation of the object. + /// Returns a string representation of the object. + public override string ToString() + { + return this.fTitle; + } + } +} \ No newline at end of file diff --git a/Labyrinth3/Data/Plot/TextAnnotation.cs b/Labyrinth3/Data/Plot/TextAnnotation.cs new file mode 100644 index 0000000..6741e5a --- /dev/null +++ b/Labyrinth3/Data/Plot/TextAnnotation.cs @@ -0,0 +1,55 @@ +// Decompiled with JetBrains decompiler +// Type: Labyrinth.Plot.TextAnnotation +// Assembly: Data, Version=3.6.1928.15689, Culture=neutral, PublicKeyToken=null +// MVID: DD3860A9-34AC-4A51-A3EB-CBA78B243957 +// Assembly location: C:\Dropbox\Workspace\Programs\Labyrinth\Data.dll + +namespace Labyrinth.Plot +{ + /// An annotation containing RTF text. + public class TextAnnotation : Annotation + { + private string fTitle = ""; + private string fContent = ""; + private string fRTF = ""; + + /// Gets or sets the title of the annotation. + public override string Title + { + get + { + return this.fTitle; + } + set + { + this.fTitle = value; + } + } + + /// Gets or sets the plaintext content of the annotation. + public override string Content + { + get + { + return this.fContent; + } + set + { + this.fContent = value; + } + } + + /// Gets or sets the RTF content of the annotation. + public string RTF + { + get + { + return this.fRTF; + } + set + { + this.fRTF = value; + } + } + } +} \ No newline at end of file diff --git a/Labyrinth3/Data/Plot/Timeline.cs b/Labyrinth3/Data/Plot/Timeline.cs new file mode 100644 index 0000000..42cdaed --- /dev/null +++ b/Labyrinth3/Data/Plot/Timeline.cs @@ -0,0 +1,139 @@ +using System; +using System.Collections.Generic; + +namespace Labyrinth.Plot +{ + /// + /// A timeline of events holding information about plot elements. + /// + public class Timeline + { + private Guid fID = Guid.NewGuid(); + private string fName = ""; + private List fElementIDs = new List(); + private List fPoints = new List(); + private bool fSorting = true; + + /// Gets or sets the timeline's ID. + public Guid ID + { + get + { + return this.fID; + } + set + { + this.fID = value; + } + } + + /// Gets or sets the timeline's name. + public string Name + { + get + { + return this.fName; + } + set + { + this.fName = value; + } + } + + /// Gets the list of elements in this timeline. + public List ElementIDs + { + get + { + return this.fElementIDs; + } + } + + /// Gets the list of points in this timeline. + public List Points + { + get + { + return this.fPoints; + } + } + + /// + /// Gets or sets a value indicating whether the timeline sorts its points by date. + /// + public bool Sorting + { + get + { + return this.fSorting; + } + set + { + this.fSorting = value; + } + } + + /// Returns a string representation of the timeline. + /// Returns a string representation of the timeline. + public override string ToString() + { + return this.fName; + } + + /// Removes all references to an element. + /// The element to remove. + public void RemoveElement(Guid element_id) + { + var arrayList1 = new List(); + foreach (Guid fElementId in this.fElementIDs) + { + if (fElementId == element_id) + arrayList1.Add(fElementId); + } + foreach (Guid guid in arrayList1) + this.fElementIDs.Remove(guid); + foreach (TimelinePoint fPoint in this.fPoints) + { + var arrayList2 = new List(); + foreach (TimelineItem timelineItem in fPoint.Items) + { + if (timelineItem.ElementID == element_id) + arrayList2.Add(timelineItem); + } + foreach (TimelineItem timelineItem in arrayList2) + fPoint.Items.Remove(timelineItem); + } + } + + /// + /// Merges the content of several elements into a new element. + /// + /// The old elements + /// The new element + public void MergeElements(Element[] oldelements, Element newelement) + { + var arrayList1 = new List(); + foreach (Element oldelement in oldelements) + arrayList1.Add(oldelement.ID); + + var arrayList2 = new List(); + foreach (Guid fElementId in this.fElementIDs) + { + if (arrayList1.Contains(fElementId)) + arrayList2.Add(fElementId); + } + foreach (Guid guid in arrayList2) + this.fElementIDs.Remove(guid); + if (arrayList2.Count != 0) + this.fElementIDs.Add(newelement.ID); + foreach (TimelinePoint fPoint in this.fPoints) + { + foreach (TimelineItem timelineItem in fPoint.Items) + { + if (arrayList1.Contains(timelineItem.ElementID)) + timelineItem.ElementID = newelement.ID; + } + } + } + } +} \ No newline at end of file diff --git a/Labyrinth3/Data/Plot/TimelineItem.cs b/Labyrinth3/Data/Plot/TimelineItem.cs new file mode 100644 index 0000000..aadcbca --- /dev/null +++ b/Labyrinth3/Data/Plot/TimelineItem.cs @@ -0,0 +1,59 @@ +// Decompiled with JetBrains decompiler +// Type: Labyrinth.Plot.TimelineItem +// Assembly: Data, Version=3.6.1928.15689, Culture=neutral, PublicKeyToken=null +// MVID: DD3860A9-34AC-4A51-A3EB-CBA78B243957 +// Assembly location: C:\Dropbox\Workspace\Programs\Labyrinth\Data.dll + +using System; + +namespace Labyrinth.Plot +{ + /// + /// Class representing information about a plot element at a point in a timeline. + /// + public class TimelineItem + { + private Guid fID = Guid.NewGuid(); + private Guid fElementID = Guid.Empty; + private TextAnnotation fAnnotation = new TextAnnotation(); + + /// Gets or sets the timeline item's ID. + public Guid ID + { + get + { + return this.fID; + } + set + { + this.fID = value; + } + } + + /// Gets or sets the ID of the plot element. + public Guid ElementID + { + get + { + return this.fElementID; + } + set + { + this.fElementID = value; + } + } + + /// Gets or sets the annotation for this item. + public TextAnnotation Annotation + { + get + { + return this.fAnnotation; + } + set + { + this.fAnnotation = value; + } + } + } +} \ No newline at end of file diff --git a/Labyrinth3/Data/Plot/TimelinePoint.cs b/Labyrinth3/Data/Plot/TimelinePoint.cs new file mode 100644 index 0000000..5fc1ecb --- /dev/null +++ b/Labyrinth3/Data/Plot/TimelinePoint.cs @@ -0,0 +1,101 @@ +// Decompiled with JetBrains decompiler +// Type: Labyrinth.Plot.TimelinePoint +// Assembly: Data, Version=3.6.1928.15689, Culture=neutral, PublicKeyToken=null +// MVID: DD3860A9-34AC-4A51-A3EB-CBA78B243957 +// Assembly location: C:\Dropbox\Workspace\Programs\Labyrinth\Data.dll + +using System; +using System.Collections.Generic; + +namespace Labyrinth.Plot +{ + /// Class representing a point in a timeline. + public class TimelinePoint : IComparable + { + private Guid fID = Guid.NewGuid(); + private string fName = ""; + private ScheduleType fUseSchedule = ScheduleType.None; + private DateTime fSchedule = DateTime.MinValue; + private List fItems = new List(); + + /// Gets or sets the timeline point's ID. + public Guid ID + { + get + { + return this.fID; + } + set + { + this.fID = value; + } + } + + /// Gets or sets the timeline point's name. + public string Name + { + get + { + return this.fName; + } + set + { + this.fName = value; + } + } + + /// + /// Gets or sets whether the point is scheduled for a specific date and time. + /// + public ScheduleType UseSchedule + { + get + { + return this.fUseSchedule; + } + set + { + this.fUseSchedule = value; + } + } + + /// Gets or sets the date and time the point occurs on. + public DateTime Schedule + { + get + { + return this.fSchedule; + } + set + { + this.fSchedule = value; + } + } + + /// Gets the list of items in this point. + public List Items + { + get + { + return this.fItems; + } + } + + /// Compares this instance with a specified object. + /// An Object that evaluates to a TimelinePoint. + /// A value indicating the relative order of the two objects. + public int CompareTo(object obj) + { + TimelinePoint timelinePoint = obj as TimelinePoint; + if (timelinePoint == null) + throw new ArgumentException(); + if (this.fUseSchedule == ScheduleType.None && timelinePoint.UseSchedule == ScheduleType.None) + return this.fName.CompareTo(timelinePoint.Name); + if (this.fUseSchedule == ScheduleType.None) + return -1; + if (timelinePoint.UseSchedule == ScheduleType.None) + return 1; + return this.fSchedule.CompareTo((object)timelinePoint.Schedule); + } + } +} \ No newline at end of file diff --git a/Labyrinth3/IDE/Annotations.cs b/Labyrinth3/IDE/Annotations.cs new file mode 100644 index 0000000..0fc33f3 --- /dev/null +++ b/Labyrinth3/IDE/Annotations.cs @@ -0,0 +1,124 @@ +// Decompiled with JetBrains decompiler +// Type: Labyrinth.Annotations +// Assembly: Labyrinth, Version=3.6.1928.15690, Culture=neutral, PublicKeyToken=null +// MVID: 1462002E-0BD1-49D2-9B56-C22E66C903E7 +// Assembly location: C:\Dropbox\Workspace\Programs\Labyrinth\Labyrinth.exe + +using Labyrinth.Forms; +using Labyrinth.Plot; +using System; +using System.Drawing; +using System.Windows.Forms; + +namespace Labyrinth +{ + public class Annotations + { + private const int fMaxLines = 5; + + public static bool Open(Annotation a) + { + TextAnnotation note1 = a as TextAnnotation; + if (note1 != null) + return new TextAnnotationDlg(note1).ShowDialog() == DialogResult.OK; + LinkAnnotation note2 = a as LinkAnnotation; + if (note2 != null) + return new FileLinkAnnotationDlg(note2).ShowDialog() == DialogResult.OK; + SketchAnnotation note3 = a as SketchAnnotation; + if (note3 != null) + return new SketchAnnotationDlg(note3).ShowDialog() == DialogResult.OK; + return false; + } + + public static string SimplifyContent(Annotation a) + { + string str1 = a.Content.Trim(); + string str2; + do + { + str2 = str1; + str1 = str1.Replace(Environment.NewLine + Environment.NewLine, Environment.NewLine); + } + while (!(str1 == str2)); + return str1; + } + + public static int MeasureHeight(Annotation a, int maxwidth, Font f, Graphics g) + { + Image image = Annotations.GetImage(a); + int width = image != null ? maxwidth - image.Width : maxwidth; + float num1 = 0.0f; + SizeF sizeF; + if (a.Title != "") + { + Font font = new Font(f, f.Style | FontStyle.Bold); + sizeF = g.MeasureString(a.Title, f, width); + num1 = sizeF.Height; + } + float num2; + if (a is SketchAnnotation) + { + num2 = (float)(5 * f.Height); + } + else + { + string text = Annotations.SimplifyContent(a); + sizeF = g.MeasureString(text, f, width); + num2 = Math.Min(sizeF.Height, (float)(5 * f.Height)); + } + int val1 = (int)((double)num1 + (double)num2); + if (image == null) + return val1; + return Math.Max(val1, image.Height); + } + + public static void Render(Annotation a, Rectangle rect, Font f, Graphics g, bool selected, bool showicon) + { + if (showicon) + { + Image image = Annotations.GetImage(a); + if (image != null) + g.DrawImage(image, rect.X, rect.Y); + if (image != null) + { + rect.X += image.Width; + rect.Width -= image.Width; + } + } + Brush brush = SystemBrushes.WindowText; + if (selected) + brush = SystemBrushes.HighlightText; + StringFormat format = new StringFormat(); + format.Trimming = StringTrimming.EllipsisWord; + format.FormatFlags |= StringFormatFlags.LineLimit; + float num = 0.0f; + if (a.Title != "") + { + Font font = new Font(f, f.Style | FontStyle.Bold); + num = g.MeasureString(a.Title, font, rect.Width).Height; + g.DrawString(a.Title, font, brush, (RectangleF)rect, format); + } + rect.Y += (int)num; + rect.Height -= (int)num; + if (a is SketchAnnotation) + { + rect.Inflate(-1, -1); + SketchAnnotation sketchAnnotation = a as SketchAnnotation; + g.DrawImage(sketchAnnotation.Sketch, rect); + } + else + { + string s = Annotations.SimplifyContent(a); + g.DrawString(s, f, brush, (RectangleF)rect, format); + } + } + + public static Image GetImage(Annotation a) + { + int imageIndex = LabyrinthData.GetImageIndex(a); + if (imageIndex != -1) + return LabyrinthData.ElementImages.Images[imageIndex]; + return (Image)null; + } + } +} \ No newline at end of file diff --git a/Labyrinth3/IDE/Controls/AnnotationList.cs b/Labyrinth3/IDE/Controls/AnnotationList.cs new file mode 100644 index 0000000..f2bd5a9 --- /dev/null +++ b/Labyrinth3/IDE/Controls/AnnotationList.cs @@ -0,0 +1,92 @@ +// Decompiled with JetBrains decompiler +// Type: Labyrinth.Controls.AnnotationList +// Assembly: Labyrinth, Version=3.6.1928.15690, Culture=neutral, PublicKeyToken=null +// MVID: 1462002E-0BD1-49D2-9B56-C22E66C903E7 +// Assembly location: C:\Dropbox\Workspace\Programs\Labyrinth\Labyrinth.exe + +using Labyrinth.Plot; +using System; +using System.Drawing; +using System.Windows.Forms; + +namespace Labyrinth.Controls +{ + public class AnnotationList : ListBox + { + public AnnotationList() + { + this.InitializeComponent(); + this.SetStyle(ControlStyles.ResizeRedraw, true); + } + + private void InitializeComponent() + { + this.Size = new Size(512, 264); + } + + public Annotation SelectedAnnotation + { + get + { + try + { + return this.SelectedItem as Annotation; + } + catch (Exception ex) + { + LabyrinthData.Log((object)ex); + } + return (Annotation)null; + } + set + { + this.SelectedItem = (object)value; + } + } + + protected override void OnMeasureItem(MeasureItemEventArgs e) + { + try + { + if (e.Index == -1 || e.Index >= this.Items.Count) + return; + Annotation a = this.Items[e.Index] as Annotation; + if (a == null) + return; + e.ItemHeight = Annotations.MeasureHeight(a, this.Width, this.Font, e.Graphics); + } + catch (Exception ex) + { + LabyrinthData.Log((object)ex); + } + } + + protected override void OnDrawItem(DrawItemEventArgs e) + { + try + { + if (e.Index == -1 || e.Index >= this.Items.Count) + return; + Annotation a = this.Items[e.Index] as Annotation; + if (a == null) + return; + e.DrawBackground(); + bool selected = (e.State & DrawItemState.Selected) == DrawItemState.Selected; + Annotations.Render(a, e.Bounds, this.Font, e.Graphics, selected, true); + } + catch (Exception ex) + { + LabyrinthData.Log((object)ex); + } + } + + protected override void OnMouseDown(MouseEventArgs e) + { + int num = this.IndexFromPoint(e.X, e.Y); + if (num >= 0 && num < this.Items.Count) + this.SelectedIndex = num; + else + this.SelectedItem = (object)null; + } + } +} \ No newline at end of file diff --git a/Labyrinth3/IDE/Controls/AnnotationList.resx b/Labyrinth3/IDE/Controls/AnnotationList.resx new file mode 100644 index 0000000..f71162d --- /dev/null +++ b/Labyrinth3/IDE/Controls/AnnotationList.resx @@ -0,0 +1,127 @@ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + text/microsoft-resx + + + 2.0 + + + System.Resources.ResXResourceReader, System.Windows.Forms, Version=4.0.0.0, Culture=neutral, PublicKeyToken=b77a5c561934e089 + + + System.Resources.ResXResourceWriter, System.Windows.Forms, Version=4.0.0.0, Culture=neutral, PublicKeyToken=b77a5c561934e089 + + + + False + + + AnnotationList + + \ No newline at end of file diff --git a/Labyrinth3/IDE/Controls/AnnotationPanel.cs b/Labyrinth3/IDE/Controls/AnnotationPanel.cs new file mode 100644 index 0000000..2e64644 --- /dev/null +++ b/Labyrinth3/IDE/Controls/AnnotationPanel.cs @@ -0,0 +1,192 @@ +// Decompiled with JetBrains decompiler +// Type: Labyrinth.Controls.AnnotationPanel +// Assembly: Labyrinth, Version=3.6.1928.15690, Culture=neutral, PublicKeyToken=null +// MVID: 1462002E-0BD1-49D2-9B56-C22E66C903E7 +// Assembly location: C:\Dropbox\Workspace\Programs\Labyrinth\Labyrinth.exe + +using Labyrinth.Plot; +using System; +using System.Collections.Generic; +using System.ComponentModel; +using System.Drawing; +using System.Windows.Forms; + +namespace Labyrinth.Controls +{ + public class AnnotationPanel : UserControl + { + private Container components = (Container)null; + private List fAnnotations = new List(); + private Panel FilterPanel; + private Label FilterLbl; + private TextBox FilterBox; + private AnnotationList AnnotationList; + + public AnnotationPanel() + { + this.InitializeComponent(); + this.SetStyle(ControlStyles.DoubleBuffer, true); + this.SetStyle(ControlStyles.UserPaint, true); + this.SetStyle(ControlStyles.AllPaintingInWmPaint, true); + this.SetStyle(ControlStyles.ResizeRedraw, true); + } + + protected override void Dispose(bool disposing) + { + if (disposing && this.components != null) + this.components.Dispose(); + base.Dispose(disposing); + } + + private void InitializeComponent() + { + this.FilterPanel = new Panel(); + this.FilterBox = new TextBox(); + this.FilterLbl = new Label(); + this.AnnotationList = new AnnotationList(); + this.FilterPanel.SuspendLayout(); + this.SuspendLayout(); + this.FilterPanel.BorderStyle = BorderStyle.Fixed3D; + this.FilterPanel.Controls.AddRange(new Control[2] + { + (Control) this.FilterBox, + (Control) this.FilterLbl + }); + this.FilterPanel.Dock = DockStyle.Top; + this.FilterPanel.Name = "FilterPanel"; + this.FilterPanel.Size = new Size(408, 56); + this.FilterPanel.TabIndex = 0; + this.FilterPanel.Visible = false; + this.FilterBox.Anchor = AnchorStyles.Top | AnchorStyles.Left | AnchorStyles.Right; + this.FilterBox.Location = new Point(112, 16); + this.FilterBox.Name = "FilterBox"; + this.FilterBox.ScrollBars = ScrollBars.Vertical; + this.FilterBox.Size = new Size(276, 20); + this.FilterBox.TabIndex = 1; + this.FilterBox.Text = ""; + this.FilterBox.TextChanged += new EventHandler(this.FilterBox_TextChanged); + this.FilterLbl.Location = new Point(8, 16); + this.FilterLbl.Name = "FilterLbl"; + this.FilterLbl.Size = new Size(96, 24); + this.FilterLbl.TabIndex = 0; + this.FilterLbl.Text = "Show annotations containing:"; + this.FilterLbl.TextAlign = ContentAlignment.MiddleLeft; + this.AnnotationList.Dock = DockStyle.Fill; + this.AnnotationList.DrawMode = DrawMode.OwnerDrawVariable; + this.AnnotationList.Location = new Point(0, 56); + this.AnnotationList.Name = "AnnotationList"; + this.AnnotationList.SelectedAnnotation = (Annotation)null; + this.AnnotationList.Size = new Size(408, 232); + this.AnnotationList.TabIndex = 5; + this.AnnotationList.DoubleClick += new EventHandler(this.AnnotationList_DoubleClick); + this.Controls.AddRange(new Control[2] + { + (Control) this.AnnotationList, + (Control) this.FilterPanel + }); + this.Name = nameof(AnnotationPanel); + this.Size = new Size(408, 288); + this.FilterPanel.ResumeLayout(false); + this.ResumeLayout(false); + } + + private void FilterBox_TextChanged(object sender, EventArgs e) + { + this.update_list(); + } + + public Annotation SelectedAnnotation + { + get + { + return this.AnnotationList.SelectedAnnotation; + } + set + { + this.AnnotationList.SelectedAnnotation = value; + } + } + + public int SelectedIndex + { + get + { + return this.AnnotationList.SelectedIndex; + } + set + { + this.AnnotationList.SelectedIndex = value; + } + } + + public bool ShowFilter + { + get + { + return this.FilterPanel.Visible; + } + set + { + this.FilterPanel.Visible = value; + } + } + + public bool FilterApplied + { + get + { + if (this.FilterPanel.Visible) + return this.FilterBox.Text != ""; + return false; + } + } + + public List Annotations + { + get + { + return this.fAnnotations; + } + set + { + this.fAnnotations = value; + this.update_list(); + } + } + + protected override void OnLayout(LayoutEventArgs e) + { + base.OnLayout(e); + this.update_list(); + } + + private void update_list() + { + this.AnnotationList.BeginUpdate(); + this.AnnotationList.Items.Clear(); + foreach (Annotation fAnnotation in this.fAnnotations) + { + bool flag = true; + if (this.FilterPanel.Visible && this.FilterBox.Text != "") + { + foreach (string str in this.FilterBox.Text.ToLower().Split((char[])null)) + { + if (fAnnotation.Title.ToLower().IndexOf(str) == -1 && fAnnotation.Content.ToLower().IndexOf(str) == -1) + { + flag = false; + break; + } + } + } + if (flag) + this.AnnotationList.Items.Add((object)fAnnotation); + } + this.AnnotationList.EndUpdate(); + } + + private void AnnotationList_DoubleClick(object sender, EventArgs e) + { + this.OnDoubleClick(e); + } + } +} \ No newline at end of file diff --git a/Labyrinth3/IDE/Controls/AnnotationPanel.resx b/Labyrinth3/IDE/Controls/AnnotationPanel.resx new file mode 100644 index 0000000..9ac66d7 --- /dev/null +++ b/Labyrinth3/IDE/Controls/AnnotationPanel.resx @@ -0,0 +1,123 @@ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + text/microsoft-resx + + + 2.0 + + + System.Resources.ResXResourceReader, System.Windows.Forms, Version=4.0.0.0, Culture=neutral, PublicKeyToken=b77a5c561934e089 + + + System.Resources.ResXResourceWriter, System.Windows.Forms, Version=4.0.0.0, Culture=neutral, PublicKeyToken=b77a5c561934e089 + + + AnnotationPanel + + \ No newline at end of file diff --git a/Labyrinth3/IDE/Controls/ColorPanel.cs b/Labyrinth3/IDE/Controls/ColorPanel.cs new file mode 100644 index 0000000..8d8b825 --- /dev/null +++ b/Labyrinth3/IDE/Controls/ColorPanel.cs @@ -0,0 +1,164 @@ +// Decompiled with JetBrains decompiler +// Type: Labyrinth.Controls.ColorPanel +// Assembly: Labyrinth, Version=3.6.1928.15690, Culture=neutral, PublicKeyToken=null +// MVID: 1462002E-0BD1-49D2-9B56-C22E66C903E7 +// Assembly location: C:\Dropbox\Workspace\Programs\Labyrinth\Labyrinth.exe + +using System; +using System.ComponentModel; +using System.Drawing; +using System.Windows.Forms; + +namespace Labyrinth.Controls +{ + public class ColorPanel : Panel + { + private Container components = (Container)null; + private Color fColor1 = Color.Black; + private Color fColor2 = Color.White; + + public ColorPanel() + { + this.InitializeComponent(); + this.SetStyle(ControlStyles.ResizeRedraw, true); + } + + protected override void Dispose(bool disposing) + { + if (disposing && this.components != null) + this.components.Dispose(); + base.Dispose(disposing); + } + + private void InitializeComponent() + { + this.components = new Container(); + } + + public Color Color1 + { + get + { + return this.fColor1; + } + set + { + this.fColor1 = value; + this.Refresh(); + } + } + + public Color Color2 + { + get + { + return this.fColor2; + } + set + { + this.fColor2 = value; + this.Refresh(); + } + } + + public event EventHandler ForeColorClick; + + protected void OnForeColorClick(EventArgs e) + { + try + { + if (this.ForeColorClick == null) + return; + this.ForeColorClick((object)this, e); + } + catch (Exception ex) + { + LabyrinthData.Log((object)ex); + } + } + + public event EventHandler BackColorClick; + + protected void OnBackColorClick(EventArgs e) + { + try + { + if (this.BackColorClick == null) + return; + this.BackColorClick((object)this, e); + } + catch (Exception ex) + { + LabyrinthData.Log((object)ex); + } + } + + protected override void OnClick(EventArgs e) + { + base.OnClick(e); + Point client = this.PointToClient(Cursor.Position); + if (this.get_fore_rect().Contains(client)) + { + this.OnForeColorClick(new EventArgs()); + } + else + { + if (!this.get_back_rect().Contains(client)) + return; + this.OnBackColorClick(new EventArgs()); + } + } + + protected override void OnPaint(PaintEventArgs e) + { + try + { + base.OnPaint(e); + Rectangle backRect = this.get_back_rect(); + e.Graphics.FillRectangle((Brush)new SolidBrush(this.fColor2), backRect); + e.Graphics.DrawRectangle(SystemPens.ControlText, backRect); + Rectangle foreRect = this.get_fore_rect(); + e.Graphics.FillRectangle((Brush)new SolidBrush(this.fColor1), foreRect); + e.Graphics.DrawRectangle(SystemPens.ControlText, foreRect); + } + catch (Exception ex) + { + LabyrinthData.Log((object)ex); + } + } + + private Rectangle get_fore_rect() + { + Rectangle clientRectangle1 = this.ClientRectangle; + int x1 = clientRectangle1.X; + clientRectangle1 = this.ClientRectangle; + int num1 = clientRectangle1.Width / 7; + int x2 = x1 + num1; + Rectangle clientRectangle2 = this.ClientRectangle; + int y1 = clientRectangle2.Y; + clientRectangle2 = this.ClientRectangle; + int num2 = clientRectangle2.Height / 7; + int y2 = y1 + num2; + int width = this.ClientRectangle.Width * 3 / 7; + int height = this.ClientRectangle.Height * 3 / 7; + return new Rectangle(x2, y2, width, height); + } + + private Rectangle get_back_rect() + { + Rectangle clientRectangle1 = this.ClientRectangle; + int x1 = clientRectangle1.X; + clientRectangle1 = this.ClientRectangle; + int num1 = clientRectangle1.Width * 3 / 7; + int x2 = x1 + num1; + Rectangle clientRectangle2 = this.ClientRectangle; + int y1 = clientRectangle2.Y; + clientRectangle2 = this.ClientRectangle; + int num2 = clientRectangle2.Height * 3 / 7; + int y2 = y1 + num2; + int width = this.ClientRectangle.Width * 3 / 7; + int height = this.ClientRectangle.Height * 3 / 7; + return new Rectangle(x2, y2, width, height); + } + } +} \ No newline at end of file diff --git a/Labyrinth3/IDE/Controls/ColorPanel.resx b/Labyrinth3/IDE/Controls/ColorPanel.resx new file mode 100644 index 0000000..d58980a --- /dev/null +++ b/Labyrinth3/IDE/Controls/ColorPanel.resx @@ -0,0 +1,120 @@ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + text/microsoft-resx + + + 2.0 + + + System.Resources.ResXResourceReader, System.Windows.Forms, Version=4.0.0.0, Culture=neutral, PublicKeyToken=b77a5c561934e089 + + + System.Resources.ResXResourceWriter, System.Windows.Forms, Version=4.0.0.0, Culture=neutral, PublicKeyToken=b77a5c561934e089 + + \ No newline at end of file diff --git a/Labyrinth3/IDE/Controls/ElementTypeBox.cs b/Labyrinth3/IDE/Controls/ElementTypeBox.cs new file mode 100644 index 0000000..fa4f90a --- /dev/null +++ b/Labyrinth3/IDE/Controls/ElementTypeBox.cs @@ -0,0 +1,82 @@ +// Decompiled with JetBrains decompiler +// Type: Labyrinth.Controls.ElementTypeBox +// Assembly: Labyrinth, Version=3.6.1928.15690, Culture=neutral, PublicKeyToken=null +// MVID: 1462002E-0BD1-49D2-9B56-C22E66C903E7 +// Assembly location: C:\Dropbox\Workspace\Programs\Labyrinth\Labyrinth.exe + +using Labyrinth.Plot; +using System; +using System.ComponentModel; +using System.Drawing; +using System.Windows.Forms; + +namespace Labyrinth.Controls +{ + public class ElementTypeBox : ComboBox + { + private Container components = (Container)null; + private StringFormat fFormat = new StringFormat(); + + public ElementTypeBox() + { + this.InitializeComponent(); + this.fFormat.Alignment = StringAlignment.Near; + this.fFormat.LineAlignment = StringAlignment.Center; + this.fFormat.Trimming = StringTrimming.EllipsisWord; + foreach (ElementType elementType in Enum.GetValues(typeof(ElementType))) + this.Items.Add((object)elementType); + this.SelectedIndex = 0; + } + + protected override void Dispose(bool disposing) + { + if (disposing && this.components != null) + this.components.Dispose(); + base.Dispose(disposing); + } + + private void InitializeComponent() + { + this.DrawMode = DrawMode.OwnerDrawVariable; + this.DropDownStyle = ComboBoxStyle.DropDownList; + } + + public ElementType SelectedElementType + { + get + { + return (ElementType)this.SelectedItem; + } + set + { + this.SelectedItem = (object)value; + } + } + + protected override void OnMeasureItem(MeasureItemEventArgs e) + { + base.OnMeasureItem(e); + Image image = LabyrinthData.ElementImages.Images[LabyrinthData.GetImageIndex((ElementType)this.Items[e.Index])]; + e.ItemHeight = image.Height; + } + + protected override void OnDrawItem(DrawItemEventArgs e) + { + base.OnDrawItem(e); + if (e.Index == -1) + return; + e.DrawBackground(); + if ((e.State & DrawItemState.Focus) == DrawItemState.Focus) + e.DrawFocusRectangle(); + ElementType type = (ElementType)this.Items[e.Index]; + string s = type.ToString(); + Image image = LabyrinthData.ElementImages.Images[LabyrinthData.GetImageIndex(type)]; + e.Graphics.DrawImage(image, e.Bounds.Location); + Rectangle bounds = e.Bounds; + bounds.X += LabyrinthData.ElementImages.ImageSize.Width; + bounds.Width -= LabyrinthData.ElementImages.ImageSize.Width; + SolidBrush solidBrush = new SolidBrush(e.ForeColor); + e.Graphics.DrawString(s, e.Font, (Brush)solidBrush, (RectangleF)bounds, this.fFormat); + } + } +} \ No newline at end of file diff --git a/Labyrinth3/IDE/Controls/ElementTypeBox.resx b/Labyrinth3/IDE/Controls/ElementTypeBox.resx new file mode 100644 index 0000000..eafc96f --- /dev/null +++ b/Labyrinth3/IDE/Controls/ElementTypeBox.resx @@ -0,0 +1,127 @@ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + text/microsoft-resx + + + 2.0 + + + System.Resources.ResXResourceReader, System.Windows.Forms, Version=4.0.0.0, Culture=neutral, PublicKeyToken=b77a5c561934e089 + + + System.Resources.ResXResourceWriter, System.Windows.Forms, Version=4.0.0.0, Culture=neutral, PublicKeyToken=b77a5c561934e089 + + + + False + + + ElementTypeBox + + \ No newline at end of file diff --git a/Labyrinth3/IDE/Controls/RTFPanel.cs b/Labyrinth3/IDE/Controls/RTFPanel.cs new file mode 100644 index 0000000..e7f8031 --- /dev/null +++ b/Labyrinth3/IDE/Controls/RTFPanel.cs @@ -0,0 +1,544 @@ +// Decompiled with JetBrains decompiler +// Type: Labyrinth.Controls.RTFPanel +// Assembly: Labyrinth, Version=3.6.1928.15690, Culture=neutral, PublicKeyToken=null +// MVID: 1462002E-0BD1-49D2-9B56-C22E66C903E7 +// Assembly location: C:\Dropbox\Workspace\Programs\Labyrinth\Labyrinth.exe + +using Labyrinth3; +using System; +using System.Collections.Generic; +using System.ComponentModel; +using System.Diagnostics; +using System.Drawing; +using System.Drawing.Printing; +using System.IO; +using System.Resources; +using System.Windows.Forms; + +namespace Labyrinth.Controls +{ + public class RTFPanel : UserControl + { + private ImageList ToolbarImages; + private ToolBar Toolbar; + private ToolBarButton FontBtn; + private ToolBarButton Sep1; + private ToolBarButton BoldBtn; + private ToolBarButton ItalicBtn; + private ToolBarButton UnderlineBtn; + private ToolBarButton StrikeBtn; + private ToolBarButton Sep2; + private ToolBarButton BulletBtn; + private ToolBarButton Sep3; + private ToolBarButton LeftBtn; + private ToolBarButton CentreBtn; + private ToolBarButton RightBtn; + private RichTextBox ContentBox; + private ToolBarButton Sep4; + private ToolBarButton PrintBtn; + private ToolBarButton PrintPreviewBtn; + private ToolBarButton Sep5; + private ToolBarButton IndentBtn; + private ToolBarButton UnindentBtn; + private ContextMenu RightClickMenu; + private MenuItem RightClickCut; + private MenuItem RightClickCopy; + private MenuItem RightClickPaste; + private MenuItem Sep6; + private MenuItem RightClickSelectAll; + private ToolBarButton CutBtn; + private ToolBarButton CopyBtn; + private ToolBarButton PasteBtn; + private ToolBarButton Sep7; + private IContainer components; + + public RTFPanel() + { + this.InitializeComponent(); + this.ContentBox.DragOver += new DragEventHandler(this.ContentBox_DragOver); + this.ContentBox.DragDrop += new DragEventHandler(this.ContentBox_DragDrop); + } + + protected override void Dispose(bool disposing) + { + if (disposing && this.components != null) + this.components.Dispose(); + base.Dispose(disposing); + } + + private void InitializeComponent() + { + this.components = (IContainer)new Container(); + ResourceManager resourceManager = new ResourceManager(typeof(RTFPanel)); + this.ToolbarImages = new ImageList(this.components); + this.Toolbar = new ToolBar(); + this.CutBtn = new ToolBarButton(); + this.CopyBtn = new ToolBarButton(); + this.PasteBtn = new ToolBarButton(); + this.Sep1 = new ToolBarButton(); + this.FontBtn = new ToolBarButton(); + this.Sep2 = new ToolBarButton(); + this.BoldBtn = new ToolBarButton(); + this.ItalicBtn = new ToolBarButton(); + this.UnderlineBtn = new ToolBarButton(); + this.StrikeBtn = new ToolBarButton(); + this.Sep3 = new ToolBarButton(); + this.BulletBtn = new ToolBarButton(); + this.Sep4 = new ToolBarButton(); + this.LeftBtn = new ToolBarButton(); + this.CentreBtn = new ToolBarButton(); + this.RightBtn = new ToolBarButton(); + this.Sep5 = new ToolBarButton(); + this.UnindentBtn = new ToolBarButton(); + this.IndentBtn = new ToolBarButton(); + this.Sep7 = new ToolBarButton(); + this.PrintBtn = new ToolBarButton(); + this.PrintPreviewBtn = new ToolBarButton(); + this.ContentBox = new RichTextBox(); + this.RightClickMenu = new ContextMenu(); + this.RightClickCut = new MenuItem(); + this.RightClickCopy = new MenuItem(); + this.RightClickPaste = new MenuItem(); + this.Sep6 = new MenuItem(); + this.RightClickSelectAll = new MenuItem(); + this.SuspendLayout(); + this.ToolbarImages.ColorDepth = ColorDepth.Depth8Bit; + this.ToolbarImages.ImageSize = new Size(16, 16); + this.ToolbarImages.ImageStream = (ImageListStreamer)resourceManager.GetObject("ToolbarImages.ImageStream"); + this.ToolbarImages.TransparentColor = Color.Magenta; + this.Toolbar.Appearance = ToolBarAppearance.Flat; + var buttons = new List() { + this.CutBtn, + this.CopyBtn, + this.PasteBtn, + this.Sep1, + this.FontBtn, + this.Sep2, + this.BoldBtn, + this.ItalicBtn, + this.UnderlineBtn, + this.StrikeBtn, + this.Sep3, + this.BulletBtn, + this.Sep4, + this.LeftBtn, + this.CentreBtn, + this.RightBtn, + this.Sep5, + this.UnindentBtn, + this.IndentBtn, + this.Sep7, + this.PrintBtn, + this.PrintPreviewBtn + }; + + if (Program.ZEKKA_WORKAROUNDS) + { + buttons.RemoveRange(3, 2); // no font button + } + this.Toolbar.Buttons.AddRange(buttons.ToArray()); + this.Toolbar.DropDownArrows = true; + this.Toolbar.ImageList = this.ToolbarImages; + this.Toolbar.Name = "Toolbar"; + this.Toolbar.ShowToolTips = true; + this.Toolbar.Size = new Size(472, 25); + this.Toolbar.TabIndex = 6; + this.Toolbar.ButtonClick += new ToolBarButtonClickEventHandler(this.Toolbar_ButtonClick); + this.CutBtn.ImageIndex = 13; + this.CutBtn.ToolTipText = "Cut"; + this.CopyBtn.ImageIndex = 14; + this.CopyBtn.ToolTipText = "Copy"; + this.PasteBtn.ImageIndex = 15; + this.PasteBtn.ToolTipText = "Paste"; + this.Sep1.Style = ToolBarButtonStyle.Separator; + this.FontBtn.ImageIndex = 8; + this.FontBtn.ToolTipText = "Font"; + this.Sep2.Style = ToolBarButtonStyle.Separator; + this.BoldBtn.ImageIndex = 0; + this.BoldBtn.ToolTipText = "Bold"; + this.ItalicBtn.ImageIndex = 1; + this.ItalicBtn.ToolTipText = "Italic"; + this.UnderlineBtn.ImageIndex = 2; + this.UnderlineBtn.ToolTipText = "Underline"; + this.StrikeBtn.ImageIndex = 3; + this.StrikeBtn.ToolTipText = "Strikeout"; + this.Sep3.Style = ToolBarButtonStyle.Separator; + this.BulletBtn.ImageIndex = 4; + this.BulletBtn.ToolTipText = "Bulleted list"; + this.Sep4.Style = ToolBarButtonStyle.Separator; + this.LeftBtn.ImageIndex = 5; + this.LeftBtn.ToolTipText = "Left align"; + this.CentreBtn.ImageIndex = 6; + this.CentreBtn.ToolTipText = "Center align"; + this.RightBtn.ImageIndex = 7; + this.RightBtn.ToolTipText = "Right align"; + this.Sep5.Style = ToolBarButtonStyle.Separator; + this.UnindentBtn.ImageIndex = 9; + this.UnindentBtn.ToolTipText = "Unindent"; + this.IndentBtn.ImageIndex = 10; + this.IndentBtn.ToolTipText = "Indent"; + this.Sep7.Style = ToolBarButtonStyle.Separator; + this.PrintBtn.ImageIndex = 11; + this.PrintBtn.ToolTipText = "Print"; + this.PrintPreviewBtn.ImageIndex = 12; + this.PrintPreviewBtn.ToolTipText = "Print Preview"; + this.ContentBox.AllowDrop = true; + this.ContentBox.ContextMenu = this.RightClickMenu; + this.ContentBox.Dock = DockStyle.Fill; + this.ContentBox.Location = new Point(0, 25); + this.ContentBox.Name = "ContentBox"; + this.ContentBox.Size = new Size(472, 159); + this.ContentBox.TabIndex = 8; + this.ContentBox.Text = ""; + this.ContentBox.TextChanged += new EventHandler(this.ContentBox_TextChanged); + this.ContentBox.LinkClicked += new LinkClickedEventHandler(this.ContentBox_LinkClicked); + this.RightClickMenu.MenuItems.AddRange(new MenuItem[5] + { + this.RightClickCut, + this.RightClickCopy, + this.RightClickPaste, + this.Sep6, + this.RightClickSelectAll + }); + this.RightClickCut.Index = 0; + this.RightClickCut.Shortcut = Shortcut.CtrlX; + this.RightClickCut.Text = "Cut"; + this.RightClickCut.Click += new EventHandler(this.RightClickCut_Click); + this.RightClickCopy.Index = 1; + this.RightClickCopy.Shortcut = Shortcut.CtrlC; + this.RightClickCopy.Text = "Copy"; + this.RightClickCopy.Click += new EventHandler(this.RightClickCopy_Click); + this.RightClickPaste.Index = 2; + this.RightClickPaste.Shortcut = Shortcut.CtrlV; + this.RightClickPaste.Text = "Paste"; + this.RightClickPaste.Click += new EventHandler(this.RightClickPaste_Click); + this.Sep6.Index = 3; + this.Sep6.Text = "-"; + this.RightClickSelectAll.Index = 4; + this.RightClickSelectAll.Shortcut = Shortcut.CtrlA; + this.RightClickSelectAll.Text = "Select All"; + this.RightClickSelectAll.Click += new EventHandler(this.RightClickSelectAll_Click); + this.Controls.AddRange(new Control[2] + { + (Control) this.ContentBox, + (Control) this.Toolbar + }); + this.Name = nameof(RTFPanel); + this.Size = new Size(472, 184); + + this.DoubleBuffered = true; + + this.ResumeLayout(false); + } + + public string RTF + { + get + { + return this.ContentBox.Rtf; + } + set + { + this.ContentBox.Rtf = value; + } + } + + public override string Text + { + get + { + return this.ContentBox.Text.Replace("\n", Environment.NewLine); + } + set + { + this.ContentBox.Text = value; + } + } + + public void UpdateUI() + { + this.RightClickCut.Enabled = this.ContentBox.SelectedText != ""; + this.RightClickCopy.Enabled = this.ContentBox.SelectedText != ""; + this.RightClickPaste.Enabled = true; + this.RightClickSelectAll.Enabled = true; + this.CutBtn.Enabled = this.RightClickCut.Enabled; + this.CopyBtn.Enabled = this.RightClickCopy.Enabled; + this.PasteBtn.Enabled = this.RightClickPaste.Enabled; + if (this.ContentBox.SelectionFont != null) + { + this.BoldBtn.Pushed = this.ContentBox.SelectionFont.Bold; + this.ItalicBtn.Pushed = this.ContentBox.SelectionFont.Italic; + this.UnderlineBtn.Pushed = this.ContentBox.SelectionFont.Underline; + this.StrikeBtn.Pushed = this.ContentBox.SelectionFont.Strikeout; + } + this.BulletBtn.Pushed = this.ContentBox.SelectionBullet; + this.LeftBtn.Pushed = this.ContentBox.SelectionAlignment == HorizontalAlignment.Left; + this.CentreBtn.Pushed = this.ContentBox.SelectionAlignment == HorizontalAlignment.Center; + this.RightBtn.Pushed = this.ContentBox.SelectionAlignment == HorizontalAlignment.Right; + this.UnindentBtn.Enabled = this.ContentBox.SelectionIndent > 0; + this.IndentBtn.Enabled = true; + } + + public event EventHandler ContentModified; + + protected void OnContentModified(EventArgs e) + { + try + { + if (this.ContentModified == null) + return; + this.ContentModified((object)this, e); + } + catch (Exception ex) + { + LabyrinthData.Log((object)ex); + } + } + + private void Toolbar_ButtonClick(object sender, ToolBarButtonClickEventArgs e) + { + try + { + if (e.Button == this.CutBtn) + this.RightClickCut_Click(sender, (EventArgs)e); + else if (e.Button == this.CopyBtn) + this.RightClickCopy_Click(sender, (EventArgs)e); + else if (e.Button == this.PasteBtn) + this.RightClickPaste_Click(sender, (EventArgs)e); + else if (e.Button == this.FontBtn) + { + FontDialog fontDialog = new FontDialog(); + fontDialog.ShowColor = true; + fontDialog.Color = this.ContentBox.SelectionColor; + fontDialog.Font = this.ContentBox.SelectionFont; + if (fontDialog.ShowDialog() != DialogResult.OK) + return; + this.ContentBox.SelectionColor = fontDialog.Color; + this.ContentBox.SelectionFont = fontDialog.Font; + } + else if (e.Button == this.BoldBtn) + { + Font selectionFont = this.ContentBox.SelectionFont; + FontStyle newStyle = selectionFont.Bold ? FontStyle.Regular : FontStyle.Bold; + this.ContentBox.SelectionFont = new Font(selectionFont, newStyle); + } + else if (e.Button == this.ItalicBtn) + { + Font selectionFont = this.ContentBox.SelectionFont; + FontStyle newStyle = selectionFont.Italic ? FontStyle.Regular : FontStyle.Italic; + this.ContentBox.SelectionFont = new Font(selectionFont, newStyle); + } + else if (e.Button == this.UnderlineBtn) + { + Font selectionFont = this.ContentBox.SelectionFont; + FontStyle newStyle = selectionFont.Underline ? FontStyle.Regular : FontStyle.Underline; + this.ContentBox.SelectionFont = new Font(selectionFont, newStyle); + } + else if (e.Button == this.StrikeBtn) + { + Font selectionFont = this.ContentBox.SelectionFont; + FontStyle newStyle = selectionFont.Strikeout ? FontStyle.Regular : FontStyle.Strikeout; + this.ContentBox.SelectionFont = new Font(selectionFont, newStyle); + } + else if (e.Button == this.BulletBtn) + this.ContentBox.SelectionBullet = !this.ContentBox.SelectionBullet; + else if (e.Button == this.LeftBtn) + this.ContentBox.SelectionAlignment = HorizontalAlignment.Left; + else if (e.Button == this.CentreBtn) + this.ContentBox.SelectionAlignment = HorizontalAlignment.Center; + else if (e.Button == this.RightBtn) + this.ContentBox.SelectionAlignment = HorizontalAlignment.Right; + else if (e.Button == this.UnindentBtn) + { + this.ContentBox.SelectionIndent -= 10; + if (this.ContentBox.SelectionIndent >= 0) + return; + this.ContentBox.SelectionIndent = 0; + } + else if (e.Button == this.IndentBtn) + this.ContentBox.SelectionIndent += 10; + else if (e.Button == this.PrintBtn) + { + PrintDialog printDialog = new PrintDialog(); + printDialog.Document = this.create_print_doc(); + if (printDialog.ShowDialog() != DialogResult.OK) + return; + for (int index = 0; index != (int)printDialog.PrinterSettings.Copies; ++index) + printDialog.Document.Print(); + } + else + { + if (e.Button != this.PrintPreviewBtn) + return; + int num = (int)new PrintPreviewDialog() + { + Document = this.create_print_doc() + }.ShowDialog(); + } + } + catch (Exception ex) + { + LabyrinthData.Log((object)ex); + } + } + + private PrintDocument create_print_doc() + { + PrintDocument printDocument = new PrintDocument(); + printDocument.DocumentName = LabyrinthData.Project.Name; + printDocument.PrintController = (PrintController)new StandardPrintController(); + printDocument.DefaultPageSettings = LabyrinthData.PageSettings; + printDocument.PrinterSettings = LabyrinthData.PrinterSettings; + printDocument.PrintPage += new PrintPageEventHandler(this.PrintPage); + return printDocument; + } + + private void PrintPage(object sender, PrintPageEventArgs e) + { + StringFormat format = new StringFormat(); + format.Alignment = StringAlignment.Near; + format.LineAlignment = StringAlignment.Near; + format.Trimming = StringTrimming.EllipsisCharacter; + Font font = new Font(this.Font, this.Font.Style); + float height = e.Graphics.MeasureString(this.ContentBox.Text, font, e.MarginBounds.Width).Height; + if ((double)height > (double)e.MarginBounds.Height) + { + float emSize = font.SizeInPoints * (float)e.MarginBounds.Height / height; + font = new Font(font.FontFamily, emSize); + } + e.Graphics.DrawString(this.ContentBox.Text, font, SystemBrushes.WindowText, (RectangleF)e.MarginBounds, format); + } + + bool zekka_hack_ongoing; + RichTextBox zekka_hack; + private void ContentBox_TextChanged(object sender, EventArgs e) + { + this.OnContentModified(e); + + // ZEKKA HACKING: Without this, copypasting randomly changes the font size + // Sorry, this breaks the fonts menu so I disable that + if (Program.ZEKKA_WORKAROUNDS && !zekka_hack_ongoing) + { + try + { + this.SuspendLayout(); + this.ContentBox.SuspendLayout(); + zekka_hack_ongoing = true; + + var selectionStart = this.ContentBox.SelectionStart; + var selectionLen = this.ContentBox.SelectionLength; + if (zekka_hack == null) + { + zekka_hack = new RichTextBox(); + zekka_hack.Font = ContentBox.Font; + } + zekka_hack.Rtf = ContentBox.Rtf; + zekka_hack.SelectAll(); + zekka_hack.SelectionFont = ContentBox.Font; + ContentBox.Rtf = zekka_hack.Rtf; + this.ContentBox.Select(selectionStart, selectionLen); + } + finally + { + this.ResumeLayout(); + this.ContentBox.ResumeLayout(); + zekka_hack_ongoing = false; + } + } + } + + private void ContentBox_LinkClicked(object sender, LinkClickedEventArgs e) + { + try + { + Process.Start(e.LinkText); + } + catch (Exception ex) + { + LabyrinthData.Log((object)ex); + } + } + + private void ContentBox_DragOver(object sender, DragEventArgs e) + { + e.Effect = DragDropEffects.Copy; + } + + private void ContentBox_DragDrop(object sender, DragEventArgs e) + { + this.import_data(e.Data); + } + + private void RightClickCut_Click(object sender, EventArgs e) + { + try + { + Clipboard.SetDataObject((object)new DataObject(DataFormats.Rtf, (object)this.ContentBox.SelectedRtf), true); + this.ContentBox.SelectedText = ""; + } + catch (Exception ex) + { + LabyrinthData.Log((object)ex); + } + } + + private void RightClickCopy_Click(object sender, EventArgs e) + { + try + { + Clipboard.SetDataObject((object)new DataObject(DataFormats.Rtf, (object)this.ContentBox.SelectedRtf), true); + } + catch (Exception ex) + { + LabyrinthData.Log((object)ex); + } + } + + private void RightClickPaste_Click(object sender, EventArgs e) + { + try + { + this.import_data(Clipboard.GetDataObject()); + } + catch (Exception ex) + { + LabyrinthData.Log((object)ex); + } + } + + private void RightClickSelectAll_Click(object sender, EventArgs e) + { + try + { + this.ContentBox.SelectAll(); + } + catch (Exception ex) + { + LabyrinthData.Log((object)ex); + } + } + + private void import_data(IDataObject data) + { + if (data.GetDataPresent(DataFormats.Rtf)) + this.ContentBox.SelectedRtf = data.GetData(DataFormats.Rtf) as string; + else if (data.GetDataPresent(DataFormats.FileDrop)) + { + string[] data1 = data.GetData(DataFormats.FileDrop) as string[]; + string str = ""; + foreach (string path in data1) + { + StreamReader streamReader = new StreamReader(path); + str += streamReader.ReadToEnd(); + } + this.ContentBox.SelectedText = str; + } + else + { + if (!data.GetDataPresent(typeof(string))) + return; + this.ContentBox.SelectedText = data.GetData(typeof(string)) as string; + } + } + } +} \ No newline at end of file diff --git a/Labyrinth3/IDE/Controls/RTFPanel.resx b/Labyrinth3/IDE/Controls/RTFPanel.resx new file mode 100644 index 0000000..bb7cdc2 --- /dev/null +++ b/Labyrinth3/IDE/Controls/RTFPanel.resx @@ -0,0 +1,195 @@ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + text/microsoft-resx + + + 2.0 + + + System.Resources.ResXResourceReader, System.Windows.Forms, Version=4.0.0.0, Culture=neutral, PublicKeyToken=b77a5c561934e089 + + + System.Resources.ResXResourceWriter, System.Windows.Forms, Version=4.0.0.0, Culture=neutral, PublicKeyToken=b77a5c561934e089 + + + RTFPanel + + + + 17, 17 + + + + 55 + + + 143, 17 + + + + AAEAAAD/////AQAAAAAAAAAMAgAAAFdTeXN0ZW0uV2luZG93cy5Gb3JtcywgVmVyc2lvbj00LjAuMC4w + LCBDdWx0dXJlPW5ldXRyYWwsIFB1YmxpY0tleVRva2VuPWI3N2E1YzU2MTkzNGUwODkFAQAAACZTeXN0 + ZW0uV2luZG93cy5Gb3Jtcy5JbWFnZUxpc3RTdHJlYW1lcgEAAAAERGF0YQcCAgAAAAkDAAAADwMAAACE + DAAAAk1TRnQBSQFMAgEBEAEAARMBAAEIAQABEAEAARABAAT/AQkBEAj/AUIBTQE2AQQGAAE2AQQCAAEo + AwABQAMAAVADAAEBAQABCAYAARQYAAGAAgABgAMAAoABAAGAAwABgAEAAYABAAKAAgADwAEAAcAB3AHA + AQAB8AHKAaYBAAEzBQABMwEAATMBAAEzAQACMwIAAxYBAAMcAQADIgEAAykBAANVAQADTQEAA0IBAAM5 + AQABgAF8Af8BAAJQAf8BAAGTAQAB1gEAAf8B7AHMAQABxgHWAe8BAAHWAucBAAGQAakBrQIAAf8BMwMA + AWYDAAGZAwABzAIAATMDAAIzAgABMwFmAgABMwGZAgABMwHMAgABMwH/AgABZgMAAWYBMwIAAmYCAAFm + AZkCAAFmAcwCAAFmAf8CAAGZAwABmQEzAgABmQFmAgACmQIAAZkBzAIAAZkB/wIAAcwDAAHMATMCAAHM + AWYCAAHMAZkCAALMAgABzAH/AgAB/wFmAgAB/wGZAgAB/wHMAQABMwH/AgAB/wEAATMBAAEzAQABZgEA + ATMBAAGZAQABMwEAAcwBAAEzAQAB/wEAAf8BMwIAAzMBAAIzAWYBAAIzAZkBAAIzAcwBAAIzAf8BAAEz + AWYCAAEzAWYBMwEAATMCZgEAATMBZgGZAQABMwFmAcwBAAEzAWYB/wEAATMBmQIAATMBmQEzAQABMwGZ + AWYBAAEzApkBAAEzAZkBzAEAATMBmQH/AQABMwHMAgABMwHMATMBAAEzAcwBZgEAATMBzAGZAQABMwLM + AQABMwHMAf8BAAEzAf8BMwEAATMB/wFmAQABMwH/AZkBAAEzAf8BzAEAATMC/wEAAWYDAAFmAQABMwEA + AWYBAAFmAQABZgEAAZkBAAFmAQABzAEAAWYBAAH/AQABZgEzAgABZgIzAQABZgEzAWYBAAFmATMBmQEA + AWYBMwHMAQABZgEzAf8BAAJmAgACZgEzAQADZgEAAmYBmQEAAmYBzAEAAWYBmQIAAWYBmQEzAQABZgGZ + AWYBAAFmApkBAAFmAZkBzAEAAWYBmQH/AQABZgHMAgABZgHMATMBAAFmAcwBmQEAAWYCzAEAAWYBzAH/ + AQABZgH/AgABZgH/ATMBAAFmAf8BmQEAAWYB/wHMAQABzAEAAf8BAAH/AQABzAEAApkCAAGZATMBmQEA + AZkBAAGZAQABmQEAAcwBAAGZAwABmQIzAQABmQEAAWYBAAGZATMBzAEAAZkBAAH/AQABmQFmAgABmQFm + ATMBAAGZATMBZgEAAZkBZgGZAQABmQFmAcwBAAGZATMB/wEAApkBMwEAApkBZgEAA5kBAAKZAcwBAAKZ + Af8BAAGZAcwCAAGZAcwBMwEAAWYBzAFmAQABmQHMAZkBAAGZAswBAAGZAcwB/wEAAZkB/wIAAZkB/wEz + AQABmQHMAWYBAAGZAf8BmQEAAZkB/wHMAQABmQL/AQABzAMAAZkBAAEzAQABzAEAAWYBAAHMAQABmQEA + AcwBAAHMAQABmQEzAgABzAIzAQABzAEzAWYBAAHMATMBmQEAAcwBMwHMAQABzAEzAf8BAAHMAWYCAAHM + AWYBMwEAAZkCZgEAAcwBZgGZAQABzAFmAcwBAAGZAWYB/wEAAcwBmQIAAcwBmQEzAQABzAGZAWYBAAHM + ApkBAAHMAZkBzAEAAcwBmQH/AQACzAIAAswBMwEAAswBZgEAAswBmQEAA8wBAALMAf8BAAHMAf8CAAHM + Af8BMwEAAZkB/wFmAQABzAH/AZkBAAHMAf8BzAEAAcwC/wEAAcwBAAEzAQAB/wEAAWYBAAH/AQABmQEA + AcwBMwIAAf8CMwEAAf8BMwFmAQAB/wEzAZkBAAH/ATMBzAEAAf8BMwH/AQAB/wFmAgAB/wFmATMBAAHM + AmYBAAH/AWYBmQEAAf8BZgHMAQABzAFmAf8BAAH/AZkCAAH/AZkBMwEAAf8BmQFmAQAB/wKZAQAB/wGZ + AcwBAAH/AZkB/wEAAf8BzAIAAf8BzAEzAQAB/wHMAWYBAAH/AcwBmQEAAf8CzAEAAf8BzAH/AQAC/wEz + AQABzAH/AWYBAAL/AZkBAAL/AcwBAAJmAf8BAAFmAf8BZgEAAWYC/wEAAf8CZgEAAf8BZgH/AQAC/wFm + AQABIQEAAaUBAANfAQADdwEAA4YBAAOWAQADywEAA7IBAAPXAQAD3QEAA+MBAAPqAQAD8QEAA/gBAAHw + AfsB/wEAAaQCoAEAA4ADAAH/AgAB/wMAAv8BAAH/AwAB/wEAAf8BAAL/AgAD//8A/wD/AP8AWQACBCAA + CgQBAAr/CAABBAIAAQQCAAIECwAJBAcAAQQI/wEEAQAH/wsAAQQCAAEEAQABBAIAAQQKAAEEB/8BBAMA + AQMBAAEDAQABBAH/BgQB/wEEAQAG/wIAAgcIAAEEAgABBAEAAQQCAAEECgABBAH/BQAB/wEEAgABAwEA + AQMBAAEDAQQI/wEEAQAF/wIAAgcB/gkAAwQBAAEEAgABBAoAAQQH/wEEAwABAwEAAQMBAAEEAf8DBAH/ + BAQBAAX/AQAEBwsAAQQBAAMEBgAF/wEEAf8FAAH/AQQCAAEDAQABAwEAAQMBBAX/AQQB/wEEAgAF/wEA + AQcB/gIHCwABBAEAAQQIAAH/BAABBAf/AQQDAAEDAQABAwEAAQQF/wIEAwAF/wIAAv4BBxYABf8BBAH/ + AgAB/wQEAgABAwEAAQMBAAEDBwQEAAb/AgACBxYAAf8EAAEEBP8BBAH/AQQEAAEDAQABAwEAAQMBAAED + AQABAwEAAQMEAAf/GQAF/wEEBP8CBAQAAQMPAAr/FgAB/wIAAf8BAAYECAAGBwIAAQMEAAf/GQAE/wEA + Af8KAAEDAQABAwEAAfsCAAH7AgABAwUAB/8BAAEHFwAE/xEAAvsJAAf//wA7AAQEAwAGBCMACQcBAAEH + BgABBwEEBQABBwIEAQcvAAEHBgACBAQAAQcCBCQABgcD+wIHCAABBwEEBAACBAEHBQABBA8AAQQOAAYH + AwACBwEAAQcHAAcEBQACBA8AAgQZAAIHBgABBwEEAgACBAEHBAAFBAsABQQMAAoHAQABBwEAAQcHAAIE + AQACBAYAAgQPAAIEFwABBwEAAQcIAAEHAwQBBwcAAQQPAAEEEAAI/wEAAQcBAAEHCAADBCoAAf8FAAH/ + DAABBwEEAQcqAAj/DAABBCwAAf8FAAH/OQAI/8QAAwQ9AAMEPQADBL0AAwQ9AAMEPQADBL0AAwQ9AAME + PQADBP8A1AAB7A4AAewBAAHsLAAB7EIAAew9AAHsQgAB7D0AAexCAAHs/wAmAAFCAU0BPgcAAT4DAAEo + AwABQAMAAVADAAEBAQABAQUAAYABAhYAA/+BAAj/AQABDAHzA/8B/AIAAQgB7QGfAfwBAQGAAgABAQHt + AW8B/AEBAwABAwHtAW8B/AEBAwABAwHxAW8BAAEBAwABCwH9AR8BAAEBAQABAQEAAQsB/AF/AQABAQEA + AQMBAAEDAf4B/wEAAQEBAAEDAQABBwH8AX8BAAEDAQABAwEAAQ8B/QF/AQABBwEAAQMBAAEPAfkBPwEA + AQ8BAAEDAQABDwH7Ab8BAAH/AQABAwEAAR8B+wG/AQEB/wGAAQcBAAE/AfsBvwEDAf8B+AF/AQABfwj/ + Af4B/wH+Df8BwgF/AcIBfwHAAQcBwwGBBP8BgAEDAecBwwHCAQABwgIAAQEB8wHHBP8BAAEBAfMBxwHe + AQcB3gEHAQABAQH4AQ8BngEHAc4BBwIAAfkBjwEHAf8BBwH/AgAB/AGfAZ4BAAHOAQABgAEAAfwBHwHe + AQAB3gEAAcABAAH+AT8E/wHgAQEB/gE/AcIBAAHCAQAB4AEHAf8BfwT/AfABBwL/Af4B/wH+Af8B8AED + Bv8B+AEDEP8Bjwf/AYwBAQGAAQMBwAEPAfABAwGPCf8BgAE/AQABAwEAAQMI/wGPAf8BgAEDAcABDwHw + AQMBjAEBBv8BjwH/AYABPwEAAQMBAAEDCv8BgAEDAcABDwHwAQMBjwf/AYwBAQGAAT8BAAEDAQABAwGP + I/8B4AEPCv8B4AEfAeABfwH4AT8C/wHxAY8B+AH/AfEBHwEQATgB8QGPAfgB/wHzAZ8BugHXAfEBjwH8 + AX8B8wGfAgAB8AEfAfwBfwHzAZ8B1gE3AfEBjwH+AT8B8wGfAcYB1wHxAY8B/gE/AfMBnwHuAdYB8QGP + Af8BHwHzAZ8B7AE4AeABHwH+AQ8B4QEPGv8WAAs= + + + \ No newline at end of file diff --git a/Labyrinth3/IDE/Controls/StructureView.cs b/Labyrinth3/IDE/Controls/StructureView.cs new file mode 100644 index 0000000..a4a5348 --- /dev/null +++ b/Labyrinth3/IDE/Controls/StructureView.cs @@ -0,0 +1,508 @@ +// Decompiled with JetBrains decompiler +// Type: Labyrinth.Controls.StructureView +// Assembly: Labyrinth, Version=3.6.1928.15690, Culture=neutral, PublicKeyToken=null +// MVID: 1462002E-0BD1-49D2-9B56-C22E66C903E7 +// Assembly location: C:\Dropbox\Workspace\Programs\Labyrinth\Labyrinth.exe + +using Labyrinth.Collections; +using Labyrinth.Forms; +using Labyrinth.Plot; +using System; +using System.ComponentModel; +using System.Drawing; +using System.Windows.Forms; + +namespace Labyrinth.Controls +{ + public class StructureView : UserControl + { + private Container components = (Container)null; + private Structure fStructure = (Structure)null; + private Node fSelectedNode = (Node)null; + private bool fShowArrows = true; + private bool fShowText = true; + private bool fAddingLink = false; + private Node fFirstNode = (Node)null; + private StringFormat fStringFormat = (StringFormat)null; + private Font fSmallFont = (Font)null; + private Font fBoldFont = (Font)null; + private Node fHoverNode = (Node)null; + private const int fArrowSize = 8; + private const int fNodePadding = 3; + private const int fShadowSize = 3; + private Size fOffset; + + public StructureView() + { + this.InitializeComponent(); + this.SetStyle(ControlStyles.DoubleBuffer, true); + this.SetStyle(ControlStyles.UserPaint, true); + this.SetStyle(ControlStyles.AllPaintingInWmPaint, true); + this.SetStyle(ControlStyles.ResizeRedraw, true); + this.create_renderers(); + } + + protected override void Dispose(bool disposing) + { + if (disposing && this.components != null) + this.components.Dispose(); + base.Dispose(disposing); + } + + private void InitializeComponent() + { + this.AllowDrop = true; + this.BackColor = SystemColors.ControlDark; + this.Name = nameof(StructureView); + this.Size = new Size(312, 240); + } + + public Structure Structure + { + get + { + return this.fStructure; + } + set + { + if (this.fStructure == value) + return; + this.fStructure = value; + this.Refresh(); + } + } + + public Node SelectedNode + { + get + { + return this.fSelectedNode; + } + } + + public bool ShowArrows + { + get + { + return this.fShowArrows; + } + set + { + this.fShowArrows = value; + } + } + + public bool ShowText + { + get + { + return this.fShowText; + } + set + { + this.fShowText = value; + } + } + + public bool AddingLink + { + get + { + return this.fAddingLink; + } + set + { + if (this.fAddingLink == value) + return; + this.fAddingLink = value; + if (!this.fAddingLink) + this.fFirstNode = (Node)null; + this.Refresh(); + } + } + + public event EventHandler StructureModified; + + protected void OnStructureModified(EventArgs e) + { + try + { + if (this.StructureModified == null) + return; + this.StructureModified((object)this, e); + } + catch (Exception ex) + { + LabyrinthData.Log((object)ex); + } + } + + private void create_renderers() + { + this.fStringFormat = new StringFormat(); + this.fStringFormat.Alignment = StringAlignment.Center; + this.fStringFormat.LineAlignment = StringAlignment.Center; + this.fStringFormat.Trimming = StringTrimming.EllipsisCharacter; + this.fStringFormat.FormatFlags = this.fStringFormat.FormatFlags; + this.fSmallFont = new Font(this.Font.FontFamily, this.Font.Size * 0.8f); + this.fBoldFont = new Font(this.Font, this.Font.Style | FontStyle.Bold); + } + + protected override void OnPaint(PaintEventArgs e) + { + this.Render(e.Graphics, this.ClientRectangle); + } + + public void Render(Graphics g, Rectangle rect) + { + try + { + if (this.fStructure == null) + { + string s = "No structure to view."; + g.DrawString(s, this.Font, SystemBrushes.WindowText, (RectangleF)rect, this.fStringFormat); + } + else if (this.fStructure.Nodes.Count == 0) + { + string s = "There are no elements in this structure."; + g.DrawString(s, this.Font, SystemBrushes.WindowText, (RectangleF)rect, this.fStringFormat); + } + else + { + foreach (Node node in this.fStructure.Nodes) + this.draw_shadow(node, g, rect); + foreach (Labyrinth.Plot.Link link in this.fStructure.Links) + this.draw_link(link, g, rect); + if (this.fAddingLink && this.fFirstNode != null) + this.draw_new_link(g, rect); + foreach (Node node in this.fStructure.Nodes) + this.draw_node(node, g, rect); + } + } + catch (Exception ex) + { + LabyrinthData.Log((object)ex); + } + } + + private void draw_link(Labyrinth.Plot.Link l, Graphics g, Rectangle rect) + { + Node node1 = this.find_node(l.LHS); + Node node2 = this.find_node(l.RHS); + if (node1 == null || node2 == null) + return; + int num1 = (int)((double)node1.Position.X * (double)rect.Width) + rect.Left; + PointF position = node1.Position; + int num2 = (int)((double)position.Y * (double)rect.Height) + rect.Top; + PointF pointF1 = new PointF((float)num1, (float)num2); + position = node2.Position; + int num3 = (int)((double)position.X * (double)rect.Width) + rect.Left; + position = node2.Position; + int num4 = (int)((double)position.Y * (double)rect.Height) + rect.Top; + PointF pointF2 = new PointF((float)num3, (float)num4); + g.DrawLine(SystemPens.ControlText, pointF1, pointF2); + if (this.fShowText) + { + PointF pointF3 = this.get_intersection(pointF2, pointF1, this.rect_for_node(node1, rect)); + PointF pointF4 = this.get_intersection(pointF1, pointF2, this.rect_for_node(node2, rect)); + if (this.fShowArrows) + { + if (l.Direction == LinkDirection.Single || l.Direction == LinkDirection.Double) + pointF4 = this.find_arrow_point(pointF3, pointF4); + if (l.Direction == LinkDirection.Double) + pointF3 = this.find_arrow_point(pointF4, pointF3); + } + SizeF textSize = this.get_text_size(l.Description, this.fSmallFont); + RectangleF rectangleF = new RectangleF(new PointF((float)(((double)pointF3.X + (double)pointF4.X) / 2.0 - (double)textSize.Width / 2.0), (float)(((double)pointF3.Y + (double)pointF4.Y) / 2.0 - (double)textSize.Height / 2.0)), textSize); + g.FillRectangle(SystemBrushes.FromSystemColor(this.BackColor), rectangleF); + g.DrawString(l.Description, this.fSmallFont, SystemBrushes.WindowText, rectangleF, this.fStringFormat); + } + if (!this.fShowArrows) + return; + if (l.Direction == LinkDirection.Single || l.Direction == LinkDirection.Double) + this.draw_arrow(node1, node2, g, rect); + if (l.Direction != LinkDirection.Double) + return; + this.draw_arrow(node2, node1, g, rect); + } + + private void draw_arrow(Node lhs_item, Node rhs_item, Graphics g, Rectangle rect) + { + Rectangle rectangle = this.rect_for_node(lhs_item, rect); + Rectangle rect1 = this.rect_for_node(rhs_item, rect); + if (rectangle.IsEmpty || rect1.IsEmpty) + return; + PointF pointF1 = new PointF((float)(rectangle.X + rectangle.Width / 2), (float)(rectangle.Y + rectangle.Height / 2)); + PointF pt2 = new PointF((float)(rect1.X + rect1.Width / 2), (float)(rect1.Y + rect1.Height / 2)); + PointF intersection = this.get_intersection(pointF1, pt2, rect1); + if (rectangle.Contains((int)intersection.X, (int)intersection.Y)) + return; + PointF arrowPoint = this.find_arrow_point(pointF1, intersection); + if (rectangle.Contains((int)arrowPoint.X, (int)arrowPoint.Y)) + return; + double num1 = Math.Atan(((double)pt2.Y - (double)pointF1.Y) / ((double)pt2.X - (double)pointF1.X)); + double num2 = 4.0 * Math.Sin(num1); + double num3 = 4.0 * Math.Cos(num1); + PointF pointF2 = new PointF(arrowPoint.X + (float)num2, arrowPoint.Y - (float)num3); + PointF pointF3 = new PointF(arrowPoint.X - (float)num2, arrowPoint.Y + (float)num3); + if (rectangle.Contains((int)pointF2.X, (int)pointF2.Y) || rectangle.Contains((int)pointF3.X, (int)pointF3.Y)) + return; + PointF[] points = new PointF[3] + { + intersection, + pointF2, + pointF3 + }; + g.FillPolygon(SystemBrushes.ControlText, points); + } + + private PointF find_arrow_point(PointF lhs, PointF rhs) + { + double num1 = Math.Atan(((double)rhs.Y - (double)lhs.Y) / ((double)rhs.X - (double)lhs.X)); + double num2 = 8.0 * Math.Cos(num1) * ((double)lhs.X <= (double)rhs.X ? 1.0 : -1.0); + double num3 = 8.0 * Math.Sin(num1) * ((double)lhs.X <= (double)rhs.X ? 1.0 : -1.0); + return new PointF(rhs.X - (float)num2, rhs.Y - (float)num3); + } + + private void draw_node(Node n, Graphics g, Rectangle rect) + { + Rectangle rect1 = this.rect_for_node(n, rect); + Element element = this.get_element(n.ElementID); + if (element == null) + return; + Image elementIcon = this.get_element_icon(element); + if (elementIcon == null) + return; + g.FillRectangle(SystemBrushes.Window, rect1); + g.DrawRectangle(this.fHoverNode != n ? SystemPens.WindowText : SystemPens.Highlight, rect1); + int num1 = (rect1.Height - elementIcon.Height) / 2; + g.DrawImage(elementIcon, rect1.X + 3, rect1.Y + num1); + int num2 = 3 + elementIcon.Width + 3; + rect1.X += num2; + rect1.Width -= num2 + 3; + rect1.Y += 3; + rect1.Height -= 6; + Brush brush = SystemBrushes.WindowText; + if (this.fAddingLink && this.fHoverNode == n) + brush = SystemBrushes.Highlight; + Font font = this.fSelectedNode == n ? this.fBoldFont : this.Font; + g.DrawString(element.Name, font, brush, (RectangleF)rect1, this.fStringFormat); + } + + private void draw_shadow(Node n, Graphics g, Rectangle rect) + { + Rectangle rect1 = this.rect_for_node(n, rect); + rect1.X += 3; + rect1.Y += 3; + g.FillRectangle(SystemBrushes.ControlDarkDark, rect1); + } + + private void draw_new_link(Graphics g, Rectangle rect) + { + PointF pt1 = new PointF((float)((int)((double)this.fFirstNode.Position.X * (double)rect.Width) + rect.Left), (float)((int)((double)this.fFirstNode.Position.Y * (double)rect.Height) + rect.Top)); + if (this.fHoverNode != null) + { + PointF pt2 = new PointF((float)((int)((double)this.fHoverNode.Position.X * (double)rect.Width) + rect.Left), (float)((int)((double)this.fHoverNode.Position.Y * (double)rect.Height) + rect.Top)); + g.DrawLine(SystemPens.Highlight, pt1, pt2); + } + else + { + Point client = this.PointToClient(Cursor.Position); + g.DrawLine(SystemPens.HighlightText, pt1, (PointF)client); + } + } + + private Rectangle rect_for_node(Node n, Rectangle rect) + { + Element element = this.get_element(n.ElementID); + if (element == null) + return new Rectangle(0, 0, 0, 0); + Image elementIcon = this.get_element_icon(element); + if (elementIcon == null) + return new Rectangle(0, 0, 0, 0); + Font f = this.fSelectedNode == n ? this.fBoldFont : this.Font; + this.CreateGraphics(); + SizeF textSize = this.get_text_size(element.Name, f); + textSize.Width += 3f; + int width = 3 + elementIcon.Width + 3 + (int)textSize.Width + 3; + int height = 3 + Math.Max(elementIcon.Height, (int)textSize.Height) + 3; + PointF position = n.Position; + int num1 = (int)((double)position.X * (double)rect.Width) + rect.Left; + position = n.Position; + int num2 = (int)((double)position.Y * (double)rect.Height) + rect.Top; + return new Rectangle(num1 - width / 2, num2 - height / 2, width, height); + } + + private PointF get_intersection(PointF pt1, PointF pt2, Rectangle rect) + { + float f = (float)(((double)pt2.Y - (double)pt1.Y) / ((double)pt2.X - (double)pt1.X)); + double num1 = (double)pt2.Y - (double)pt2.X * (double)f; + double num2 = (double)rect.Height / (double)rect.Width; + double num3; + double num4; + if ((double)Math.Abs(f) > Math.Abs(num2)) + { + num3 = (double)pt1.Y < (double)pt2.Y ? (double)rect.Top : (double)(rect.Top + rect.Height); + num4 = (num3 - num1) / (double)f; + if (float.IsInfinity(f)) + num4 = (double)pt2.X; + } + else + { + num4 = (double)pt1.X < (double)pt2.X ? (double)rect.Left : (double)(rect.Left + rect.Width); + num3 = num4 * (double)f + num1; + } + return new PointF((float)num4, (float)num3); + } + + protected override void OnMouseDown(MouseEventArgs e) + { + base.OnMouseDown(e); + Point client = this.PointToClient(Cursor.Position); + this.fSelectedNode = this.node_at_point(client); + if (this.fSelectedNode != null) + { + this.fStructure.Nodes.Remove(this.fSelectedNode); + this.fStructure.Nodes.Add(this.fSelectedNode); + Rectangle rectangle = this.rect_for_node(this.fSelectedNode, this.ClientRectangle); + this.fOffset = new Size(client.X - rectangle.X - rectangle.Width / 2, client.Y - rectangle.Y - rectangle.Height / 2); + if (this.fAddingLink) + { + if (this.fFirstNode == null) + { + this.fFirstNode = this.fSelectedNode; + } + else + { + if (this.fSelectedNode != this.fFirstNode) + { + Labyrinth.Plot.Link l = new Labyrinth.Plot.Link(); + l.LHS = this.fFirstNode.ElementID; + l.RHS = this.fSelectedNode.ElementID; + l.Description = ""; + if (new LinkDlg(l).ShowDialog() == DialogResult.OK) + { + this.fStructure.Links.Add(l); + this.OnStructureModified(new EventArgs()); + } + } + this.fAddingLink = false; + this.fFirstNode = (Node)null; + } + } + } + else + { + this.fAddingLink = false; + this.fFirstNode = (Node)null; + } + this.Refresh(); + } + + protected override void OnMouseMove(MouseEventArgs e) + { + base.OnMouseMove(e); + Node node = this.node_at_point(new Point(e.X, e.Y)); + if (this.fHoverNode != node) + { + this.fHoverNode = node; + this.Refresh(); + } + if (this.fSelectedNode != null && e.Button == MouseButtons.Left) + { + Point point = new Point(e.X - this.fOffset.Width, e.Y - this.fOffset.Height); + float x = (float)point.X / (float)this.Width; + float y = (float)point.Y / (float)this.Height; + if ((double)x < 0.0) + x = 0.0f; + if ((double)y < 0.0) + y = 0.0f; + if ((double)x > 1.0) + x = 1f; + if ((double)y > 1.0) + y = 1f; + this.fSelectedNode.Position = new PointF(x, y); + this.Refresh(); + } + if (!this.fAddingLink || this.fFirstNode == null) + return; + this.Refresh(); + } + + protected override void OnMouseLeave(EventArgs e) + { + base.OnMouseLeave(e); + this.fHoverNode = (Node)null; + this.Refresh(); + } + + private Node node_at_point(Point p) + { + Node node1 = (Node)null; + foreach (Node node2 in this.fStructure.Nodes) + { + if (this.rect_for_node(node2, this.ClientRectangle).Contains(p)) + node1 = node2; + } + return node1; + } + + private Node find_node(Guid element_id) + { + foreach (Node node in this.fStructure.Nodes) + { + if (node.ElementID == element_id) + return node; + } + return (Node)null; + } + + private Element get_element(Guid id) + { + int index = LabyrinthData.Project.Elements.IndexOf(id); + if (index != -1) + return LabyrinthData.Project.Elements[index]; + return (Element)null; + } + + private Image get_element_icon(Element e) + { + if (this.TopLevelControl is MainForm) + return LabyrinthData.ElementImages.Images[LabyrinthData.GetImageIndex(e.Type)]; + return (Image)null; + } + + private SizeF get_text_size(string str, Font f) + { + Graphics graphics = this.CreateGraphics(); + SizeF sizeF1 = graphics.MeasureString(str, f); + int num1 = (int)Math.Ceiling((double)(sizeF1.Width / sizeF1.Height) / 5.0); + if (num1 == 1) + return sizeF1; + float num2 = sizeF1.Width / (float)num1; + foreach (string text in str.Split((char[])null)) + { + SizeF sizeF2 = graphics.MeasureString(text, f); + if ((double)sizeF2.Width > (double)num2) + num2 = sizeF2.Width; + } + float num3 = sizeF1.Height * (float)num1; + for (int width = (int)Math.Ceiling((double)num2); (double)width <= Math.Ceiling((double)sizeF1.Width); ++width) + { + SizeF sizeF2 = graphics.MeasureString(str, f, width, this.fStringFormat); + if ((double)sizeF2.Height <= (double)num3) + return sizeF2; + } + return sizeF1; + } + + public Image CreateImage() + { + Image image = (Image)new Bitmap(this.Width, this.Height); + Graphics graphics = Graphics.FromImage(image); + graphics.Clear(this.BackColor); + this.OnPaint(new PaintEventArgs(graphics, new Rectangle(0, 0, this.Width, this.Height))); + return image; + } + } +} \ No newline at end of file diff --git a/Labyrinth3/IDE/Controls/StructureView.resx b/Labyrinth3/IDE/Controls/StructureView.resx new file mode 100644 index 0000000..7c80b85 --- /dev/null +++ b/Labyrinth3/IDE/Controls/StructureView.resx @@ -0,0 +1,123 @@ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + text/microsoft-resx + + + 2.0 + + + System.Resources.ResXResourceReader, System.Windows.Forms, Version=4.0.0.0, Culture=neutral, PublicKeyToken=b77a5c561934e089 + + + System.Resources.ResXResourceWriter, System.Windows.Forms, Version=4.0.0.0, Culture=neutral, PublicKeyToken=b77a5c561934e089 + + + StructureView + + \ No newline at end of file diff --git a/Labyrinth3/IDE/Controls/TimelineGrid.cs b/Labyrinth3/IDE/Controls/TimelineGrid.cs new file mode 100644 index 0000000..51e7402 --- /dev/null +++ b/Labyrinth3/IDE/Controls/TimelineGrid.cs @@ -0,0 +1,333 @@ +// Decompiled with JetBrains decompiler +// Type: Labyrinth.Controls.TimelineGrid +// Assembly: Labyrinth, Version=3.6.1928.15690, Culture=neutral, PublicKeyToken=null +// MVID: 1462002E-0BD1-49D2-9B56-C22E66C903E7 +// Assembly location: C:\Dropbox\Workspace\Programs\Labyrinth\Labyrinth.exe + +using Labyrinth.Collections; +using Labyrinth.Plot; +using System; +using System.Collections; +using System.ComponentModel; +using System.Drawing; +using System.Windows.Forms; + +namespace Labyrinth.Controls +{ + public class TimelineGrid : UserControl + { + private Container components = (Container)null; + private Timeline fTimeline = (Timeline)null; + private SizeF fCellSize = new SizeF(0.0f, 0.0f); + private Guid fSelectedElementID = Guid.Empty; + private TimelinePoint fSelectedPoint = (TimelinePoint)null; + private Guid fHoverElementID = Guid.Empty; + private TimelinePoint fHoverPoint = (TimelinePoint)null; + private StringFormat fColHdrFormat = (StringFormat)null; + private StringFormat fRowHdrFormat = (StringFormat)null; + private StringFormat fMsgFormat = (StringFormat)null; + private Font fBoldFont = (Font)null; + + public TimelineGrid() + { + this.InitializeComponent(); + this.SetStyle(ControlStyles.DoubleBuffer, true); + this.SetStyle(ControlStyles.UserPaint, true); + this.SetStyle(ControlStyles.AllPaintingInWmPaint, true); + this.SetStyle(ControlStyles.ResizeRedraw, true); + this.create_renderers(); + } + + protected override void Dispose(bool disposing) + { + if (disposing && this.components != null) + this.components.Dispose(); + base.Dispose(disposing); + } + + private void InitializeComponent() + { + this.Font = new Font("Tahoma", 11f, FontStyle.Regular, GraphicsUnit.World, (byte)0); + this.Name = nameof(TimelineGrid); + this.Size = new Size(288, 176); + } + + public Timeline Timeline + { + get + { + return this.fTimeline; + } + set + { + this.fTimeline = value; + this.Refresh(); + } + } + + public SizeF CellSize + { + get + { + return this.fCellSize; + } + } + + public Element SelectedElement + { + get + { + return this.get_element(this.fSelectedElementID); + } + } + + public TimelinePoint SelectedPoint + { + get + { + return this.fSelectedPoint; + } + } + + public Element HoverElement + { + get + { + return this.get_element(this.fHoverElementID); + } + } + + public TimelinePoint HoverPoint + { + get + { + return this.fHoverPoint; + } + } + + private void create_renderers() + { + this.fColHdrFormat = new StringFormat(); + this.fColHdrFormat.Alignment = StringAlignment.Center; + this.fColHdrFormat.LineAlignment = StringAlignment.Far; + this.fColHdrFormat.Trimming = StringTrimming.EllipsisWord; + this.fColHdrFormat.FormatFlags |= StringFormatFlags.LineLimit; + this.fRowHdrFormat = new StringFormat(); + this.fRowHdrFormat.Alignment = StringAlignment.Near; + this.fRowHdrFormat.LineAlignment = StringAlignment.Center; + this.fRowHdrFormat.Trimming = StringTrimming.EllipsisWord; + this.fRowHdrFormat.FormatFlags |= StringFormatFlags.LineLimit; + this.fMsgFormat = new StringFormat(); + this.fMsgFormat.Alignment = StringAlignment.Center; + this.fMsgFormat.LineAlignment = StringAlignment.Center; + this.fMsgFormat.Trimming = StringTrimming.EllipsisWord; + this.fMsgFormat.FormatFlags |= StringFormatFlags.LineLimit; + this.fBoldFont = new Font(this.Font, this.Font.Style | FontStyle.Bold); + } + + protected override void OnPaint(PaintEventArgs e) + { + this.Render(e.Graphics, this.ClientRectangle); + } + + public void Render(Graphics g, Rectangle rect) + { + try + { + if (this.fTimeline == null) + return; + if (this.fTimeline.ElementIDs.Count == 0 || this.fTimeline.Points.Count == 0) + { + string s = ""; + if (this.fTimeline.ElementIDs.Count == 0) + s += "No elements in this timeline"; + if (this.fTimeline.Points.Count == 0) + { + if (s != "") + s += "\n"; + s += "No points in this timeline"; + } + g.DrawString(s, this.Font, SystemBrushes.ControlText, (RectangleF)rect, this.fMsgFormat); + } + else + { + this.calc_cell_size(rect); + this.draw_column_headers(g, rect); + this.draw_row_headers(g, rect); + foreach (Guid elementId in this.fTimeline.ElementIDs) + { + foreach (TimelinePoint point in this.fTimeline.Points) + this.draw_cell(g, elementId, point, rect); + } + } + } + catch (Exception ex) + { + LabyrinthData.Log((object)ex); + } + } + + private void draw_column_headers(Graphics g, Rectangle rect) + { + for (int p_index = 0; p_index != this.fTimeline.Points.Count; ++p_index) + { + TimelinePoint point = this.fTimeline.Points[p_index]; + RectangleF layoutRectangle = this.rect_for_cell(-1, p_index, rect); + string s = point.Name; + switch (point.UseSchedule) + { + case ScheduleType.Date: + s = s + "\n" + point.Schedule.ToShortDateString(); + break; + + case ScheduleType.DateTime: + s = s + "\n" + point.Schedule.ToShortDateString() + " " + point.Schedule.ToString("HH:mm"); + break; + } + g.DrawRectangle(SystemPens.ControlDark, layoutRectangle.X, layoutRectangle.Y, layoutRectangle.Width, layoutRectangle.Height); + Font font = point == this.SelectedPoint ? this.fBoldFont : this.Font; + g.DrawString(s, font, SystemBrushes.ControlText, layoutRectangle, this.fColHdrFormat); + } + } + + private void draw_row_headers(Graphics g, Rectangle rect) + { + for (int e_index = 0; e_index != this.fTimeline.ElementIDs.Count; ++e_index) + { + Element element = this.get_element(this.fTimeline.ElementIDs[e_index]); + RectangleF layoutRectangle = this.rect_for_cell(e_index, -1, rect); + Image image = LabyrinthData.ElementImages.Images[LabyrinthData.GetImageIndex(element.Type)]; + Rectangle rect1 = new Rectangle(new Point((int)layoutRectangle.X, (int)layoutRectangle.Top + ((int)layoutRectangle.Height - image.Height) / 2), image.Size); + g.DrawImage(image, rect1); + g.DrawRectangle(SystemPens.ControlDark, layoutRectangle.X, layoutRectangle.Y, layoutRectangle.Width, layoutRectangle.Height); + Font font = element == this.SelectedElement ? this.fBoldFont : this.Font; + layoutRectangle.X += (float)rect1.Width; + layoutRectangle.Width -= (float)rect1.Width; + g.DrawString(element.Name, font, SystemBrushes.ControlText, layoutRectangle, this.fRowHdrFormat); + } + } + + private void draw_cell(Graphics g, Guid element_id, TimelinePoint tlp, Rectangle rect) + { + RectangleF rect1 = this.rect_for_cell(this.fTimeline.ElementIDs.IndexOf(element_id), this.fTimeline.Points.IndexOf(tlp), rect); + rect1.Offset(1f, 1f); + rect1.Inflate(-1f, -1f); + ArrayList arrayList = new ArrayList(); + foreach (TimelineItem timelineItem in tlp.Items) + { + if (timelineItem.ElementID == element_id) + arrayList.Add((object)timelineItem.Annotation); + } + if (arrayList.Count != 0) + { + int count = arrayList.Count; + bool selected = element_id == this.fSelectedElementID && tlp == this.fSelectedPoint; + g.FillRectangle(selected ? SystemBrushes.Highlight : SystemBrushes.Window, rect1); + for (int index = 0; index != arrayList.Count; ++index) + { + Annotation a = arrayList[index] as Annotation; + int height = (int)((double)rect1.Height / (double)arrayList.Count); + int y = (int)((double)rect1.Y + (double)(height * index)); + Rectangle rect2 = new Rectangle((int)rect1.X, y, (int)rect1.Width, height); + Annotations.Render(a, rect2, this.Font, g, selected, false); + } + } + else + { + bool flag = element_id == this.fSelectedElementID && tlp == this.fSelectedPoint; + g.FillRectangle(flag ? SystemBrushes.Highlight : SystemBrushes.ControlLight, rect1); + if (!(element_id == this.fHoverElementID) || tlp != this.fHoverPoint) + return; + g.DrawRectangle(SystemPens.Highlight, rect1.X, rect1.Y, rect1.Width, rect1.Height); + } + } + + protected override void OnMouseDown(MouseEventArgs e) + { + base.OnMouseDown(e); + this.fSelectedPoint = (TimelinePoint)null; + this.fSelectedElementID = Guid.Empty; + if (this.fTimeline != null) + { + Point client = this.PointToClient(Cursor.Position); + int index1 = (int)((double)client.X / (double)this.fCellSize.Width) - 1; + if (index1 >= 0 && index1 < this.fTimeline.Points.Count) + this.fSelectedPoint = this.fTimeline.Points[index1]; + int index2 = (int)((double)client.Y / (double)this.fCellSize.Height) - 1; + if (index2 >= 0 && index2 < this.fTimeline.ElementIDs.Count) + this.fSelectedElementID = this.fTimeline.ElementIDs[index2]; + } + this.Refresh(); + } + + protected override void OnMouseMove(MouseEventArgs e) + { + base.OnMouseMove(e); + this.RecalculateHover(); + } + + public void RecalculateHover() + { + this.fHoverElementID = Guid.Empty; + this.fHoverPoint = (TimelinePoint)null; + if (this.fTimeline != null && this.fTimeline.Points.Count != 0 && this.fTimeline.ElementIDs.Count != 0) + { + Point client = this.PointToClient(Cursor.Position); + int index1 = (int)((double)client.X / (double)this.fCellSize.Width) - 1; + int index2 = (int)((double)client.Y / (double)this.fCellSize.Height) - 1; + if (index1 >= 0 && index2 >= 0 && (index1 < this.fTimeline.Points.Count && index2 < this.fTimeline.ElementIDs.Count)) + { + this.fHoverElementID = this.fTimeline.ElementIDs[index2]; + this.fHoverPoint = this.fTimeline.Points[index1]; + } + } + this.Refresh(); + } + + protected override void OnMouseLeave(EventArgs e) + { + base.OnMouseLeave(e); + this.fHoverElementID = Guid.Empty; + this.fHoverPoint = (TimelinePoint)null; + this.Refresh(); + } + + public override void Refresh() + { + this.calc_cell_size(this.ClientRectangle); + base.Refresh(); + } + + private Element get_element(Guid id) + { + int index = LabyrinthData.Project.Elements.IndexOf(id); + if (index != -1) + return LabyrinthData.Project.Elements[index]; + return (Element)null; + } + + private RectangleF rect_for_cell(int e_index, int p_index, Rectangle rect) + { + float num1 = (float)(p_index + 1) * this.fCellSize.Width; + float num2 = (float)(e_index + 1) * this.fCellSize.Height; + return new RectangleF(num1 + (float)rect.Left, num2 + (float)rect.Top, this.fCellSize.Width, this.fCellSize.Height); + } + + private void calc_cell_size(Rectangle rect) + { + if (this.fTimeline == null || this.fTimeline.ElementIDs.Count == 0 || this.fTimeline.Points.Count == 0) + return; + this.fCellSize.Width = (float)rect.Width / (float)(this.fTimeline.Points.Count + 1); + this.fCellSize.Height = (float)rect.Height / (float)(this.fTimeline.ElementIDs.Count + 1); + } + + public Image CreateImage() + { + Image image = (Image)new Bitmap(this.Width, this.Height); + Graphics graphics = Graphics.FromImage(image); + graphics.Clear(this.BackColor); + this.OnPaint(new PaintEventArgs(graphics, new Rectangle(0, 0, this.Width, this.Height))); + return image; + } + } +} \ No newline at end of file diff --git a/Labyrinth3/IDE/Controls/TimelineGrid.resx b/Labyrinth3/IDE/Controls/TimelineGrid.resx new file mode 100644 index 0000000..3a2810a --- /dev/null +++ b/Labyrinth3/IDE/Controls/TimelineGrid.resx @@ -0,0 +1,123 @@ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + text/microsoft-resx + + + 2.0 + + + System.Resources.ResXResourceReader, System.Windows.Forms, Version=4.0.0.0, Culture=neutral, PublicKeyToken=b77a5c561934e089 + + + System.Resources.ResXResourceWriter, System.Windows.Forms, Version=4.0.0.0, Culture=neutral, PublicKeyToken=b77a5c561934e089 + + + TimelineGrid + + \ No newline at end of file diff --git a/Labyrinth3/IDE/Extensibility/AddInManager.cs b/Labyrinth3/IDE/Extensibility/AddInManager.cs new file mode 100644 index 0000000..e22efea --- /dev/null +++ b/Labyrinth3/IDE/Extensibility/AddInManager.cs @@ -0,0 +1,84 @@ +// Decompiled with JetBrains decompiler +// Type: Labyrinth.Extensibility.AddInManager +// Assembly: Labyrinth, Version=3.6.1928.15690, Culture=neutral, PublicKeyToken=null +// MVID: 1462002E-0BD1-49D2-9B56-C22E66C903E7 +// Assembly location: C:\Dropbox\Workspace\Programs\Labyrinth\Labyrinth.exe + +using System; +using System.Collections; +using System.IO; +using System.Reflection; + +namespace Labyrinth.Extensibility +{ + public class AddInManager + { + private ArrayList fAddIns = new ArrayList(); + + public ArrayList AddIns + { + get + { + return this.fAddIns; + } + } + + public void Load(string dir, IApplication app) + { + foreach (string searchFile in this.search_files(dir, "*.dll")) + this.check_dll(searchFile, app); + } + + private ArrayList search_files(string dir, string mask) + { + ArrayList arrayList1 = new ArrayList(); + if (Directory.Exists(dir)) + { + string[] files = Directory.GetFiles(dir, mask); + arrayList1.AddRange((ICollection)files); + foreach (string directory in Directory.GetDirectories(dir)) + { + ArrayList arrayList2 = this.search_files(directory, mask); + arrayList1.AddRange((ICollection)arrayList2); + } + } + return arrayList1; + } + + private void check_dll(string filename, IApplication app) + { + try + { + foreach (Type type in Assembly.LoadFrom(filename).GetTypes()) + { + if (type.GetInterface(typeof(IAddIn).Name) != null) + { + ConstructorInfo constructor = type.GetConstructor(Type.EmptyTypes); + if (constructor != null) + { + try + { + IAddIn addIn = constructor.Invoke((object[])null) as IAddIn; + if (addIn != null) + { + if (addIn.Load(app)) + this.fAddIns.Add((object)addIn); + else + addIn.Unload(); + } + } + catch (Exception ex) + { + LabyrinthData.Log((object)ex); + } + } + } + } + } + catch (Exception ex) + { + LabyrinthData.Log((object)ex); + } + } + } +} \ No newline at end of file diff --git a/Labyrinth3/IDE/FileConversion.cs b/Labyrinth3/IDE/FileConversion.cs new file mode 100644 index 0000000..de9c79d --- /dev/null +++ b/Labyrinth3/IDE/FileConversion.cs @@ -0,0 +1,55 @@ +// Decompiled with JetBrains decompiler +// Type: Labyrinth.FileConversion +// Assembly: Labyrinth, Version=3.6.1928.15690, Culture=neutral, PublicKeyToken=null +// MVID: 1462002E-0BD1-49D2-9B56-C22E66C903E7 +// Assembly location: C:\Dropbox\Workspace\Programs\Labyrinth\Labyrinth.exe + +using System.Xml; + +namespace Labyrinth +{ + public class FileConversion + { + public static bool Convert(ref string content) + { + bool flag = false; + string str = ""; + XmlDocument xmlDocument = new XmlDocument(); + xmlDocument.LoadXml(content); + foreach (XmlNode childNode in xmlDocument.DocumentElement.ChildNodes) + { + if (childNode.Name == "SaveFormat") + { + str = childNode.InnerText; + break; + } + } + if (str == "") + { + XmlElement element = xmlDocument.CreateElement("SaveFormat"); + element.InnerText = "3.3"; + xmlDocument.DocumentElement.InsertAfter((XmlNode)element, (XmlNode)null); + str = "3.3"; + flag = true; + } + if (str == "3.3") + { + foreach (XmlNode childNode in xmlDocument.DocumentElement.ChildNodes) + { + if (childNode.Name == "SaveFormat") + { + childNode.InnerText = "3.4"; + break; + } + } + str = "3.4"; + flag = true; + } + if (str == "3.4") + flag = true; + if (flag) + content = xmlDocument.OuterXml; + return flag; + } + } +} \ No newline at end of file diff --git a/Labyrinth3/IDE/Forms/AboutDlg.cs b/Labyrinth3/IDE/Forms/AboutDlg.cs new file mode 100644 index 0000000..e009862 --- /dev/null +++ b/Labyrinth3/IDE/Forms/AboutDlg.cs @@ -0,0 +1,145 @@ +// Decompiled with JetBrains decompiler +// Type: Labyrinth.Forms.AboutDlg +// Assembly: Labyrinth, Version=3.6.1928.15690, Culture=neutral, PublicKeyToken=null +// MVID: 1462002E-0BD1-49D2-9B56-C22E66C903E7 +// Assembly location: C:\Dropbox\Workspace\Programs\Labyrinth\Labyrinth.exe + +using System; +using System.ComponentModel; +using System.Diagnostics; +using System.Drawing; +using System.Resources; +using System.Windows.Forms; + +namespace Labyrinth.Forms +{ + public class AboutDlg : Form + { + private Container components = (Container)null; + private Button OKBn; + private Label VersionLbl; + private Label CopyrightLbl; + private LinkLabel EmailLbl; + private PictureBox pictureBox1; + private Label VerLbl; + private Label CopyLbl; + private Label SuppLbl; + + public AboutDlg() + { + this.InitializeComponent(); + this.VersionLbl.Text = Application.ProductVersion; + } + + protected override void Dispose(bool disposing) + { + if (disposing && this.components != null) + this.components.Dispose(); + base.Dispose(disposing); + } + + private void InitializeComponent() + { + ResourceManager resourceManager = new ResourceManager(typeof(AboutDlg)); + this.VersionLbl = new Label(); + this.CopyrightLbl = new Label(); + this.OKBn = new Button(); + this.EmailLbl = new LinkLabel(); + this.pictureBox1 = new PictureBox(); + this.VerLbl = new Label(); + this.CopyLbl = new Label(); + this.SuppLbl = new Label(); + this.SuspendLayout(); + this.VersionLbl.Anchor = AnchorStyles.Top | AnchorStyles.Left | AnchorStyles.Right; + this.VersionLbl.Location = new Point(88, 96); + this.VersionLbl.Name = "VersionLbl"; + this.VersionLbl.Size = new Size(176, 23); + this.VersionLbl.TabIndex = 0; + this.VersionLbl.Text = "{version}"; + this.VersionLbl.TextAlign = ContentAlignment.MiddleLeft; + this.CopyrightLbl.Anchor = AnchorStyles.Top | AnchorStyles.Left | AnchorStyles.Right; + this.CopyrightLbl.Location = new Point(88, 128); + this.CopyrightLbl.Name = "CopyrightLbl"; + this.CopyrightLbl.Size = new Size(176, 23); + this.CopyrightLbl.TabIndex = 1; + this.CopyrightLbl.Text = "Karetao 2004"; + this.CopyrightLbl.TextAlign = ContentAlignment.MiddleLeft; + this.OKBn.Anchor = AnchorStyles.Bottom | AnchorStyles.Right; + this.OKBn.DialogResult = DialogResult.OK; + this.OKBn.Location = new Point(184, 208); + this.OKBn.Name = "OKBn"; + this.OKBn.TabIndex = 3; + this.OKBn.Text = "OK"; + this.EmailLbl.Anchor = AnchorStyles.Top | AnchorStyles.Left | AnchorStyles.Right; + this.EmailLbl.Location = new Point(88, 160); + this.EmailLbl.Name = "EmailLbl"; + this.EmailLbl.Size = new Size(176, 24); + this.EmailLbl.TabIndex = 2; + this.EmailLbl.TabStop = true; + this.EmailLbl.Text = "labyrinth@habitualindolence.net"; + this.EmailLbl.TextAlign = ContentAlignment.MiddleLeft; + this.EmailLbl.LinkClicked += new LinkLabelLinkClickedEventHandler(this.EmailLbl_LinkClicked); + this.pictureBox1.BorderStyle = BorderStyle.Fixed3D; + this.pictureBox1.Image = (Image)resourceManager.GetObject("pictureBox1.Image"); + this.pictureBox1.Location = new Point(29, 16); + this.pictureBox1.Name = "pictureBox1"; + this.pictureBox1.Size = new Size(216, 59); + this.pictureBox1.TabIndex = 6; + this.pictureBox1.TabStop = false; + this.VerLbl.Location = new Point(16, 96); + this.VerLbl.Name = "VerLbl"; + this.VerLbl.Size = new Size(64, 23); + this.VerLbl.TabIndex = 7; + this.VerLbl.Text = "Version:"; + this.VerLbl.TextAlign = ContentAlignment.MiddleLeft; + this.CopyLbl.Location = new Point(16, 128); + this.CopyLbl.Name = "CopyLbl"; + this.CopyLbl.Size = new Size(64, 23); + this.CopyLbl.TabIndex = 8; + this.CopyLbl.Text = "Copyright:"; + this.CopyLbl.TextAlign = ContentAlignment.MiddleLeft; + this.SuppLbl.Location = new Point(16, 160); + this.SuppLbl.Name = "SuppLbl"; + this.SuppLbl.Size = new Size(64, 23); + this.SuppLbl.TabIndex = 9; + this.SuppLbl.Text = "Support:"; + this.SuppLbl.TextAlign = ContentAlignment.MiddleLeft; + this.AcceptButton = (IButtonControl)this.OKBn; + this.AutoScaleBaseSize = new Size(5, 14); + this.ClientSize = new Size(274, 248); + this.Controls.AddRange(new Control[8] + { + (Control) this.SuppLbl, + (Control) this.CopyLbl, + (Control) this.VerLbl, + (Control) this.pictureBox1, + (Control) this.EmailLbl, + (Control) this.OKBn, + (Control) this.CopyrightLbl, + (Control) this.VersionLbl + }); + this.Font = new Font("Tahoma", 11f, FontStyle.Regular, GraphicsUnit.World); + this.FormBorderStyle = FormBorderStyle.FixedDialog; + this.Icon = (Icon)resourceManager.GetObject("$this.Icon"); + this.MaximizeBox = false; + this.MinimizeBox = false; + this.Name = nameof(AboutDlg); + this.ShowInTaskbar = false; + this.StartPosition = FormStartPosition.CenterParent; + this.Text = "About"; + this.ResumeLayout(false); + } + + private void EmailLbl_LinkClicked(object sender, LinkLabelLinkClickedEventArgs e) + { + try + { + Process.Start("mailto:" + this.EmailLbl.Text); + } + catch (Exception ex) + { + LabyrinthData.Log((object)ex); + } + } + } +} \ No newline at end of file diff --git a/Labyrinth3/IDE/Forms/AboutDlg.resx b/Labyrinth3/IDE/Forms/AboutDlg.resx new file mode 100644 index 0000000..e187896 --- /dev/null +++ b/Labyrinth3/IDE/Forms/AboutDlg.resx @@ -0,0 +1,817 @@ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + text/microsoft-resx + + + 2.0 + + + System.Resources.ResXResourceReader, System.Windows.Forms, Version=4.0.0.0, Culture=neutral, PublicKeyToken=b77a5c561934e089 + + + System.Resources.ResXResourceWriter, System.Windows.Forms, Version=4.0.0.0, Culture=neutral, PublicKeyToken=b77a5c561934e089 + + + + + AAABAAMAICAQAAAAAADoAgAANgAAABAQEAAAAAAAKAEAAB4DAAAwMBAAAAAAAGgGAABGBAAAKAAAACAA + AABAAAAAAQAEAAAAAAAAAgAAAAAAAAAAAAAQAAAAEAAAAAAAAAAAAIAAAIAAAACAgACAAAAAgACAAICA + AACAgIAAwMDAAAAA/wAA/wAAAP//AP8AAAD/AP8A//8AAP///wAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA + AAAAAAAAAAAAAABERERERERERERERERERAAAREREREREREREREREREQAAEREREREREREREREREREAABE + T//////////////0RAAARE//////////////9EQAAERP//////////////REAABET///RI////9Ej//0 + RAAARE///0SP///0RI//9EQAAERP//9ESP//REj///REAABET///9Ej//0SP///0RAAARE////REj/RE + j///9EQAAERP////REj0SP////REAABET/////REREj////0RAAARE//////RESP////9EQAAERP//// + //REj/////REAABET//////0SP/////0RAAARE//////9Ej/////9EQAAERP/////0RI//////REAABE + T/////9Ej//////0RAAARE/////0RI//////9EQAAERP//9EREj///////REAABET///9ESP///////0 + RAAARE//////////////9EQAAERP//////////////REAABET//////////////0RAAARERERERERERE + REREREQAAEREREREREREREREREREAABERERERERERERERERERAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA + AAAAAAAAAAAAAP//////////wAAAA8AAAAPAAAADwAAAA8AAAAPAAAADwAAAA8AAAAPAAAADwAAAA8AA + AAPAAAADwAAAA8AAAAPAAAADwAAAA8AAAAPAAAADwAAAA8AAAAPAAAADwAAAA8AAAAPAAAADwAAAA8AA + AAPAAAADwAAAA///////////KAAAABAAAAAgAAAAAQAEAAAAAACAAAAAAAAAAAAAAAAQAAAAEAAAAAAA + AAAAAIAAAIAAAACAgACAAAAAgACAAICAAACAgIAAwMDAAAAA/wAA/wAAAP//AP8AAAD/AP8A//8AAP// + /wD///////////RERERERERP9ERERERERE/0T//////0T/RP9I//SPRP9E/0SPRI9E/0T/9EhI/0T/RP + //REj/RP9E///0j/9E/0T//0SP/0T/RP9ESP//RP9E//SP//9E/0T//////0T/RERERERERP9ERERERE + RE///////////wAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA + AAAAAAAAAAAAAAAAAAAoAAAAMAAAAGAAAAABAAQAAAAAAIAEAAAAAAAAAAAAABAAAAAQAAAAAAAAAAAA + gAAAgAAAAICAAIAAAACAAIAAgIAAAMDAwACAgIAAAAD/AAD/AAAA//8A/wAAAP8A/wD//wAA////AAAA + AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA + AAAAAAAAAAAAAAAERERERERERERERERERERERERERERAAAAERERERERERERERERERERERERERERAAAAE + RERERERERERERERERERERERERERAAAAERERERERERERERERERERERERERERAAAAERERERERERERERERE + RERERERERERAAAAERE//////////////////////RERAAAAERE//////////////////////RERAAAAE + RE//////////////////////RERAAAAERE//////////////////////RERAAAAERE/////0RH////// + /0RH////RERAAAAERE/////0RH//////9ERH////RERAAAAERE/////0RH//////RER/////RERAAAAE + RE//////REf////0REf/////RERAAAAERE//////REf////0RH//////RERAAAAERE//////9ER///9E + RH//////RERAAAAERE//////9ERH//9ER///////RERAAAAERE///////0RH//9ER///////RERAAAAE + RE///////0REf/REf///////RERAAAAERE////////RER/REf///////RERAAAAERE////////9ERERH + ////////RERAAAAERE/////////0RERH////////RERAAAAERE//////////9ERH////////RERAAAAE + RE//////////9ER/////////RERAAAAERE//////////RER/////////RERAAAAERE//////////REf/ + ////////RERAAAAERE//////////REf/////////RERAAAAERE/////////0REf/////////RERAAAAE + RE/////////0RH//////////RERAAAAERE////////9ERH//////////RERAAAAERE////////RER/// + ////////RERAAAAERE/////0REREf///////////RERAAAAERE/////0RERH////////////RERAAAAE + RE//////REf/////////////RERAAAAERE//////////////////////RERAAAAERE////////////// + ////////RERAAAAERE//////////////////////RERAAAAERE//////////////////////RERAAAAE + RE//////////////////////RERAAAAERERERERERERERERERERERERERERAAAAERERERERERERERERE + RERERERERERAAAAERERERERERERERERERERERERERERAAAAERERERERERERERERERERERERERERAAAAA + AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA + AAAAAAAAAAAAAP///////wAA////////AAD///////8AAOAAAAAABwAA4AAAAAAHAADgAAAAAAcAAOAA + AAAABwAA4AAAAAAHAADgAAAAAAcAAOAAAAAABwAA4AAAAAAHAADgAAAAAAcAAOAAAAAABwAA4AAAAAAH + AADgAAAAAAcAAOAAAAAABwAA4AAAAAAHAADgAAAAAAcAAOAAAAAABwAA4AAAAAAHAADgAAAAAAcAAOAA + AAAABwAA4AAAAAAHAADgAAAAAAcAAOAAAAAABwAA4AAAAAAHAADgAAAAAAcAAOAAAAAABwAA4AAAAAAH + AADgAAAAAAcAAOAAAAAABwAA4AAAAAAHAADgAAAAAAcAAOAAAAAABwAA4AAAAAAHAADgAAAAAAcAAOAA + AAAABwAA4AAAAAAHAADgAAAAAAcAAOAAAAAABwAA4AAAAAAHAADgAAAAAAcAAOAAAAAABwAA4AAAAAAH + AADgAAAAAAcAAP///////wAA////////AAD///////8AAA== + + + + AboutDlg + + + + Qk2OlQAAAAAAADYAAAAoAAAA2AAAADsAAAABABgAAAAAAAAAAADEDgAAxA4AAAAAAAAAAAAA//////// + //////////////////////////////////////////////////////////////////////////////// + //////////////////////////////////////////////////////////////////////////////// + //////////////////////////////////////////////////////////////////////////////// + //////////////////////////////////////////////////////////////////////////////// + //////////////////////////////////////////////////////////////////////////////// + //////////////////////////////////////////////////////////////////////////////// + //////////////////////////////////////////////////////////////////////////////// + //////////////////////////////////////////////////////////////////////////////// + //////////////////////////////////////////////////////////////////////////////// + //////////////////////////////////////////////////////////////////////////////// + //////////////////////////////////////////////////////////////////////////////// + //////////////////////////////////////////////////////////////////////////////// + //////////////////////////////////////////////////////////////////////////////// + //////////////////////////////////////////////////////////////////////////////// + //////////////////////////////////////////////////////////////////////////////// + //////////////////////////////////////////////////////////////////////////////// + //////////////////////////////////////////////////////////////////////////////// + //////////////////////////////////////////////////////////////////////////////// + //////////////////////////////////////////////////////////////////////////////// + //////////////////////////////////////////////////////////////////////////////// + //////////////////////////////////////////////////////////////////////////////// + //////////////////////////////////////////////////////////////////////////////// + //////////////////////////////////////////////////////////////////////////////// + //////////////////////////////////////////////////////////////////////////////// + //////////////////////////////////////////////////////////////////////////////// + //////////////////////////////////////////////////////////////////////////////// + //////////////////////////////////////////////////////////////////////////////// + //////////////////////////////////////////////////////////////////////////////// + //////////////////////////////////////////////////////////////////////////////// + //////////////////////////////////////////////////////////////////////////////// + //////////////////////////////////////////////////////////////////////////////// + //////////////////////////////////////////////////////////////////////////////// + //////////////////////////////////////////////////////////////////////////////// + //////////////////////////////////////////////////////////////////////////////// + //////////////////////////////////////////////////////////////////////////////// + //////////////////////////////////////////////////////////////////////////////// + //////////////////////////////////////////////////////////////////////////////// + //////////////////////////////////////////////////////////////////////////////// + //////////////////////////////////////////////////////////////////////////////// + //////////////////////////////////////////////////////////////////////////////// + //////////////////////////////////////////////////////////////////////////////// + //////////////////////////////////////////////////////////////////////////////// + //////////////////////////////////////////////////////////////////////////////// + //////////////////////////////////////////////////////////////////////////////// + //////////////////////////////////////////////////////////////////////////////// + //////////////////////////////////////////////////////////////////////////////// + //////////////////////////////////////////////////////////////////////////////// + //////////////////////////////////////////////////////////////////////////////// + //////////////////////////////////////////////////////////////////////////////// + //////////////////////////////////////////////////////////////////////////////// + //////////////////////////////////////////////////////////////////////////////// + //////////////////////////////////////////////////////////////////////////////// + //////////////////////////////////////////////////////////////////////////////// + //////////////////////////////////////////////////////////////////////////////// + //////////////////////////////////////////////////////////////////////////////// + //////////////////////////////////////////////////////////////////////////////// + //////////////////////////////////////////////////////////////////////////////// + //////////////////////////////////////////////////////////////////////////////// + //////////////////////////////////////////////////////////////////////////////// + //////////////////////////////////////////////////////////////////////////////// + //////////////////////////////////////////////////////////////////////////////// + //////////////////////////////////////////////////////////////////////////////// + //////////////////////////////////////////////////////////////////////////////// + //////////////////////////////////////////////////////////////////////////////// + //////////////////////////////////////////////////////////////////////////////// + //////////////////////////////////////////////////////////////////////////////// + //////////////////////////////////////////////////////////////////////////////// + //////////////////////////////////////////////////////////////////////////////// + //////////////////////////////////////////////////////////////////////////////// + //////////////////////////////////////////////////////////////////////////////// + //////////////////////////////////////////////////////////////////////////////// + //////////////////////////////////////////////////////////////////////////////// + //////////////////////////////////////////////////////////////////////////////// + //////////////////////////////////////////////////////////////////////////////// + //////////////////////////////////////////////////////////////////////////////// + //////////////////////////////////////////////////////////////////////////////// + //////////////////////////////////////////////////////////////////////////////// + //////////////////////////////////////////////////////////////////////////////// + //////////////////////////////////////////////////////////////////////////////// + //////////////////////////////////////////////////////////////////////////////// + //////////////////////////////////////////////////////////////////////////////// + //////////////////////////////////////////////////////////////////////////////// + //////////////////////////////////////////////////////////////////////////////// + //////////////////////////////////////////////////////////////////////////////// + //////////////////////////////////////////////////////////////////////////////// + //////////////////////////////////////////////////////////////////////////////// + //////////////////////////////////////////////////////////////////////////////// + //////////////////////////////////////////////////////////////////////////////// + //////////////////////////////////////////////////////////////////////////////// + //////////////////////////////////////////////////////////////////////////////// + //////////////////////////////////////////////////////////////////////////////// + //////////////////////////////////////////////////////////////////////////////// + //////////////////////////////////////////////////////////////////////////////// + //////////////////////////////////////////////////////////////////////////////// + //////////////////////////////////////////////////////////////////////////////// + //////////////////////////////////////////////////////////////////////////////// + //////////////////////////////////////////////////////////////////////////////// + ////////////////////////////////////////////////gAAAgAAAgAAAgAAAgAAAgAAAgAAAgAAA + gAAAgAAAgAAAgAAAgAAAgAAAgAAAgAAAgAAAgAAAgAAAgAAAgAAAgAAAgAAAgAAAgAAAgAAAgAAAgAAA + gAAAgAAAgAAAgAAAgAAAgAAAgAAAgAAAgAAAgAAAgAAAgAAAgAAAgAAA//////////////////////// + //////////////////////////////////////////////////////////////////////////////// + //////////////////////////////////////////////////////////////////////////////// + //////////////////////////////////////////////////////////////////////////////// + //////////////////////////////////////////////////////////////////////////////// + //////////////////////////////////////////////////////////////////////////////// + //////////////////////////////////////////////////////////////////////////////// + //////////////////////////////////////////////////////////////////////////////// + //////////////////////////////////////////////////////////////////////////////// + ////////////////////////////////gAAAgAAAgAAAgAAAgAAAgAAAgAAAgAAAgAAAgAAAgAAAgAAA + gAAAgAAAgAAAgAAAgAAAgAAAgAAAgAAAgAAAgAAAgAAAgAAAgAAAgAAAgAAAgAAAgAAAgAAAgAAAgAAA + gAAAgAAAgAAAgAAAgAAAgAAAgAAAgAAAgAAAgAAA//////////////////////////////////////// + //////////////////////////////////////////////////////////////////////////////// + //////////////////////////////////////////////////////////////////////////////// + //////////////////////////////////////////////////////////////////////////////// + //////////////////////////////////////////////////////////////////////////////// + //////////////////////////////////////////////////////////////////////////////// + //////////////////////////////////////////////////////////////////////////////// + //////////////////////////////////////////////////////////////////////////////// + //////////////////////////////////////////////////////////////////////////////// + ////////////////gAAAgAAAgAAAgAAAgAAAgAAAgAAAgAAAgAAAgAAAgAAAgAAAgAAAgAAAgAAAgAAA + gAAAgAAAgAAAgAAAgAAAgAAAgAAAgAAAgAAAgAAAgAAAgAAAgAAAgAAAgAAAgAAAgAAAgAAAgAAAgAAA + gAAAgAAAgAAAgAAAgAAAgAAA//////////////////////////////////////////////////////// + //////////////////////////////////////////////////////////////////////////////// + //////////////////////////////////////////////////////////////////////////////// + //////////////////////////////////////////////////////////////////////////////// + //////////////////////////////////////////////////////////////////////////////// + //////////////////////////////////////////////////////////////////////////////// + //////////////////////////////////////////////////////////////////////////////// + //////////////////////////////////////////////////////////////////////////////// + //////////////////////////////////////////////////////////////////////////////// + gAAAgAAAgAAAgAAAgAAAgAAAgAAAgAAAgAAAgAAAgAAAgAAAgAAAgAAAgAAAgAAAgAAAgAAAgAAAgAAA + gAAAgAAAgAAAgAAAgAAAgAAAgAAAgAAAgAAAgAAAgAAAgAAAgAAAgAAAgAAAgAAAgAAAgAAAgAAAgAAA + gAAAgAAA//////////////////////////////////////////////////////////////////////// + //////////////////////////////////////////////////////////////////////////////// + //////////////////////////////////////////////////////////////////////////////// + //////////////////////////////////////////////////////////////////////////////// + //////////////////////////////////////////////////////////////////////////////// + //////////////////////////////////////////////////////////////////////////////// + //////////////////////////////////////////////////////////////////////////////// + //////////////////////////////////////////////////////////////////////////////// + ////////////////////////////////////////////////////////////////gAAAgAAAgAAAgAAA + gAAAgAAAgAAAgAAAgAAAgAAAgAAAgAAAgAAAgAAAgAAAgAAAgAAAgAAAgAAAgAAAgAAAgAAAgAAAgAAA + gAAAgAAAgAAAgAAAgAAAgAAAgAAAgAAAgAAAgAAAgAAAgAAAgAAAgAAAgAAAgAAAgAAAgAAA//////// + //////////////////////////////////////////////////////////////////////////////// + //////////////////////////////////////////////////////////////////////////////// + //////////////////////////////////////////////////////////////////////////////// + //////////////////////////////////////////////////////////////////////////////// + //////////////////////////////////////////////////////////////////////////////// + //////////////////////////////////////////////////////////////////////////////// + //////////////////////////////////////////////////////////////////////////////// + //////////////////////////////////////////////////////////////////////////////// + ////////////////////////////////////////////////gAAAgAAAgAAAgAAA//////////////// + //////////////////////////////////////////////////////////////////////////////// + ////////////////////////////////////gAAAgAAAgAAAgAAAgAAA//////////////////////// + //////////////////////////////////////////////////////////////////////////////// + //////////////////////////////////////////////////////////////////////////////// + //////////////////////////////////////////////////////////////////////////////// + //////////////////////////////////////////////////////////////////////////////// + //////////////////////////////////////////////////////////////////////////////// + //////////////////////////////////////////////////////////////////////////////// + //////////////////////////////////////////////////////////////////////////////// + //////////////////////////////////////////////////////////////////////////////// + ////////////////////////////////gAAAgAAAgAAAgAAA//////////////////////////////// + //////////////////////////////////////////////////////////////////////////////// + ////////////////////gAAAgAAAgAAAgAAAgAAA//////////////////////////////////////// + //////////////////////////////////////////////////////////////////////////////// + //////////////////////////////////////////////////////////////////////////////// + //////////////////////////////////////////////////////////////////////////////// + //////////////////////////////////////////////////////////////////////////////// + //////////////////////////////////////////////////////////////////////////////// + //////////////////////////////////////////////////////////////////////////////// + //////////////////////////////////////////////////////////////////////////////// + //////////////////////////////////////////////////////////////////////////////// + ////////////////gAAAgAAAgAAAgAAA//////////////////////////////////////////////// + //////////////////////////////////////////////////////////////////////////////// + ////gAAAgAAAgAAAgAAAgAAA//////////////////////////////////////////////////////// + //////////////////////////////////////////////////////////////////////////////// + //////////////////////////////////////////////////////////////////////////////// + ////////////////////////////////////////////////////////////AGqxAAAAAAAAAAAA2K9r + //////////////////////////////////////////////////////////////////////////////// + //////////////////////////////////////////////////////////////////////////////// + //////////////////////////////////////////////////////////////////////////////// + //////////////////////////////////////////////////////////////////////////////// + //////////////////////////////////////////////////////////////////////////////// + gAAAgAAAgAAAgAAA//////////////////////////////////////////////////////////////// + ////////////////////////////////////////////////////////////////////gAAAgAAAgAAA + gAAAgAAA//////////////////////////////////////////////////////////////////////// + //////////////////////////////////////////////////////////////////////////////// + //////////////////////////////////////////////////////////////////////////////// + ////////////////////////////////////////////AGqxAAAAAAAAAAAAAAAAvY9B//////////// + //////////////////////////////////////////////////////////////////////////////// + //////////////////////////////////////////////////////////////////////////////// + //////////////////////////////////////////////////////////////////////////////// + //////////////////////////////////////////////////////////////////////////////// + ////////////////////////////////////////////////////////////////gAAAgAAAgAAAgAAA + ////////////////////////////////gAAAgAAAgAAAwMDA//////////////////////////////// + ////////////gAAAgAAAgAAAwMDA////////////////////////gAAAgAAAgAAAgAAAgAAA//////// + //////////////////////////////////////////////////////////////////////////////// + //////////////////////////////////////////////////////////////////////////////// + //////////////////////////////////////////////////////////////////////////////// + ////////////////////////////AGqxAAAAAAAAAAAAAAAAYgAA2Omx//////////////////////// + //////////////////////////////////////////////////////////////////////////////// + //////////////////////////////////////////////////////////////////////////////// + //////////////////////////////////////////////////////////////////////////////// + //////////////////////////////////////////////////////////////////////////////// + ////////////////////////////////////////////////gAAAgAAAgAAAgAAA//////////////// + ////////////////gAAAgAAAgAAAwMDA////////////////////////////////////////gAAAgAAA + gAAAgAAAwMDA////////////////////////gAAAgAAAgAAAgAAAgAAA//////////////////////// + //////////////////////////////////////////////////////////////////////////////// + //////////////////////////////////////////////////////////////////////////////// + //////////////////////////////////////////////////////////////////////////////// + ////////////////////////hM3sAABBAAAAvY9B//////////////////////////////////////// + //////////////////////////////////////////////////////////////////////////////// + //////////////////////////////////////////////////////////////////////////////// + //////////////////////////////////////////////////////////////////////////////// + //////////////////////////////////////////////////////////////////////////////// + ////////////////////////////////gAAAgAAAgAAAgAAA//////////////////////////////// + gAAAgAAAgAAAwMDA////////////////////////////////////gAAAgAAAgAAAgAAAwMDA//////// + ////////////////////gAAAgAAAgAAAgAAAgAAA//////////////////////////////////////// + //////////////////////////////////////////////////////////////////////////////// + //////////////////////////////////////////////////////////////////////////////// + //////////////////////////////////////////////////////////////////////////////// + ////////////AGqxAAAAhEEA2OnP//////////////////////////////////////////////////// + //////////////////////////////////////////////////////////////////////////////// + //////////////////////////////////////////////////////////////////////////////// + //////////////////////////////////////////////////////////////////////////////// + //////////////////////////////////////////////////////////////////////////////// + ////////////////gAAAgAAAgAAAgAAA////////////////////////////////////gAAAgAAAgAAA + wMDA////////////////////////////gAAAgAAAgAAAgAAAwMDA//////////////////////////// + ////gAAAgAAAgAAAgAAAgAAA//////////////////////////////////////////////////////// + ////////////////////////////////vensAEGQAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA + AAAAvY9B////////////PI/PAAAAAAAAAAAAAAAAvY9B////vensAEGQAAAAAAAAvY9B////////ouns + AABromoA////////Yq/sAAAAAAAAAAAAAAAAvY9B////////////////////////////////////AGqx + AAAAPAAA2M2Q////////////////////ounsAABrAAAAAAAA2K9r////////////////////ounsAABr + AAAAAAAA2K9r////////ounsAABrAAAAAAAA2K9r////////////////hM3sAABBAAAAAAAA2K9r//// + ////////////////AGqxAAAAAAAAAAAAhEEA2OnP////ounsAABrAAAAAAAA2K9r//////////////// + hM3sAABBAAAAAAAA2K9r//////////////////////////////////////////////////////////// + //////////////////////////////////////////////////////////////////////////////// + gAAAgAAAgAAAgAAA////////////////////////////////////gAAAgAAAgAAAwMDA//////////// + ////////////////gAAAgAAAgAAAwMDA////////////////////////////////////gAAAgAAAgAAA + gAAAgAAA//////////////////////////////////////////////////////////////////////// + ////////////////vensAEGQAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAvY9B////vens + AEGQAAAAAAAAAAAAAAAAAAAAAAAAhEEAounPAABrAAAAAAAA2K9r////////ounsAABrPAAAvc2QAEGQ + AAAAAAAAAAAAAAAAAAAAAAAAYgAA2Omx////////////////////////ounsAABrAAAAAAAAvY9B//// + ////////////////ounsAABrAAAAAAAA2K9r////////////////////ounsAABrAAAAAAAA2K9r//// + ////ounsAABrAAAAAAAA2K9r////////////////hM3sAABBAAAAAAAA2K9r////////////vensAEGQ + AAAAAAAAAAAAAAAAhEEA2OnP////ounsAABrAAAAAAAA2K9r////////////////hM3sAABBAAAAAAAA + 2K9r//////////////////////////////////////////////////////////////////////////// + ////////////////////////////////////////////////////////////////gAAAgAAAgAAAgAAA + ////////////////////////////////////////gAAAgAAAgAAAwMDA////////////////////gAAA + gAAAgAAAgAAAwMDA////////////////////////////////////gAAAgAAAgAAAgAAAgAAA//////// + //////////////////////////////////////////////////////////////////////////////// + vensAEGQAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAvY9B////PI/PAAAAAAAAAAAAAAAA + AAAAAAAAAAAAAAAAPEEAAABBAAAAAAAA2K9r////////ounsAABrAAAAAAAAAAAAAAAAAAAAAAAAAAAA + AAAAAAAAAAAAomoA////////////////////////Yq/sAAAAAAAAAAAAhEEA2OnP//////////////// + ounsAABrAAAAAAAA2K9r////////////////////ounsAABrAAAAAAAA2K9r////////ounsAABrAAAA + AAAA2K9r////////////////hM3sAABBAAAAAAAA2K9r////////////Yq/sAAAAAAAAAAAAAAAAAAAA + hEEA2OnP////ounsAABrAAAAAAAA2K9r////////////////hM3sAABBAAAAAAAA2K9r//////////// + //////////////////////////////////////////////////////////////////////////////// + ////////////////////////////////////////////////gAAAgAAAgAAAgAAA//////////////// + ////////////////////////gAAAgAAAgAAAgAAAwMDA////////////////gAAAgAAAgAAAwMDA//// + ////////////////////////////////////gAAAgAAAgAAAgAAAgAAA//////////////////////// + ////////////////////////////////////////////////////////////////vensAEGQAAAAAAAA + YgAA2Omx////////////////////////////////vensAEGQAAAAAAAAPAAA2M2Q////////////PI/P + AAAAAAAAAAAAAAAA2K9r////////ounsAABrAAAAAAAAAAAAvY9B////////vensAEGQAAAAAAAAAAAA + 2K9r////////////////////AGqxAAAAAAAAAAAAPAAA2M2Q////////////////ounsAABrAAAAAAAA + 2K9r////////////////////ounsAABrAAAAAAAA2K9r////////ounsAABrAAAAAAAA2K9r//////// + ////////hM3sAABBAAAAAAAA2K9r////////////PI/PAAAAAAAAAAAA2K9r////////////////ouns + AABrAAAAAAAA2K9r////////////////hM3sAABBAAAAAAAA2K9r//////////////////////////// + //////////////////////////////////////////////////////////////////////////////// + ////////////////////////////////gAAAgAAAgAAAgAAA//////////////////////////////// + ////////////gAAAgAAAgAAAwMDA////////////////gAAAgAAAgAAAwMDA//////////////////// + ////////////////////gAAAgAAAgAAAgAAAgAAA//////////////////////////////////////// + ////////////////////////////////////////////////vensAEGQAAAAAAAAYgAA2Omx//////// + ////////////////////////ounsAABrAAAAAAAAvY9B////////////////////PI/PAAAAAAAAAAAA + 2K9r////////ounsAABrAAAAAAAAomoA////////////////ounsAABrAAAAAAAAomoA//////////// + ////hM3sAABBAAAAAAAAAAAAAAAAomoA////////////////ounsAABrAAAAAAAA2K9r//////////// + ////////ounsAABrAAAAAAAA2K9r////////ounsAABrAAAAAAAA2K9r////////////////hM3sAABB + AAAAAAAA2K9r////////////PI/PAAAAAAAAhEEA2OnP////////////////ounsAABrAAAAAAAA2K9r + ////////////////hM3sAABBAAAAAAAA2K9r//////////////////////////////////////////// + //////////////////////////////////////////////////////////////////////////////// + ////////////////gAAAgAAAgAAAgAAA////////////////////////////////////////////gAAA + gAAAgAAAgAAAwMDA////////gAAAgAAAgAAAwMDA//////////////////////////////////////// + ////gAAAgAAAgAAAgAAAgAAA//////////////////////////////////////////////////////// + ////////////////////////////////vensAEGQAAAAAAAAYgAA2Omx//////////////////////// + ////////vensAEGQAAAAAAAAomoA////////////////////hM3sAABBAAAAAAAA2K9r////////ouns + AABrAAAAAAAA2K9r////////////////////AGqxAAAAAAAAYgAA2Omx////////////PI/PAAAAAAAA + YgAAPI+QAAAAYgAA2Omx////////////ounsAABrAAAAAAAA2K9r////////////////////ounsAABr + AAAAAAAA2K9r////////ounsAABrAAAAAAAA2K9r////////////////hM3sAABBAAAAAAAA2K9r//// + ////////PI/PAAAAAAAAhEEA2OnP////////////////ounsAABrAAAAAAAA2K9r//////////////// + hM3sAABBAAAAAAAA2K9r//////////////////////////////////////////////////////////// + //////////////////////////////////////////////////////////////////////////////// + gAAAgAAAgAAAgAAA////////////////////////////////////////////////gAAAgAAAgAAAgAAA + wMDA////gAAAgAAAgAAAwMDA////////////////////////////////////////////gAAAgAAAgAAA + gAAAgAAA//////////////////////////////////////////////////////////////////////// + ////////////////vensAEGQAAAAAAAAYgAA2Omx////////////////////////////////////Yq/s + AAAAAAAAAAAAAAAA2K9r////////////hM3sAABBAAAAAAAA2K9r////////ounsAABrAAAAAAAA2K9r + ////////////////////PI/PAAAAAAAAYgAA2Omx////////vensAEGQAAAAAAAAomoAhM3sAABBAAAA + 2K9r////////////ounsAABrAAAAAAAA2K9r////////////////////ounsAABrAAAAAAAA2K9r//// + ////ounsAABrAAAAAAAA2K9r////////////////hM3sAABBAAAAAAAA2K9r////////////PI/PAAAA + AAAAhEEA2OnP////////////////ounsAABrAAAAAAAA2K9r////////////////hM3sAABBAAAAAAAA + 2K9r//////////////////////////////////////////////////////////////////////////// + ////////////////////////////////////////////////////////////////gAAAgAAAgAAAgAAA + ////////////////////////////////////////////////////gAAAgAAAgAAAgAAAgAAAgAAAgAAA + wMDA////////////////////////////////////////////////gAAAgAAAgAAAgAAAgAAA//////// + //////////////////////////////////////////////////////////////////////////////// + vensAEGQAAAAAAAAYgAA2Omx////////////////////////////////////////hM3sAABBAAAAAAAA + AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA2K9r////////ounsAABrAAAAAAAA2K9r//////////////// + ////Yq/sAAAAAAAAPAAA2M2Q////////hM3sAABBAAAAPAAA2M2QvensAEGQAAAAomoA//////////// + ounsAABrAAAAAAAA2K9r////////////////////ounsAABrAAAAAAAA2K9r////////ounsAABrAAAA + AAAA2K9r////////////////hM3sAABBAAAAAAAA2K9r////////////PI/PAAAAAAAAhEEA2OnP//// + ////////////ounsAABrAAAAAAAA2K9r////////////////hM3sAABBAAAAAAAA2K9r//////////// + //////////////////////////////////////////////////////////////////////////////// + ////////////////////////////////////////////////gAAAgAAAgAAAgAAA//////////////// + ////////////////////////////////////////gAAAgAAAgAAAgAAAgAAAgAAAwMDA//////////// + ////////////////////////////////////gAAAgAAAgAAAgAAAgAAA//////////////////////// + ////////////////////////////////////////////////////////////////vensAEGQAAAAAAAA + YgAA2Omx////////////////////////////////////////////////ounsAABrAAAAAAAAAAAAAAAA + AAAAAAAAAAAAAAAA2K9r////////ounsAABrAAAAAAAA2K9r////////////////////Yq/sAAAAAAAA + PAAA2M2Q////////AGqxAAAAAAAAhEEA2OnP////PI/PAAAAYgAA2Omx////////ounsAABrAAAAAAAA + vY9B////////////////////ounsAABrAAAAAAAA2K9r////////ounsAABrAAAAAAAAvY9B//////// + ////////hM3sAABBAAAAAAAA2K9r////////////PI/PAAAAAAAAhEEA2OnP////////////////ouns + AABrAAAAAAAAvY9B////////////////hM3sAABBAAAAAAAA2K9r//////////////////////////// + //////////////////////////////////////////////////////////////////////////////// + ////////////////////////////////gAAAgAAAgAAAgAAA//////////////////////////////// + ////////////////////////////////gAAAgAAAgAAAgAAAwMDA//////////////////////////// + ////////////////////gAAAgAAAgAAAgAAAgAAA//////////////////////////////////////// + ////////////////////////////////////////////////vensAEGQAAAAAAAAYgAA2Omx//////// + ////////////////////////////////////////////////////////////////hM3sAABBAAAAAAAA + 2K9r////////ounsAABrAAAAAAAAvY9B////////////////////PI/PAAAAAAAAYgAA2Omx////ouns + AABrAAAAAAAAvY9B////////hM3sAABBAAAA2K9r////////ounsAABrAAAAAAAAhEEA2OnP//////// + ////////ounsAABrAAAAAAAA2K9r////////ounsAABrAAAAAAAAomoA////////////////hM3sAABB + AAAAPAAA2M2Q////////////PI/PAAAAAAAAhEEA2OnP////////////////ounsAABrAAAAAAAAomoA + ////////////////hM3sAABBAAAAAAAA2K9r//////////////////////////////////////////// + //////////////////////////////////////////////////////////////////////////////// + ////////////////gAAAgAAAgAAAgAAA//////////////////////////////////////////////// + ////////////////gAAAgAAAgAAAwMDA//////////////////////////////////////////////// + ////gAAAgAAAgAAAgAAAgAAA//////////////////////////////////////////////////////// + ////////////////////////////////vensAEGQAAAAAAAAYgAA2Omx//////////////////////// + ////////////PI/PAAAAAAAAvY9B////////////////////hM3sAABBAAAAPAAA2M2Q////////ouns + AABrAAAAAAAAYgAA2Omx////////////ounsAABrAAAAAAAAhEEA2OnP////Yq/sAAAAAAAAPAAA2M2Q + ////////vensAEGQAAAAomoA////////ounsAABrAAAAAAAAAAAA2K9r////////////////ounsAABr + AAAAAAAA2K9r////////ounsAABrAAAAAAAAYgAA2Omx////////////Yq/sAAAAAAAAPAAA2M2Q//// + ////////PI/PAAAAAAAAhEEA2OnP////////////////ounsAABrAAAAAAAAYgAA2Omx//////////// + Yq/sAAAAAAAAPAAA2M2Q//////////////////////////////////////////////////////////// + //////////////////////////////////////////////////////////////////////////////// + gAAAgAAAgAAAgAAA////////////////////////////////////////////////////////////gAAA + gAAAgAAAgAAAwMDA////////////////////////////////////////////////////gAAAgAAAgAAA + gAAAgAAA//////////////////////////////////////////////////////////////////////// + ////////////////vensAEGQAAAAAAAAYgAA2Omx////////////////////////////////////hM3s + AABBAAAAAAAA2K9r////////////ounsAABrAAAAAAAAPAAA2M2Q////////ounsAABrAAAAAAAAAAAA + hEEA2OnP////vensAEGQAAAAAAAAAAAAvY9B////////AGqxAAAAAAAAhEEA2OnP////////////PI/P + AAAAYgAA2Omx////ounsAABrAAAAPAAAAEFBAAAA2K9r////////////ounsAABrAAAAAAAA2K9r//// + ////ounsAABrAAAAAAAAAAAAYgAA2Omx////ounsAABrAAAAAAAAYgAA2Omx////////////PI/PAAAA + AAAAhEEA2OnP////////////////ounsAABrAAAAAAAAAAAAYgAA2Omx////vensAEGQAAAAAAAAPAAA + 2M2Q//////////////////////////////////////////////////////////////////////////// + ////////////////////////////////////////////////////////////////gAAAgAAAgAAAgAAA + ////////////////////////////////////////////////////////////gAAAgAAAgAAAwMDA//// + ////////////////////////////////////////////////////gAAAgAAAgAAAgAAAgAAA//////// + //////////////////////////////////////////////////////////////////////////////// + vensAEGQAAAAAAAAYgAA2Omx////////////////////////////////////////AGqxAAAAAAAAAAAA + AAAAAAAAAAAAAAAAAAAAAAAAAAAAhEEA2OnP////////ounsAABrAAAAAAAAPEFBAAAAAAAAAAAAAAAA + AAAAAAAAAAAAYgAA2Omx////hM3sAABBAAAAAAAA2K9r////////////////hM3sAABBAAAAvY9B//// + ounsAABrAAAAYgAAYq+xAAAAAAAAAAAAvY9B////ounsAABrAAAAAAAA2K9r////////ounsAABrAAAA + YgAAPI+QAAAAAAAAAAAAAAAAAAAAAAAAAAAAhEEA2OnP////PI/PAAAAAAAAAAAAAAAAAAAAAAAAAAAA + omoA////////ounsAABrAAAAAAAAYmprAAAAAAAAAAAAAAAAAAAAAAAAAAAAhEEA2OnP//////////// + //////////////////////////////////////////////////////////////////////////////// + ////////////////////////////////////////////////gAAAgAAAgAAAgAAA//////////////// + ////////////////////////////////////////////gAAAgAAAgAAAwMDA//////////////////// + ////////////////////////////////////gAAAgAAAgAAAgAAAgAAA//////////////////////// + ////////////////////////////////////////////////////////////////vensAEGQAAAAAAAA + YgAA2Omx////////////////////////////////////////vensAEGQAAAAAAAAAAAAAAAAAAAAAAAA + AAAAAAAAPAAA2M2Q////////////ounsAABrAAAAAAAAva9rAEGQAAAAAAAAAAAAAAAAAAAAPAAA2M2Q + ////////PI/PAAAAAAAAYgAA2Omx////////////////vensAEGQAAAAhEEA2OnPounsAABrAAAAYgAA + 2OmxAGqxAAAAAAAAvY9B////ounsAABrAAAAAAAA2K9r////////ounsAABrAAAAYgAA2OmxAGqxAAAA + AAAAAAAAAAAAAAAAPAAA2M2Q////////PI/PAAAAAAAAAAAAAAAAAAAAAAAAAAAAomoA////////ouns + AABrAAAAAAAA2K9rAGqxAAAAAAAAAAAAAAAAAAAAAAAA2K9r//////////////////////////////// + //////////////////////////////////////////////////////////////////////////////// + ////////////////////////////////gAAAgAAAgAAAgAAA//////////////////////////////// + ////////////////////////gAAAgAAAgAAAgAAAwMDA//////////////////////////////////// + ////////////////////gAAAgAAAgAAAgAAAgAAA//////////////////////////////////////// + ////////////////////////////////////////////////vensAEGQAAAAAAAAYgAA2Omx//////// + ////////////////////////////////////////ounsAABrAAAAAAAAAAAAAAAAAAAAomoA//////// + ////////////ounsAABrAAAAAAAA2K9r////AGqxAAAAAAAAAAAAhEEA2OnP////////vensAEGQAAAA + AAAAomoA////////////////////////PI/PAAAAPAAA2M2QounsAABrAAAAYgAA2Omx////PI/PAAAA + vY9B////ounsAABrAAAAAAAA2K9r////////ounsAABrAAAAYgAA2Omx////PI/PAAAAAAAAAAAAhEEA + 2OnP////////////PI/PAAAAAAAAAAAAAAAAAAAAAAAAAAAAomoA////////ounsAABrAAAAAAAA2K9r + ////PI/PAAAAAAAAAAAAPAAA2M2Q//////////////////////////////////////////////////// + //////////////////////////////////////////////////////////////////////////////// + ////////////////gAAAgAAAgAAAgAAA//////////////////////////////////////////////// + ////////gAAAgAAAgAAAwMDA//////////////////////////////////////////////////////// + ////gAAAgAAAgAAAgAAAgAAA//////////////////////////////////////////////////////// + ////////////////////////////////vensAEGQAAAAAAAAYgAA2Omx//////////////////////// + ////////////////////////////////////////////////////////////////////////////ouns + AABrAAAAAAAA2K9r//////////////////////////////////////////////////////////////// + //////////////////////////////////////////////////////////////////////////////// + //////////////////////////////////////////////////////////////////////////////// + ////////Yq/sAAAAAAAAhEEA2OnP////////////////ounsAABrAAAAAAAA2K9r//////////////// + //////////////////////////////////////////////////////////////////////////////// + //////////////////////////////////////////////////////////////////////////////// + gAAAgAAAgAAAgAAA////////////////////////////////////////////////////gAAAgAAAgAAA + gAAAwMDA////////////////////////////////////////////////////////////gAAAgAAAgAAA + gAAAgAAA//////////////////////////////////////////////////////////////////////// + ////////////////vensAEGQAAAAAAAAYgAA2Omx//////////////////////////////////////// + ////////////////////////////////////////////////////////////ounsAABrAAAAAAAA2K9r + //////////////////////////////////////////////////////////////////////////////// + //////////////////////////////////////////////////////////////////////////////// + ////////////////////////////////////////////////////////////////////////Yq/sAAAA + AAAAhEEA2OnP////////////////ounsAABrAAAAAAAA2K9r//////////////////////////////// + //////////////////////////////////////////////////////////////////////////////// + ////////////////////////////////////////////////////////////////gAAAgAAAgAAAgAAA + ////////////////////////////////////////////////gAAAgAAAgAAAgAAAwMDA//////////// + ////////////////////////////////////////////////////gAAAgAAAgAAAgAAAgAAA//////// + //////////////////////////////////////////////////////////////////////////////// + vensAEGQAAAAAAAAYgAA2Omx//////////////////////////////////////////////////////// + ////////////////////////////////////////////ounsAABrAAAAAAAA2K9r//////////////// + //////////////////////////////////////////////////////////////////////////////// + ////////////////////////////////////////ounsAABrAAAAAAAA2K9r//////////////////// + ////////////////////////////////////////////////////////hM3sAABBAAAAhEEA2OnP//// + ////////////ounsAABrAAAAAAAA2K9r//////////////////////////////////////////////// + //////////////////////////////////////////////////////////////////////////////// + ////////////////////////////////////////////////gAAAgAAAgAAAgAAA//////////////// + ////////////////gAAAgAAAgAAAgAAAgAAAgAAAgAAAwMDA//////////////////////////////// + ////////////////////////////////////gAAAgAAAgAAAgAAAgAAA//////////////////////// + ////////////////////////////////////////////////////////////////vensAEGQAAAAAAAA + YgAA2Omx//////////////////////////////////////////////////////////////////////// + ////////////////////////////ounsAABrAAAAAAAA2K9r//////////////////////////////// + //////////////////////////////////////////////////////////////////////////////// + ////////////////////////ounsAABrAAAAAAAA2K9r//////////////////////////////////// + ////////////////////////////////////////hM3sAABBAAAAhEEA2OnP////////////////ouns + AABrAAAAAAAA2K9r//////////////////////////////////////////////////////////////// + //////////////////////////////////////////////////////////////////////////////// + ////////////////////////////////gAAAgAAAgAAAgAAA//////////////////////////////// + gAAAgAAAgAAAgAAAgAAAgAAAwMDA//////////////////////////////////////////////////// + ////////////////////gAAAgAAAgAAAgAAAgAAA//////////////////////////////////////// + ////////////////////////////////////////////////vensAEGQAAAAAAAAYgAA2Omx//////// + //////////////////////////////////////////////////////////////////////////////// + ////////////ounsAABrAAAAAAAA2K9r//////////////////////////////////////////////// + //////////////////////////////////////////////////////////////////////////////// + ////////ounsAABrAAAAAAAA2K9r//////////////////////////////////////////////////// + ////////////////////////////////////////////////////////////ounsAABrAAAAAAAA2K9r + //////////////////////////////////////////////////////////////////////////////// + //////////////////////////////////////////////////////////////////////////////// + ////////////////gAAAgAAAgAAAgAAA////////////////////////////////////gAAAgAAAgAAA + wMDA//////////////////////////////////////////////////////////////////////////// + ////gAAAgAAAgAAAgAAAgAAA//////////////////////////////////////////////////////// + //////////////////////////////////////////////////////////////////////////////// + //////////////////////////////////////////////////////////////////////////////// + //////////////////////////////////////////////////////////////////////////////// + //////////////////////////////////////////////////////////////////////////////// + //////////////////////////////////////////////////////////////////////////////// + //////////////////////////////////////////////////////////////////////////////// + //////////////////////////////////////////////////////////////////////////////// + //////////////////////////////////////////////////////////////////////////////// + gAAAgAAAgAAAgAAA//////////////////////////////////////////////////////////////// + ////////////////////////////////////////////////////////////////////gAAAgAAAgAAA + gAAAgAAA//////////////////////////////////////////////////////////////////////// + //////////////////////////////////////////////////////////////////////////////// + //////////////////////////////////////////////////////////////////////////////// + //////////////////////////////////////////////////////////////////////////////// + //////////////////////////////////////////////////////////////////////////////// + //////////////////////////////////////////////////////////////////////////////// + //////////////////////////////////////////////////////////////////////////////// + //////////////////////////////////////////////////////////////////////////////// + ////////////////////////////////////////////////////////////////gAAAgAAAgAAAgAAA + //////////////////////////////////////////////////////////////////////////////// + ////////////////////////////////////////////////////gAAAgAAAgAAAgAAAgAAA//////// + //////////////////////////////////////////////////////////////////////////////// + //////////////////////////////////////////////////////////////////////////////// + //////////////////////////////////////////////////////////////////////////////// + //////////////////////////////////////////////////////////////////////////////// + //////////////////////////////////////////////////////////////////////////////// + //////////////////////////////////////////////////////////////////////////////// + //////////////////////////////////////////////////////////////////////////////// + //////////////////////////////////////////////////////////////////////////////// + ////////////////////////////////////////////////gAAAgAAAgAAAgAAA//////////////// + //////////////////////////////////////////////////////////////////////////////// + ////////////////////////////////////gAAAgAAAgAAAgAAAgAAA//////////////////////// + //////////////////////////////////////////////////////////////////////////////// + //////////////////////////////////////////////////////////////////////////////// + //////////////////////////////////////////////////////////////////////////////// + //////////////////////////////////////////////////////////////////////////////// + //////////////////////////////////////////////////////////////////////////////// + //////////////////////////////////////////////////////////////////////////////// + //////////////////////////////////////////////////////////////////////////////// + //////////////////////////////////////////////////////////////////////////////// + ////////////////////////////////gAAAgAAAgAAAgAAA//////////////////////////////// + //////////////////////////////////////////////////////////////////////////////// + ////////////////////gAAAgAAAgAAAgAAAgAAA//////////////////////////////////////// + //////////////////////////////////////////////////////////////////////////////// + //////////////////////////////////////////////////////////////////////////////// + //////////////////////////////////////////////////////////////////////////////// + //////////////////////////////////////////////////////////////////////////////// + //////////////////////////////////////////////////////////////////////////////// + //////////////////////////////////////////////////////////////////////////////// + //////////////////////////////////////////////////////////////////////////////// + //////////////////////////////////////////////////////////////////////////////// + ////////////////gAAAgAAAgAAAgAAA//////////////////////////////////////////////// + //////////////////////////////////////////////////////////////////////////////// + ////gAAAgAAAgAAAgAAAgAAA//////////////////////////////////////////////////////// + //////////////////////////////////////////////////////////////////////////////// + //////////////////////////////////////////////////////////////////////////////// + //////////////////////////////////////////////////////////////////////////////// + //////////////////////////////////////////////////////////////////////////////// + //////////////////////////////////////////////////////////////////////////////// + //////////////////////////////////////////////////////////////////////////////// + //////////////////////////////////////////////////////////////////////////////// + //////////////////////////////////////////////////////////////////////////////// + gAAAgAAAgAAAgAAAgAAAgAAAgAAAgAAAgAAAgAAAgAAAgAAAgAAAgAAAgAAAgAAAgAAAgAAAgAAAgAAA + gAAAgAAAgAAAgAAAgAAAgAAAgAAAgAAAgAAAgAAAgAAAgAAAgAAAgAAAgAAAgAAAgAAAgAAAgAAAgAAA + gAAAgAAA//////////////////////////////////////////////////////////////////////// + //////////////////////////////////////////////////////////////////////////////// + //////////////////////////////////////////////////////////////////////////////// + //////////////////////////////////////////////////////////////////////////////// + //////////////////////////////////////////////////////////////////////////////// + //////////////////////////////////////////////////////////////////////////////// + //////////////////////////////////////////////////////////////////////////////// + //////////////////////////////////////////////////////////////////////////////// + ////////////////////////////////////////////////////////////////gAAAgAAAgAAAgAAA + gAAAgAAAgAAAgAAAgAAAgAAAgAAAgAAAgAAAgAAAgAAAgAAAgAAAgAAAgAAAgAAAgAAAgAAAgAAAgAAA + gAAAgAAAgAAAgAAAgAAAgAAAgAAAgAAAgAAAgAAAgAAAgAAAgAAAgAAAgAAAgAAAgAAAgAAA//////// + //////////////////////////////////////////////////////////////////////////////// + //////////////////////////////////////////////////////////////////////////////// + //////////////////////////////////////////////////////////////////////////////// + //////////////////////////////////////////////////////////////////////////////// + //////////////////////////////////////////////////////////////////////////////// + //////////////////////////////////////////////////////////////////////////////// + //////////////////////////////////////////////////////////////////////////////// + //////////////////////////////////////////////////////////////////////////////// + ////////////////////////////////////////////////gAAAgAAAgAAAgAAAgAAAgAAAgAAAgAAA + gAAAgAAAgAAAgAAAgAAAgAAAgAAAgAAAgAAAgAAAgAAAgAAAgAAAgAAAgAAAgAAAgAAAgAAAgAAAgAAA + gAAAgAAAgAAAgAAAgAAAgAAAgAAAgAAAgAAAgAAAgAAAgAAAgAAAgAAA//////////////////////// + //////////////////////////////////////////////////////////////////////////////// + //////////////////////////////////////////////////////////////////////////////// + //////////////////////////////////////////////////////////////////////////////// + //////////////////////////////////////////////////////////////////////////////// + //////////////////////////////////////////////////////////////////////////////// + //////////////////////////////////////////////////////////////////////////////// + //////////////////////////////////////////////////////////////////////////////// + //////////////////////////////////////////////////////////////////////////////// + ////////////////////////////////gAAAgAAAgAAAgAAAgAAAgAAAgAAAgAAAgAAAgAAAgAAAgAAA + gAAAgAAAgAAAgAAAgAAAgAAAgAAAgAAAgAAAgAAAgAAAgAAAgAAAgAAAgAAAgAAAgAAAgAAAgAAAgAAA + gAAAgAAAgAAAgAAAgAAAgAAAgAAAgAAAgAAAgAAA//////////////////////////////////////// + //////////////////////////////////////////////////////////////////////////////// + //////////////////////////////////////////////////////////////////////////////// + //////////////////////////////////////////////////////////////////////////////// + //////////////////////////////////////////////////////////////////////////////// + //////////////////////////////////////////////////////////////////////////////// + //////////////////////////////////////////////////////////////////////////////// + //////////////////////////////////////////////////////////////////////////////// + //////////////////////////////////////////////////////////////////////////////// + //////////////////////////////////////////////////////////////////////////////// + //////////////////////////////////////////////////////////////////////////////// + //////////////////////////////////////////////////////////////////////////////// + //////////////////////////////////////////////////////////////////////////////// + //////////////////////////////////////////////////////////////////////////////// + //////////////////////////////////////////////////////////////////////////////// + //////////////////////////////////////////////////////////////////////////////// + //////////////////////////////////////////////////////////////////////////////// + //////////////////////////////////////////////////////////////////////////////// + //////////////////////////////////////////////////////////////////////////////// + //////////////////////////////////////////////////////////////////////////////// + //////////////////////////////////////////////////////////////////////////////// + //////////////////////////////////////////////////////////////////////////////// + //////////////////////////////////////////////////////////////////////////////// + //////////////////////////////////////////////////////////////////////////////// + //////////////////////////////////////////////////////////////////////////////// + //////////////////////////////////////////////////////////////////////////////// + //////////////////////////////////////////////////////////////////////////////// + //////////////////////////////////////////////////////////////////////////////// + //////////////////////////////////////////////////////////////////////////////// + //////////////////////////////////////////////////////////////////////////////// + //////////////////////////////////////////////////////////////////////////////// + //////////////////////////////////////////////////////////////////////////////// + //////////////////////////////////////////////////////////////////////////////// + //////////////////////////////////////////////////////////////////////////////// + //////////////////////////////////////////////////////////////////////////////// + //////////////////////////////////////////////////////////////////////////////// + //////////////////////////////////////////////////////////////////////////////// + //////////////////////////////////////////////////////////////////////////////// + //////////////////////////////////////////////////////////////////////////////// + //////////////////////////////////////////////////////////////////////////////// + //////////////////////////////////////////////////////////////////////////////// + //////////////////////////////////////////////////////////////////////////////// + //////////////////////////////////////////////////////////////////////////////// + //////////////////////////////////////////////////////////////////////////////// + //////////////////////////////////////////////////////////////////////////////// + //////////////////////////////////////////////////////////////////////////////// + //////////////////////////////////////////////////////////////////////////////// + //////////////////////////////////////////////////////////////////////////////// + //////////////////////////////////////////////////////////////////////////////// + //////////////////////////////////////////////////////////////////////////////// + //////////////////////////////////////////////////////////////////////////////// + //////////////////////////////////////////////////////////////////////////////// + //////////////////////////////////////////////////////////////////////////////// + //////////////////////////////////////////////////////////////////////////////// + //////////////////////////////////////////////////////////////////////////////// + //////////////////////////////////////////////////////////////////////////////// + //////////////////////////////////////////////////////////////////////////////// + //////////////////////////////////////////////////////////////////////////////// + //////////////////////////////////////////////////////////////////////////////// + //////////////////////////////////////////////////////////////////////////////// + //////////////////////////////////////////////////////////////////////////////// + //////////////////////////////////////////////////////////////////////////////// + //////////////////////////////////////////////////////////////////////////////// + //////////////////////////////////////////////////////////////////////////////// + //////////////////////////////////////////////////////////////////////////////// + //////////////////////////////////////////////////////////////////////////////// + //////////////////////////////////////////////////////////////////////////////// + //////////////////////////////////////////////////////////////////////////////// + //////////////////////////////////////////////////////////////////////////////// + //////////////////////////////////////////////////////////////////////////////// + //////////////////////////////////////////////////////////////////////////////// + //////////////////////////////////////////////////////////////////////////////// + //////////////////////////////////////////////////////////////////////////////// + //////////////////////////////////////////////////////////////////////////////// + //////////////////////////////////////////////////////////////////////////////// + //////////////////////////////////////////////////////////////////////////////// + //////////////////////////////////////////////////////////////////////////////// + //////////////////////////////////////////////////////////////////////////////// + //////////////////////////////////////////////////////////////////////////////// + //////////////////////////////////////////////////////////////////////////////// + //////////////////////////////////////////////////////////////////////////////// + //////////////////////////////////////////////////////////////////////////////// + //////////////////////////////////////////////////////////////////////////////// + //////////////////////////////////////////////////////////////////////////////// + //////////////////////////////////////////////////////////////////////////////// + //////////////////////////////////////////////////////////////////////////////// + //////////////////////////////////////////////////////////////////////////////// + //////////////////////////////////////////////////////////////////////////////// + //////////////////////////////////////////////////////////////////////////////// + //////////////////////////////////////////////////////////////////////////////// + //////////////////////////////////////////////////////////////////////////////// + //////////////////////////////////////////////////////////////////////////////// + //////////////////////////////////////////////////////////////////////////////// + //////////////////////////////////////////////////////////////////////////////// + //////////////////////////////////////////////////////////////////////////////// + //////// + + + \ No newline at end of file diff --git a/Labyrinth3/IDE/Forms/AddInDlg.cs b/Labyrinth3/IDE/Forms/AddInDlg.cs new file mode 100644 index 0000000..7cad0d6 --- /dev/null +++ b/Labyrinth3/IDE/Forms/AddInDlg.cs @@ -0,0 +1,238 @@ +// Decompiled with JetBrains decompiler +// Type: Labyrinth.Forms.AddInDlg +// Assembly: Labyrinth, Version=3.6.1928.15690, Culture=neutral, PublicKeyToken=null +// MVID: 1462002E-0BD1-49D2-9B56-C22E66C903E7 +// Assembly location: C:\Dropbox\Workspace\Programs\Labyrinth\Labyrinth.exe + +using Labyrinth.Extensibility; +using System; +using System.Collections; +using System.ComponentModel; +using System.Drawing; +using System.Reflection; +using System.Resources; +using System.Windows.Forms; + +namespace Labyrinth.Forms +{ + public class AddInDlg : Form + { + private Button OKBn; + private TabControl Tabs; + private TabPage DescPage; + private TabPage CompPage; + private RichTextBox DescBox; + private ListView CompList; + private ColumnHeader ComponentHdr; + private ColumnHeader TypeHdr; + private ColumnHeader DescHdr; + private ImageList Images; + private ColumnHeader NameHdr; + private ColumnHeader VersionHdr; + private ColumnHeader FileHdr; + private ListView AddInList; + private IContainer components; + + public AddInDlg(AddInManager addins) + { + this.InitializeComponent(); + this.AddInList.ListViewItemSorter = (IComparer)new ListViewSorter(); + this.CompList.ListViewItemSorter = (IComparer)new ListViewSorter(); + foreach (IAddIn addIn in addins.AddIns) + { + Assembly assembly = Assembly.GetAssembly(addIn.GetType()); + ListViewItem listViewItem = this.AddInList.Items.Add(addIn.Name); + listViewItem.SubItems.Add(assembly.GetName().Version.ToString()); + listViewItem.SubItems.Add(assembly.Location); + listViewItem.ImageIndex = 0; + listViewItem.Tag = (object)addIn; + } + this.AddInList.Items[0].Selected = true; + } + + protected override void Dispose(bool disposing) + { + if (disposing && this.components != null) + this.components.Dispose(); + base.Dispose(disposing); + } + + private void InitializeComponent() + { + this.components = (IContainer)new Container(); + ResourceManager resourceManager = new ResourceManager(typeof(AddInDlg)); + this.OKBn = new Button(); + this.Tabs = new TabControl(); + this.DescPage = new TabPage(); + this.DescBox = new RichTextBox(); + this.CompPage = new TabPage(); + this.CompList = new ListView(); + this.ComponentHdr = new ColumnHeader(); + this.TypeHdr = new ColumnHeader(); + this.DescHdr = new ColumnHeader(); + this.Images = new ImageList(this.components); + this.AddInList = new ListView(); + this.NameHdr = new ColumnHeader(); + this.VersionHdr = new ColumnHeader(); + this.FileHdr = new ColumnHeader(); + this.Tabs.SuspendLayout(); + this.DescPage.SuspendLayout(); + this.CompPage.SuspendLayout(); + this.SuspendLayout(); + this.OKBn.Anchor = AnchorStyles.Bottom | AnchorStyles.Right; + this.OKBn.DialogResult = DialogResult.OK; + this.OKBn.Location = new Point(382, 326); + this.OKBn.Name = "OKBn"; + this.OKBn.TabIndex = 7; + this.OKBn.Text = "OK"; + this.Tabs.Anchor = AnchorStyles.Top | AnchorStyles.Bottom | AnchorStyles.Left | AnchorStyles.Right; + this.Tabs.Controls.AddRange(new Control[2] + { + (Control) this.DescPage, + (Control) this.CompPage + }); + this.Tabs.Location = new Point(16, 152); + this.Tabs.Name = "Tabs"; + this.Tabs.SelectedIndex = 0; + this.Tabs.Size = new Size(438, 152); + this.Tabs.TabIndex = 9; + this.DescPage.Controls.AddRange(new Control[1] + { + (Control) this.DescBox + }); + ((Control)this.DescPage).Location = new Point(4, 22); + this.DescPage.Name = "DescPage"; + this.DescPage.Size = new Size(430, 126); + this.DescPage.TabIndex = 0; + this.DescPage.Text = "Description"; + this.DescBox.AcceptsTab = true; + this.DescBox.Dock = DockStyle.Fill; + this.DescBox.Name = "DescBox"; + this.DescBox.ReadOnly = true; + this.DescBox.Size = new Size(430, 126); + this.DescBox.TabIndex = 9; + this.DescBox.Text = ""; + this.CompPage.Controls.AddRange(new Control[1] + { + (Control) this.CompList + }); + ((Control)this.CompPage).Location = new Point(4, 22); + this.CompPage.Name = "CompPage"; + this.CompPage.Size = new Size(430, 126); + this.CompPage.TabIndex = 1; + this.CompPage.Text = "Components"; + this.CompList.Columns.AddRange(new ColumnHeader[3] + { + this.ComponentHdr, + this.TypeHdr, + this.DescHdr + }); + this.CompList.Dock = DockStyle.Fill; + this.CompList.FullRowSelect = true; + this.CompList.Name = "CompList"; + this.CompList.Size = new Size(430, 126); + this.CompList.SmallImageList = this.Images; + this.CompList.TabIndex = 0; + this.CompList.View = View.Details; + this.CompList.ColumnClick += new ColumnClickEventHandler(this.CompList_ColumnClick); + this.ComponentHdr.Text = "Component"; + this.ComponentHdr.Width = 120; + this.TypeHdr.Text = "Type"; + this.TypeHdr.Width = 90; + this.DescHdr.Text = "Description"; + this.DescHdr.Width = 150; + this.Images.ColorDepth = ColorDepth.Depth8Bit; + this.Images.ImageSize = new Size(16, 16); + this.Images.ImageStream = (ImageListStreamer)resourceManager.GetObject("Images.ImageStream"); + this.Images.TransparentColor = Color.Magenta; + this.AddInList.Anchor = AnchorStyles.Bottom | AnchorStyles.Left | AnchorStyles.Right; + this.AddInList.Columns.AddRange(new ColumnHeader[3] + { + this.NameHdr, + this.VersionHdr, + this.FileHdr + }); + this.AddInList.FullRowSelect = true; + this.AddInList.HideSelection = false; + this.AddInList.Location = new Point(16, 16); + this.AddInList.Name = "AddInList"; + this.AddInList.Size = new Size(440, 120); + this.AddInList.SmallImageList = this.Images; + this.AddInList.TabIndex = 10; + this.AddInList.View = View.Details; + this.AddInList.ColumnClick += new ColumnClickEventHandler(this.AddInList_ColumnClick); + this.AddInList.SelectedIndexChanged += new EventHandler(this.AddInList_SelectedIndexChanged); + this.NameHdr.Text = "Add-In"; + this.NameHdr.Width = 120; + this.VersionHdr.Text = "Version"; + this.VersionHdr.Width = 120; + this.FileHdr.Text = "Filename"; + this.FileHdr.Width = 150; + this.AcceptButton = (IButtonControl)this.OKBn; + this.AutoScaleBaseSize = new Size(5, 14); + this.ClientSize = new Size(472, 366); + this.Controls.AddRange(new Control[3] + { + (Control) this.AddInList, + (Control) this.Tabs, + (Control) this.OKBn + }); + this.Font = new Font("Tahoma", 11f, FontStyle.Regular, GraphicsUnit.World); + this.Icon = (Icon)resourceManager.GetObject("$this.Icon"); + this.MaximizeBox = false; + this.MinimizeBox = false; + this.Name = nameof(AddInDlg); + this.ShowInTaskbar = false; + this.StartPosition = FormStartPosition.CenterParent; + this.Text = "Add-In Manager"; + this.Tabs.ResumeLayout(false); + this.DescPage.ResumeLayout(false); + this.CompPage.ResumeLayout(false); + this.ResumeLayout(false); + } + + public IAddIn SelectedAddIn + { + get + { + if (this.AddInList.SelectedItems.Count != 0) + return this.AddInList.SelectedItems[0].Tag as IAddIn; + return (IAddIn)null; + } + } + + private void AddInList_ColumnClick(object sender, ColumnClickEventArgs e) + { + ListViewSorter.Sort(this.AddInList, e.Column); + } + + private void CompList_ColumnClick(object sender, ColumnClickEventArgs e) + { + ListViewSorter.Sort(this.CompList, e.Column); + } + + private void AddInList_SelectedIndexChanged(object sender, EventArgs e) + { + this.DescBox.Clear(); + this.CompList.Items.Clear(); + if (this.SelectedAddIn == null) + return; + this.DescBox.Text = this.SelectedAddIn.Description; + foreach (IAddInComponent component in this.SelectedAddIn.Components) + { + string text = ""; + if (component is ICommand) + text = "Command"; + else if (component is IExplorerPage) + text = "Explorer page"; + else if (component is ICustomSearch) + text = "Custom search"; + ListViewItem listViewItem = this.CompList.Items.Add(component.Name); + listViewItem.SubItems.Add(text); + listViewItem.SubItems.Add(component.Description); + listViewItem.ImageIndex = 0; + listViewItem.Tag = (object)component; + } + } + } +} \ No newline at end of file diff --git a/Labyrinth3/IDE/Forms/AddInDlg.resx b/Labyrinth3/IDE/Forms/AddInDlg.resx new file mode 100644 index 0000000..fc407c2 --- /dev/null +++ b/Labyrinth3/IDE/Forms/AddInDlg.resx @@ -0,0 +1,217 @@ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + text/microsoft-resx + + + 2.0 + + + System.Resources.ResXResourceReader, System.Windows.Forms, Version=4.0.0.0, Culture=neutral, PublicKeyToken=b77a5c561934e089 + + + System.Resources.ResXResourceWriter, System.Windows.Forms, Version=4.0.0.0, Culture=neutral, PublicKeyToken=b77a5c561934e089 + + + + + AAABAAMAICAQAAAAAADoAgAANgAAABAQEAAAAAAAKAEAAB4DAAAwMBAAAAAAAGgGAABGBAAAKAAAACAA + AABAAAAAAQAEAAAAAAAAAgAAAAAAAAAAAAAQAAAAEAAAAAAAAAAAAIAAAIAAAACAgACAAAAAgACAAICA + AACAgIAAwMDAAAAA/wAA/wAAAP//AP8AAAD/AP8A//8AAP///wAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA + AAAAAAAAAAAAAABERERERERERERERERERAAAREREREREREREREREREQAAEREREREREREREREREREAABE + T//////////////0RAAARE//////////////9EQAAERP//////////////REAABET///RI////9Ej//0 + RAAARE///0SP///0RI//9EQAAERP//9ESP//REj///REAABET///9Ej//0SP///0RAAARE////REj/RE + j///9EQAAERP////REj0SP////REAABET/////REREj////0RAAARE//////RESP////9EQAAERP//// + //REj/////REAABET//////0SP/////0RAAARE//////9Ej/////9EQAAERP/////0RI//////REAABE + T/////9Ej//////0RAAARE/////0RI//////9EQAAERP//9EREj///////REAABET///9ESP///////0 + RAAARE//////////////9EQAAERP//////////////REAABET//////////////0RAAARERERERERERE + REREREQAAEREREREREREREREREREAABERERERERERERERERERAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA + AAAAAAAAAAAAAP//////////wAAAA8AAAAPAAAADwAAAA8AAAAPAAAADwAAAA8AAAAPAAAADwAAAA8AA + AAPAAAADwAAAA8AAAAPAAAADwAAAA8AAAAPAAAADwAAAA8AAAAPAAAADwAAAA8AAAAPAAAADwAAAA8AA + AAPAAAADwAAAA///////////KAAAABAAAAAgAAAAAQAEAAAAAACAAAAAAAAAAAAAAAAQAAAAEAAAAAAA + AAAAAIAAAIAAAACAgACAAAAAgACAAICAAACAgIAAwMDAAAAA/wAA/wAAAP//AP8AAAD/AP8A//8AAP// + /wD///////////RERERERERP9ERERERERE/0T//////0T/RP9I//SPRP9E/0SPRI9E/0T/9EhI/0T/RP + //REj/RP9E///0j/9E/0T//0SP/0T/RP9ESP//RP9E//SP//9E/0T//////0T/RERERERERP9ERERERE + RE///////////wAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA + AAAAAAAAAAAAAAAAAAAoAAAAMAAAAGAAAAABAAQAAAAAAIAEAAAAAAAAAAAAABAAAAAQAAAAAAAAAAAA + gAAAgAAAAICAAIAAAACAAIAAgIAAAMDAwACAgIAAAAD/AAD/AAAA//8A/wAAAP8A/wD//wAA////AAAA + AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA + AAAAAAAAAAAAAAAERERERERERERERERERERERERERERAAAAERERERERERERERERERERERERERERAAAAE + RERERERERERERERERERERERERERAAAAERERERERERERERERERERERERERERAAAAERERERERERERERERE + RERERERERERAAAAERE//////////////////////RERAAAAERE//////////////////////RERAAAAE + RE//////////////////////RERAAAAERE//////////////////////RERAAAAERE/////0RH////// + /0RH////RERAAAAERE/////0RH//////9ERH////RERAAAAERE/////0RH//////RER/////RERAAAAE + RE//////REf////0REf/////RERAAAAERE//////REf////0RH//////RERAAAAERE//////9ER///9E + RH//////RERAAAAERE//////9ERH//9ER///////RERAAAAERE///////0RH//9ER///////RERAAAAE + RE///////0REf/REf///////RERAAAAERE////////RER/REf///////RERAAAAERE////////9ERERH + ////////RERAAAAERE/////////0RERH////////RERAAAAERE//////////9ERH////////RERAAAAE + RE//////////9ER/////////RERAAAAERE//////////RER/////////RERAAAAERE//////////REf/ + ////////RERAAAAERE//////////REf/////////RERAAAAERE/////////0REf/////////RERAAAAE + RE/////////0RH//////////RERAAAAERE////////9ERH//////////RERAAAAERE////////RER/// + ////////RERAAAAERE/////0REREf///////////RERAAAAERE/////0RERH////////////RERAAAAE + RE//////REf/////////////RERAAAAERE//////////////////////RERAAAAERE////////////// + ////////RERAAAAERE//////////////////////RERAAAAERE//////////////////////RERAAAAE + RE//////////////////////RERAAAAERERERERERERERERERERERERERERAAAAERERERERERERERERE + RERERERERERAAAAERERERERERERERERERERERERERERAAAAERERERERERERERERERERERERERERAAAAA + AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA + AAAAAAAAAAAAAP///////wAA////////AAD///////8AAOAAAAAABwAA4AAAAAAHAADgAAAAAAcAAOAA + AAAABwAA4AAAAAAHAADgAAAAAAcAAOAAAAAABwAA4AAAAAAHAADgAAAAAAcAAOAAAAAABwAA4AAAAAAH + AADgAAAAAAcAAOAAAAAABwAA4AAAAAAHAADgAAAAAAcAAOAAAAAABwAA4AAAAAAHAADgAAAAAAcAAOAA + AAAABwAA4AAAAAAHAADgAAAAAAcAAOAAAAAABwAA4AAAAAAHAADgAAAAAAcAAOAAAAAABwAA4AAAAAAH + AADgAAAAAAcAAOAAAAAABwAA4AAAAAAHAADgAAAAAAcAAOAAAAAABwAA4AAAAAAHAADgAAAAAAcAAOAA + AAAABwAA4AAAAAAHAADgAAAAAAcAAOAAAAAABwAA4AAAAAAHAADgAAAAAAcAAOAAAAAABwAA4AAAAAAH + AADgAAAAAAcAAP///////wAA////////AAD///////8AAA== + + + + AddInDlg + + + + AAEAAAD/////AQAAAAAAAAAMAgAAAFdTeXN0ZW0uV2luZG93cy5Gb3JtcywgVmVyc2lvbj00LjAuMC4w + LCBDdWx0dXJlPW5ldXRyYWwsIFB1YmxpY0tleVRva2VuPWI3N2E1YzU2MTkzNGUwODkFAQAAACZTeXN0 + ZW0uV2luZG93cy5Gb3Jtcy5JbWFnZUxpc3RTdHJlYW1lcgEAAAAERGF0YQcCAgAAAAkDAAAADwMAAAC2 + BwAAAk1TRnQBSQFMAwEBAAEFAQABCAEAARABAAEQAQAE/wEJARAI/wFCAU0BNgEEBgABNgEEAgABKAMA + AUADAAEQAwABAQEAAQgGAAEEGAABgAIAAYADAAKAAQABgAMAAYABAAGAAQACgAIAA8ABAAHAAdwBwAEA + AfABygGmAQABMwUAATMBAAEzAQABMwEAAjMCAAMWAQADHAEAAyIBAAMpAQADVQEAA00BAANCAQADOQEA + AYABfAH/AQACUAH/AQABkwEAAdYBAAH/AewBzAEAAcYB1gHvAQAB1gLnAQABkAGpAa0CAAH/ATMDAAFm + AwABmQMAAcwCAAEzAwACMwIAATMBZgIAATMBmQIAATMBzAIAATMB/wIAAWYDAAFmATMCAAJmAgABZgGZ + AgABZgHMAgABZgH/AgABmQMAAZkBMwIAAZkBZgIAApkCAAGZAcwCAAGZAf8CAAHMAwABzAEzAgABzAFm + AgABzAGZAgACzAIAAcwB/wIAAf8BZgIAAf8BmQIAAf8BzAEAATMB/wIAAf8BAAEzAQABMwEAAWYBAAEz + AQABmQEAATMBAAHMAQABMwEAAf8BAAH/ATMCAAMzAQACMwFmAQACMwGZAQACMwHMAQACMwH/AQABMwFm + AgABMwFmATMBAAEzAmYBAAEzAWYBmQEAATMBZgHMAQABMwFmAf8BAAEzAZkCAAEzAZkBMwEAATMBmQFm + AQABMwKZAQABMwGZAcwBAAEzAZkB/wEAATMBzAIAATMBzAEzAQABMwHMAWYBAAEzAcwBmQEAATMCzAEA + ATMBzAH/AQABMwH/ATMBAAEzAf8BZgEAATMB/wGZAQABMwH/AcwBAAEzAv8BAAFmAwABZgEAATMBAAFm + AQABZgEAAWYBAAGZAQABZgEAAcwBAAFmAQAB/wEAAWYBMwIAAWYCMwEAAWYBMwFmAQABZgEzAZkBAAFm + ATMBzAEAAWYBMwH/AQACZgIAAmYBMwEAA2YBAAJmAZkBAAJmAcwBAAFmAZkCAAFmAZkBMwEAAWYBmQFm + AQABZgKZAQABZgGZAcwBAAFmAZkB/wEAAWYBzAIAAWYBzAEzAQABZgHMAZkBAAFmAswBAAFmAcwB/wEA + AWYB/wIAAWYB/wEzAQABZgH/AZkBAAFmAf8BzAEAAcwBAAH/AQAB/wEAAcwBAAKZAgABmQEzAZkBAAGZ + AQABmQEAAZkBAAHMAQABmQMAAZkCMwEAAZkBAAFmAQABmQEzAcwBAAGZAQAB/wEAAZkBZgIAAZkBZgEz + AQABmQEzAWYBAAGZAWYBmQEAAZkBZgHMAQABmQEzAf8BAAKZATMBAAKZAWYBAAOZAQACmQHMAQACmQH/ + AQABmQHMAgABmQHMATMBAAFmAcwBZgEAAZkBzAGZAQABmQLMAQABmQHMAf8BAAGZAf8CAAGZAf8BMwEA + AZkBzAFmAQABmQH/AZkBAAGZAf8BzAEAAZkC/wEAAcwDAAGZAQABMwEAAcwBAAFmAQABzAEAAZkBAAHM + AQABzAEAAZkBMwIAAcwCMwEAAcwBMwFmAQABzAEzAZkBAAHMATMBzAEAAcwBMwH/AQABzAFmAgABzAFm + ATMBAAGZAmYBAAHMAWYBmQEAAcwBZgHMAQABmQFmAf8BAAHMAZkCAAHMAZkBMwEAAcwBmQFmAQABzAKZ + AQABzAGZAcwBAAHMAZkB/wEAAswCAALMATMBAALMAWYBAALMAZkBAAPMAQACzAH/AQABzAH/AgABzAH/ + ATMBAAGZAf8BZgEAAcwB/wGZAQABzAH/AcwBAAHMAv8BAAHMAQABMwEAAf8BAAFmAQAB/wEAAZkBAAHM + ATMCAAH/AjMBAAH/ATMBZgEAAf8BMwGZAQAB/wEzAcwBAAH/ATMB/wEAAf8BZgIAAf8BZgEzAQABzAJm + AQAB/wFmAZkBAAH/AWYBzAEAAcwBZgH/AQAB/wGZAgAB/wGZATMBAAH/AZkBZgEAAf8CmQEAAf8BmQHM + AQAB/wGZAf8BAAH/AcwCAAH/AcwBMwEAAf8BzAFmAQAB/wHMAZkBAAH/AswBAAH/AcwB/wEAAv8BMwEA + AcwB/wFmAQAC/wGZAQAC/wHMAQACZgH/AQABZgH/AWYBAAFmAv8BAAH/AmYBAAH/AWYB/wEAAv8BZgEA + ASEBAAGlAQADXwEAA3cBAAOGAQADlgEAA8sBAAOyAQAD1wEAA90BAAPjAQAD6gEAA/EBAAP4AQAB8AH7 + Af8BAAGkAqABAAOAAwAB/wIAAf8DAAL/AQAB/wMAAf8BAAH/AQAC/wIAA/9DAAgFOAABBQb/OQABBQH/ + AgAD/wEAAf83AAEFBP8DAAH/NwABBQH/AgAB/wEABf81AAEFBP8DAAH/NwABBQH/AgAD/wEAAf83AAEF + Bv85AAEFAf8EAAH/AQU4AAEFBv8BBTgAAQUB/wQAAf8BBTgAAQUG/wEFOAAIBbYAAUIBTQE+BwABPgMA + ASgDAAFAAwABEAMAAQEBAAEBBQABgBcAA/8BAAL/BgABwAE/BgABwAEPBgABwAEPBgABwAEDBgABwAED + BgABwAEDBgABwAEPBgABwAEPBgABwAE/BgABwAE/BgABwAE/BgABwAE/BgABwAE/BgAC/wYAAv8cAAs= + + + + 17, 17 + + \ No newline at end of file diff --git a/Labyrinth3/IDE/Forms/ElementDlg.cs b/Labyrinth3/IDE/Forms/ElementDlg.cs new file mode 100644 index 0000000..16ca028 --- /dev/null +++ b/Labyrinth3/IDE/Forms/ElementDlg.cs @@ -0,0 +1,152 @@ +// Decompiled with JetBrains decompiler +// Type: Labyrinth.Forms.ElementDlg +// Assembly: Labyrinth, Version=3.6.1928.15690, Culture=neutral, PublicKeyToken=null +// MVID: 1462002E-0BD1-49D2-9B56-C22E66C903E7 +// Assembly location: C:\Dropbox\Workspace\Programs\Labyrinth\Labyrinth.exe + +using Labyrinth.Controls; +using Labyrinth.Plot; +using System; +using System.ComponentModel; +using System.Drawing; +using System.Windows.Forms; + +namespace Labyrinth.Forms +{ + public class ElementDlg : Form + { + private Container components = (Container)null; + private Element fElement = (Element)null; + private Label NameLbl; + private TextBox NameBox; + private Button OKBtn; + private Button CancelBtn; + private Label TypeLbl; + private ElementTypeBox TypeBox; + + public ElementDlg(Element e) + { + this.InitializeComponent(); + this.fElement = e; + this.NameBox.Text = this.fElement.Name; + this.TypeBox.SelectedElementType = this.fElement.Type; + } + + protected override void Dispose(bool disposing) + { + if (disposing && this.components != null) + this.components.Dispose(); + base.Dispose(disposing); + } + + private void InitializeComponent() + { + this.NameLbl = new Label(); + this.NameBox = new TextBox(); + this.OKBtn = new Button(); + this.CancelBtn = new Button(); + this.TypeLbl = new Label(); + this.TypeBox = new ElementTypeBox(); + this.SuspendLayout(); + this.NameLbl.Location = new Point(16, 24); + this.NameLbl.Name = "NameLbl"; + this.NameLbl.Size = new Size(48, 23); + this.NameLbl.TabIndex = 0; + this.NameLbl.Text = "Name:"; + this.NameLbl.TextAlign = ContentAlignment.MiddleLeft; + this.NameBox.Anchor = AnchorStyles.Top | AnchorStyles.Left | AnchorStyles.Right; + this.NameBox.Location = new Point(64, 24); + this.NameBox.Name = "NameBox"; + this.NameBox.Size = new Size(216, 21); + this.NameBox.TabIndex = 1; + this.NameBox.Text = ""; + this.OKBtn.Anchor = AnchorStyles.Bottom | AnchorStyles.Right; + this.OKBtn.DialogResult = DialogResult.OK; + this.OKBtn.Location = new Point(128, 98); + this.OKBtn.Name = "OKBtn"; + this.OKBtn.Size = new Size(72, 23); + this.OKBtn.TabIndex = 4; + this.OKBtn.Text = "OK"; + this.OKBtn.Click += new EventHandler(this.OKBtn_Click); + this.CancelBtn.Anchor = AnchorStyles.Bottom | AnchorStyles.Right; + this.CancelBtn.DialogResult = DialogResult.Cancel; + this.CancelBtn.Location = new Point(208, 98); + this.CancelBtn.Name = "CancelBtn"; + this.CancelBtn.Size = new Size(72, 23); + this.CancelBtn.TabIndex = 5; + this.CancelBtn.Text = "Cancel"; + this.TypeLbl.Location = new Point(16, 56); + this.TypeLbl.Name = "TypeLbl"; + this.TypeLbl.Size = new Size(48, 23); + this.TypeLbl.TabIndex = 2; + this.TypeLbl.Text = "Type:"; + this.TypeLbl.TextAlign = ContentAlignment.MiddleLeft; + this.TypeBox.DrawMode = DrawMode.OwnerDrawFixed; + this.TypeBox.DropDownStyle = ComboBoxStyle.DropDownList; + this.TypeBox.Items.AddRange(new object[26] + { + (object) ElementType.Generic, + (object) ElementType.Character, + (object) ElementType.Organisation, + (object) ElementType.Website, + (object) ElementType.EmailAccount, + (object) ElementType.PhoneNumber, + (object) ElementType.File, + (object) ElementType.Puzzle, + (object) ElementType.Location, + (object) ElementType.Vehicle, + (object) ElementType.Concept, + (object) ElementType.Object, + (object) ElementType.Event, + (object) ElementType.Generic, + (object) ElementType.Character, + (object) ElementType.Organisation, + (object) ElementType.Website, + (object) ElementType.EmailAccount, + (object) ElementType.PhoneNumber, + (object) ElementType.File, + (object) ElementType.Puzzle, + (object) ElementType.Location, + (object) ElementType.Vehicle, + (object) ElementType.Concept, + (object) ElementType.Object, + (object) ElementType.Event + }); + this.TypeBox.Location = new Point(64, 56); + this.TypeBox.Name = "TypeBox"; + this.TypeBox.SelectedElementType = ElementType.Generic; + this.TypeBox.Size = new Size(216, 22); + this.TypeBox.TabIndex = 3; + this.AcceptButton = (IButtonControl)this.OKBtn; + this.AutoScaleBaseSize = new Size(5, 14); + this.CancelButton = (IButtonControl)this.CancelBtn; + this.ClientSize = new Size(292, 136); + this.ControlBox = false; + this.Controls.AddRange(new Control[6] + { + (Control) this.TypeBox, + (Control) this.TypeLbl, + (Control) this.CancelBtn, + (Control) this.OKBtn, + (Control) this.NameBox, + (Control) this.NameLbl + }); + this.Font = new Font("Tahoma", 11f, FontStyle.Regular, GraphicsUnit.World); + this.FormBorderStyle = FormBorderStyle.FixedDialog; + this.MaximizeBox = false; + this.MinimizeBox = false; + this.Name = nameof(ElementDlg); + this.ShowInTaskbar = false; + this.SizeGripStyle = SizeGripStyle.Hide; + this.StartPosition = FormStartPosition.CenterParent; + this.Text = "Element Properties"; + this.ResumeLayout(false); + } + + private void OKBtn_Click(object sender, EventArgs e) + { + this.fElement.Name = this.NameBox.Text; + this.fElement.Type = this.TypeBox.SelectedElementType; + } + } +} \ No newline at end of file diff --git a/Labyrinth3/IDE/Forms/ElementDlg.resx b/Labyrinth3/IDE/Forms/ElementDlg.resx new file mode 100644 index 0000000..364493b --- /dev/null +++ b/Labyrinth3/IDE/Forms/ElementDlg.resx @@ -0,0 +1,123 @@ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + text/microsoft-resx + + + 2.0 + + + System.Resources.ResXResourceReader, System.Windows.Forms, Version=4.0.0.0, Culture=neutral, PublicKeyToken=b77a5c561934e089 + + + System.Resources.ResXResourceWriter, System.Windows.Forms, Version=4.0.0.0, Culture=neutral, PublicKeyToken=b77a5c561934e089 + + + ElementDlg + + \ No newline at end of file diff --git a/Labyrinth3/IDE/Forms/FileLinkAnnotationDlg.cs b/Labyrinth3/IDE/Forms/FileLinkAnnotationDlg.cs new file mode 100644 index 0000000..7d5e875 --- /dev/null +++ b/Labyrinth3/IDE/Forms/FileLinkAnnotationDlg.cs @@ -0,0 +1,294 @@ +// Decompiled with JetBrains decompiler +// Type: Labyrinth.Forms.FileLinkAnnotationDlg +// Assembly: Labyrinth, Version=3.6.1928.15690, Culture=neutral, PublicKeyToken=null +// MVID: 1462002E-0BD1-49D2-9B56-C22E66C903E7 +// Assembly location: C:\Dropbox\Workspace\Programs\Labyrinth\Labyrinth.exe + +using Labyrinth.Plot; +using System; +using System.ComponentModel; +using System.Diagnostics; +using System.Drawing; +using System.IO; +using System.Resources; +using System.Windows.Forms; + +namespace Labyrinth.Forms +{ + public class FileLinkAnnotationDlg : Form + { + private LinkAnnotation fNote = (LinkAnnotation)null; + private ImageList ToolbarImages; + private Button OKBtn; + private Button CancelBtn; + private Label LinkLbl; + private Button BrowseBtn; + private Label SizeLbl; + private Label CreatedLbl; + private Label LastAccessedLbl; + private Label LastModifiedLbl; + private Label AttributesLbl; + private Label AttributesValLbl; + private Label LastModifiedValLbl; + private Label LastAccessedValLbl; + private Label CreatedValLbl; + private Label SizeValLbl; + private LinkLabel FilenameLbl; + private IContainer components; + + public FileLinkAnnotationDlg(LinkAnnotation note) + { + this.InitializeComponent(); + this.fNote = note; + if (this.fNote.Content == "") + { + this.FilenameLbl.Text = "(no file specified)"; + this.FilenameLbl.Links.Clear(); + } + else + this.FilenameLbl.Text = this.fNote.Content; + this.update_details(); + } + + protected override void Dispose(bool disposing) + { + if (disposing && this.components != null) + this.components.Dispose(); + base.Dispose(disposing); + } + + private void InitializeComponent() + { + this.components = (IContainer)new Container(); + ResourceManager resourceManager = new ResourceManager(typeof(FileLinkAnnotationDlg)); + this.ToolbarImages = new ImageList(this.components); + this.OKBtn = new Button(); + this.CancelBtn = new Button(); + this.LinkLbl = new Label(); + this.BrowseBtn = new Button(); + this.SizeLbl = new Label(); + this.CreatedLbl = new Label(); + this.LastAccessedLbl = new Label(); + this.LastModifiedLbl = new Label(); + this.AttributesLbl = new Label(); + this.AttributesValLbl = new Label(); + this.LastModifiedValLbl = new Label(); + this.LastAccessedValLbl = new Label(); + this.CreatedValLbl = new Label(); + this.SizeValLbl = new Label(); + this.FilenameLbl = new LinkLabel(); + this.SuspendLayout(); + this.ToolbarImages.ColorDepth = ColorDepth.Depth8Bit; + this.ToolbarImages.ImageSize = new Size(16, 16); + this.ToolbarImages.ImageStream = (ImageListStreamer)resourceManager.GetObject("ToolbarImages.ImageStream"); + this.ToolbarImages.TransparentColor = Color.Magenta; + this.OKBtn.Anchor = AnchorStyles.Bottom | AnchorStyles.Right; + this.OKBtn.DialogResult = DialogResult.OK; + this.OKBtn.Location = new Point(140, 200); + this.OKBtn.Name = "OKBtn"; + this.OKBtn.TabIndex = 13; + this.OKBtn.Text = "OK"; + this.OKBtn.Click += new EventHandler(this.OKBtn_Click); + this.CancelBtn.Anchor = AnchorStyles.Bottom | AnchorStyles.Right; + this.CancelBtn.DialogResult = DialogResult.Cancel; + this.CancelBtn.Location = new Point(220, 200); + this.CancelBtn.Name = "CancelBtn"; + this.CancelBtn.TabIndex = 14; + this.CancelBtn.Text = "Cancel"; + this.LinkLbl.Location = new Point(16, 16); + this.LinkLbl.Name = "LinkLbl"; + this.LinkLbl.Size = new Size(32, 23); + this.LinkLbl.TabIndex = 0; + this.LinkLbl.Text = "File:"; + this.LinkLbl.TextAlign = ContentAlignment.MiddleLeft; + this.BrowseBtn.Anchor = AnchorStyles.Top | AnchorStyles.Right; + this.BrowseBtn.Location = new Point(264, 16); + this.BrowseBtn.Name = "BrowseBtn"; + this.BrowseBtn.Size = new Size(32, 23); + this.BrowseBtn.TabIndex = 2; + this.BrowseBtn.Text = "..."; + this.BrowseBtn.Click += new EventHandler(this.BrowseBtn_Click); + this.SizeLbl.Location = new Point(16, 56); + this.SizeLbl.Name = "SizeLbl"; + this.SizeLbl.Size = new Size(88, 23); + this.SizeLbl.TabIndex = 3; + this.SizeLbl.Text = "Size:"; + this.CreatedLbl.Location = new Point(16, 80); + this.CreatedLbl.Name = "CreatedLbl"; + this.CreatedLbl.Size = new Size(88, 23); + this.CreatedLbl.TabIndex = 5; + this.CreatedLbl.Text = "Created:"; + this.LastAccessedLbl.Location = new Point(16, 128); + this.LastAccessedLbl.Name = "LastAccessedLbl"; + this.LastAccessedLbl.Size = new Size(88, 23); + this.LastAccessedLbl.TabIndex = 9; + this.LastAccessedLbl.Text = "Last Accessed:"; + this.LastModifiedLbl.Location = new Point(16, 104); + this.LastModifiedLbl.Name = "LastModifiedLbl"; + this.LastModifiedLbl.Size = new Size(88, 23); + this.LastModifiedLbl.TabIndex = 7; + this.LastModifiedLbl.Text = "Last Modified:"; + this.AttributesLbl.Location = new Point(16, 152); + this.AttributesLbl.Name = "AttributesLbl"; + this.AttributesLbl.Size = new Size(88, 23); + this.AttributesLbl.TabIndex = 11; + this.AttributesLbl.Text = "Attributes:"; + this.AttributesValLbl.Anchor = AnchorStyles.Top | AnchorStyles.Bottom | AnchorStyles.Left | AnchorStyles.Right; + this.AttributesValLbl.Location = new Point(112, 152); + this.AttributesValLbl.Name = "AttributesValLbl"; + this.AttributesValLbl.Size = new Size(184, 40); + this.AttributesValLbl.TabIndex = 12; + this.AttributesValLbl.Text = "xxx"; + this.LastModifiedValLbl.Anchor = AnchorStyles.Top | AnchorStyles.Left | AnchorStyles.Right; + this.LastModifiedValLbl.Location = new Point(112, 104); + this.LastModifiedValLbl.Name = "LastModifiedValLbl"; + this.LastModifiedValLbl.Size = new Size(184, 23); + this.LastModifiedValLbl.TabIndex = 8; + this.LastModifiedValLbl.Text = "xxx"; + this.LastAccessedValLbl.Anchor = AnchorStyles.Top | AnchorStyles.Left | AnchorStyles.Right; + this.LastAccessedValLbl.Location = new Point(112, 128); + this.LastAccessedValLbl.Name = "LastAccessedValLbl"; + this.LastAccessedValLbl.Size = new Size(184, 23); + this.LastAccessedValLbl.TabIndex = 10; + this.LastAccessedValLbl.Text = "xxx"; + this.CreatedValLbl.Anchor = AnchorStyles.Top | AnchorStyles.Left | AnchorStyles.Right; + this.CreatedValLbl.Location = new Point(112, 80); + this.CreatedValLbl.Name = "CreatedValLbl"; + this.CreatedValLbl.Size = new Size(184, 23); + this.CreatedValLbl.TabIndex = 6; + this.CreatedValLbl.Text = "xxx"; + this.SizeValLbl.Anchor = AnchorStyles.Top | AnchorStyles.Left | AnchorStyles.Right; + this.SizeValLbl.Location = new Point(112, 56); + this.SizeValLbl.Name = "SizeValLbl"; + this.SizeValLbl.Size = new Size(184, 23); + this.SizeValLbl.TabIndex = 4; + this.SizeValLbl.Text = "xxx"; + this.FilenameLbl.Anchor = AnchorStyles.Top | AnchorStyles.Left | AnchorStyles.Right; + this.FilenameLbl.Location = new Point(56, 16); + this.FilenameLbl.Name = "FilenameLbl"; + this.FilenameLbl.Size = new Size(208, 23); + this.FilenameLbl.TabIndex = 1; + this.FilenameLbl.TabStop = true; + this.FilenameLbl.Text = "filename"; + this.FilenameLbl.TextAlign = ContentAlignment.MiddleLeft; + this.FilenameLbl.LinkClicked += new LinkLabelLinkClickedEventHandler(this.FilenameLbl_LinkClicked); + this.AutoScaleBaseSize = new Size(5, 14); + this.CancelButton = (IButtonControl)this.CancelBtn; + this.ClientSize = new Size(312, 238); + this.Controls.AddRange(new Control[15] + { + (Control) this.FilenameLbl, + (Control) this.AttributesValLbl, + (Control) this.LastModifiedValLbl, + (Control) this.LastAccessedValLbl, + (Control) this.CreatedValLbl, + (Control) this.SizeValLbl, + (Control) this.AttributesLbl, + (Control) this.LastModifiedLbl, + (Control) this.LastAccessedLbl, + (Control) this.CreatedLbl, + (Control) this.SizeLbl, + (Control) this.BrowseBtn, + (Control) this.LinkLbl, + (Control) this.CancelBtn, + (Control) this.OKBtn + }); + this.Font = new Font("Tahoma", 11f, FontStyle.Regular, GraphicsUnit.World, (byte)0); + this.Icon = (Icon)resourceManager.GetObject("$this.Icon"); + this.MinimizeBox = false; + this.Name = nameof(FileLinkAnnotationDlg); + this.ShowInTaskbar = false; + this.SizeGripStyle = SizeGripStyle.Hide; + this.StartPosition = FormStartPosition.CenterParent; + this.Text = "File Link Annotation Properties"; + this.ResumeLayout(false); + } + + private void ContentBox_LinkClicked(object sender, LinkClickedEventArgs e) + { + try + { + Process.Start(e.LinkText); + } + catch (Exception ex) + { + LabyrinthData.Log((object)ex); + } + } + + private void OKBtn_Click(object sender, EventArgs e) + { + this.fNote.Content = this.FilenameLbl.Text; + } + + private void BrowseBtn_Click(object sender, EventArgs e) + { + OpenFileDialog openFileDialog = new OpenFileDialog(); + openFileDialog.Filter = "All Files|*.*"; + openFileDialog.FileName = this.FilenameLbl.Text; + if (openFileDialog.ShowDialog() != DialogResult.OK) + return; + this.FilenameLbl.Text = openFileDialog.FileName; + this.FilenameLbl.Links.Clear(); + this.FilenameLbl.Links.Add(0, this.FilenameLbl.Text.Length); + this.update_details(); + } + + private void FilenameLbl_LinkClicked(object sender, LinkLabelLinkClickedEventArgs e) + { + try + { + Process.Start(this.FilenameLbl.Text); + } + catch (Exception ex) + { + LabyrinthData.Log((object)ex); + int num = (int)MessageBox.Show(ex.Message, "Labyrinth", MessageBoxButtons.OK, MessageBoxIcon.Hand); + } + } + + private void update_details() + { + this.SizeValLbl.Text = "-"; + this.CreatedValLbl.Text = "-"; + this.LastModifiedValLbl.Text = "-"; + this.LastAccessedValLbl.Text = "-"; + this.AttributesValLbl.Text = "-"; + try + { + FileInfo fileInfo = new FileInfo(this.FilenameLbl.Text); + if (!fileInfo.Exists) + return; + string str1 = fileInfo.Length >= 1024L ? (fileInfo.Length >= 1048576L ? (fileInfo.Length >= 1073741824L ? ((double)fileInfo.Length / 1073741824.0).ToString("F1") + " Gb" : ((double)fileInfo.Length / 1048576.0).ToString("F1") + " Mb") : ((double)fileInfo.Length / 1024.0).ToString("F1") + " kb") : fileInfo.Length.ToString() + " bytes"; + DateTime dateTime = fileInfo.CreationTime; + string shortDateString1 = dateTime.ToShortDateString(); + string str2 = ", "; + dateTime = fileInfo.CreationTime; + string shortTimeString1 = dateTime.ToShortTimeString(); + string str3 = shortDateString1 + str2 + shortTimeString1; + dateTime = fileInfo.LastWriteTime; + string shortDateString2 = dateTime.ToShortDateString(); + string str4 = ", "; + dateTime = fileInfo.LastWriteTime; + string shortTimeString2 = dateTime.ToShortTimeString(); + string str5 = shortDateString2 + str4 + shortTimeString2; + dateTime = fileInfo.LastAccessTime; + string shortDateString3 = dateTime.ToShortDateString(); + string str6 = ", "; + dateTime = fileInfo.LastAccessTime; + string shortTimeString3 = dateTime.ToShortTimeString(); + string str7 = shortDateString3 + str6 + shortTimeString3; + string str8 = fileInfo.Attributes.ToString(); + this.SizeValLbl.Text = str1; + this.CreatedValLbl.Text = str3; + this.LastModifiedValLbl.Text = str5; + this.LastAccessedValLbl.Text = str7; + this.AttributesValLbl.Text = str8; + } + catch (Exception ex) + { + LabyrinthData.Log((object)ex); + } + } + } +} \ No newline at end of file diff --git a/Labyrinth3/IDE/Forms/FileLinkAnnotationDlg.resx b/Labyrinth3/IDE/Forms/FileLinkAnnotationDlg.resx new file mode 100644 index 0000000..a6d55f7 --- /dev/null +++ b/Labyrinth3/IDE/Forms/FileLinkAnnotationDlg.resx @@ -0,0 +1,187 @@ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + text/microsoft-resx + + + 2.0 + + + System.Resources.ResXResourceReader, System.Windows.Forms, Version=4.0.0.0, Culture=neutral, PublicKeyToken=b77a5c561934e089 + + + System.Resources.ResXResourceWriter, System.Windows.Forms, Version=4.0.0.0, Culture=neutral, PublicKeyToken=b77a5c561934e089 + + + + + AAABAAEAEBAQAAAAAAAoAQAAFgAAACgAAAAQAAAAIAAAAAEABAAAAAAAgAAAAAAAAAAAAAAAEAAAABAA + AAAAAAAAAACAAACAAAAAgIAAgAAAAIAAgACAgAAAgICAAMDAwAAAAP8AAP8AAAD//wD/AAAA/wD/AP// + AAD///8AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAHvwCwDwD7AAf7APALCA8AB78AsA8L + gAAH+wDwCwAAAAe/sL8Pv78AB/vw+wv7+wAHv78Av7+/AAd3d3d3d3cAAAAAAAAAAAAAAAAAAAAAAAAA + AAAAAAAAAAAAAAAAAAD4/wAA938AAPd/AACAAQAAgAEAAIABAACAAQAAgAEAAIABAACAAQAAgAEAAIAB + AAD//wAA//8AAP//AAD//wAA + + + + FileLinkAnnotationDlg + + + 17, 17 + + + + 57 + + + + AAEAAAD/////AQAAAAAAAAAMAgAAAFdTeXN0ZW0uV2luZG93cy5Gb3JtcywgVmVyc2lvbj00LjAuMC4w + LCBDdWx0dXJlPW5ldXRyYWwsIFB1YmxpY0tleVRva2VuPWI3N2E1YzU2MTkzNGUwODkFAQAAACZTeXN0 + ZW0uV2luZG93cy5Gb3Jtcy5JbWFnZUxpc3RTdHJlYW1lcgEAAAAERGF0YQcCAgAAAAkDAAAADwMAAADs + CAAAAk1TRnQBSQFMAgEBCQEAAQ4BAAEIAQABEAEAARABAAT/AQkBEAj/AUIBTQE2AQQGAAE2AQQCAAEo + AwABQAMAATADAAEBAQABCAYAAQwYAAGAAgABgAMAAoABAAGAAwABgAEAAYABAAKAAgADwAEAAcAB3AHA + AQAB8AHKAaYBAAEzBQABMwEAATMBAAEzAQACMwIAAxYBAAMcAQADIgEAAykBAANVAQADTQEAA0IBAAM5 + AQABgAF8Af8BAAJQAf8BAAGTAQAB1gEAAf8B7AHMAQABxgHWAe8BAAHWAucBAAGQAakBrQIAAf8BMwMA + AWYDAAGZAwABzAIAATMDAAIzAgABMwFmAgABMwGZAgABMwHMAgABMwH/AgABZgMAAWYBMwIAAmYCAAFm + AZkCAAFmAcwCAAFmAf8CAAGZAwABmQEzAgABmQFmAgACmQIAAZkBzAIAAZkB/wIAAcwDAAHMATMCAAHM + AWYCAAHMAZkCAALMAgABzAH/AgAB/wFmAgAB/wGZAgAB/wHMAQABMwH/AgAB/wEAATMBAAEzAQABZgEA + ATMBAAGZAQABMwEAAcwBAAEzAQAB/wEAAf8BMwIAAzMBAAIzAWYBAAIzAZkBAAIzAcwBAAIzAf8BAAEz + AWYCAAEzAWYBMwEAATMCZgEAATMBZgGZAQABMwFmAcwBAAEzAWYB/wEAATMBmQIAATMBmQEzAQABMwGZ + AWYBAAEzApkBAAEzAZkBzAEAATMBmQH/AQABMwHMAgABMwHMATMBAAEzAcwBZgEAATMBzAGZAQABMwLM + AQABMwHMAf8BAAEzAf8BMwEAATMB/wFmAQABMwH/AZkBAAEzAf8BzAEAATMC/wEAAWYDAAFmAQABMwEA + AWYBAAFmAQABZgEAAZkBAAFmAQABzAEAAWYBAAH/AQABZgEzAgABZgIzAQABZgEzAWYBAAFmATMBmQEA + AWYBMwHMAQABZgEzAf8BAAJmAgACZgEzAQADZgEAAmYBmQEAAmYBzAEAAWYBmQIAAWYBmQEzAQABZgGZ + AWYBAAFmApkBAAFmAZkBzAEAAWYBmQH/AQABZgHMAgABZgHMATMBAAFmAcwBmQEAAWYCzAEAAWYBzAH/ + AQABZgH/AgABZgH/ATMBAAFmAf8BmQEAAWYB/wHMAQABzAEAAf8BAAH/AQABzAEAApkCAAGZATMBmQEA + AZkBAAGZAQABmQEAAcwBAAGZAwABmQIzAQABmQEAAWYBAAGZATMBzAEAAZkBAAH/AQABmQFmAgABmQFm + ATMBAAGZATMBZgEAAZkBZgGZAQABmQFmAcwBAAGZATMB/wEAApkBMwEAApkBZgEAA5kBAAKZAcwBAAKZ + Af8BAAGZAcwCAAGZAcwBMwEAAWYBzAFmAQABmQHMAZkBAAGZAswBAAGZAcwB/wEAAZkB/wIAAZkB/wEz + AQABmQHMAWYBAAGZAf8BmQEAAZkB/wHMAQABmQL/AQABzAMAAZkBAAEzAQABzAEAAWYBAAHMAQABmQEA + AcwBAAHMAQABmQEzAgABzAIzAQABzAEzAWYBAAHMATMBmQEAAcwBMwHMAQABzAEzAf8BAAHMAWYCAAHM + AWYBMwEAAZkCZgEAAcwBZgGZAQABzAFmAcwBAAGZAWYB/wEAAcwBmQIAAcwBmQEzAQABzAGZAWYBAAHM + ApkBAAHMAZkBzAEAAcwBmQH/AQACzAIAAswBMwEAAswBZgEAAswBmQEAA8wBAALMAf8BAAHMAf8CAAHM + Af8BMwEAAZkB/wFmAQABzAH/AZkBAAHMAf8BzAEAAcwC/wEAAcwBAAEzAQAB/wEAAWYBAAH/AQABmQEA + AcwBMwIAAf8CMwEAAf8BMwFmAQAB/wEzAZkBAAH/ATMBzAEAAf8BMwH/AQAB/wFmAgAB/wFmATMBAAHM + AmYBAAH/AWYBmQEAAf8BZgHMAQABzAFmAf8BAAH/AZkCAAH/AZkBMwEAAf8BmQFmAQAB/wKZAQAB/wGZ + AcwBAAH/AZkB/wEAAf8BzAIAAf8BzAEzAQAB/wHMAWYBAAH/AcwBmQEAAf8CzAEAAf8BzAH/AQAC/wEz + AQABzAH/AWYBAAL/AZkBAAL/AcwBAAJmAf8BAAFmAf8BZgEAAWYC/wEAAf8CZgEAAf8BZgH/AQAC/wFm + AQABIQEAAaUBAANfAQADdwEAA4YBAAOWAQADywEAA7IBAAPXAQAD3QEAA+MBAAPqAQAD8QEAA/gBAAHw + AfsB/wEAAaQCoAEAA4ADAAH/AgAB/wMAAv8BAAH/AwAB/wEAAf8BAAL/AgAD/8MABAQDAAYENAABBwEE + BQABBwIEAQc2AAIEBAABBwIENwABBwEEBAACBAEHOAAHBDkAAQcBBAIAAgQBBzoAAgQBAAIEOwABBwME + AQc8AAMEPQABBwEEAQc+AAEE/wA5AAMEPQADBD0AAwS9AAMEPQADBD0AAwS9AAMEPQADBD0AAwT/ANQA + AewOAAHsAQAB7CwAAexCAAHsPQAB7EIAAew9AAHsQgAB7P8AJgABQgFNAT4HAAE+AwABKAMAAUADAAEw + AwABAQEAAQEFAAGAAQEWAAP/AQAC/wYAAv8GAAL/BgABwwGBBgAB5wHDBgAB8wHHBgAB8wHHBgAB+AEP + BgAB+QGPBgAB/AGfBgAB/AEfBgAB/gE/BgAB/gE/BgAB/wF/BgAC/wYAAv8GABD/AY8H/wGMAQEBgAED + AcABDwHwAQMBjwn/AYABPwEAAQMBAAEDCP8BjwH/AYABAwHAAQ8B8AEDAYwBAQb/AY8B/wGAAT8BAAED + AQABAwr/AYABAwHAAQ8B8AEDAY8H/wGMAQEBgAE/AQABAwEAAQMBjyP/AeABDwr/AeABHwHgAX8B+AE/ + Av8B8QGPAfgB/wHxAR8BEAE4AfEBjwH4Af8B8wGfAboB1wHxAY8B/AF/AfMBnwIAAfABHwH8AX8B8wGf + AdYBNwHxAY8B/gE/AfMBnwHGAdcB8QGPAf4BPwHzAZ8B7gHWAfEBjwH/AR8B8wGfAewBOAHgAR8B/gEP + AeEBDxr/FgAL + + + \ No newline at end of file diff --git a/Labyrinth3/IDE/Forms/LinkDlg.cs b/Labyrinth3/IDE/Forms/LinkDlg.cs new file mode 100644 index 0000000..361504f --- /dev/null +++ b/Labyrinth3/IDE/Forms/LinkDlg.cs @@ -0,0 +1,165 @@ +// Decompiled with JetBrains decompiler +// Type: Labyrinth.Forms.LinkDlg +// Assembly: Labyrinth, Version=3.6.1928.15690, Culture=neutral, PublicKeyToken=null +// MVID: 1462002E-0BD1-49D2-9B56-C22E66C903E7 +// Assembly location: C:\Dropbox\Workspace\Programs\Labyrinth\Labyrinth.exe + +using Labyrinth.Collections; +using Labyrinth.Plot; +using System; +using System.ComponentModel; +using System.Drawing; +using System.Windows.Forms; + +namespace Labyrinth.Forms +{ + public class LinkDlg : Form + { + private Container components = (Container)null; + private Labyrinth.Plot.Link fLink = (Labyrinth.Plot.Link)null; + private Button OKBtn; + private Button CancelBtn; + private Label DescLbl; + private TextBox DescBox; + private Label DirLbl; + private ComboBox DirBox; + private Label FromLbl; + private Label FromNameLbl; + private Label ToLbl; + private Label ToNameLbl; + + public LinkDlg(Labyrinth.Plot.Link l) + { + this.InitializeComponent(); + foreach (LinkDirection linkDirection in Enum.GetValues(typeof(LinkDirection))) + this.DirBox.Items.Add((object)linkDirection); + this.fLink = l; + int index1 = LabyrinthData.Project.Elements.IndexOf(l.LHS); + if (index1 != -1) + this.FromNameLbl.Text = LabyrinthData.Project.Elements[index1].Name; + int index2 = LabyrinthData.Project.Elements.IndexOf(l.RHS); + if (index2 != -1) + this.ToNameLbl.Text = LabyrinthData.Project.Elements[index2].Name; + this.DescBox.Text = this.fLink.Description; + this.DirBox.SelectedItem = (object)this.fLink.Direction; + } + + protected override void Dispose(bool disposing) + { + if (disposing && this.components != null) + this.components.Dispose(); + base.Dispose(disposing); + } + + private void InitializeComponent() + { + this.DescLbl = new Label(); + this.DescBox = new TextBox(); + this.OKBtn = new Button(); + this.CancelBtn = new Button(); + this.DirLbl = new Label(); + this.DirBox = new ComboBox(); + this.FromLbl = new Label(); + this.FromNameLbl = new Label(); + this.ToLbl = new Label(); + this.ToNameLbl = new Label(); + this.SuspendLayout(); + this.DescLbl.Location = new Point(16, 80); + this.DescLbl.Name = "DescLbl"; + this.DescLbl.Size = new Size(72, 23); + this.DescLbl.TabIndex = 4; + this.DescLbl.Text = "Description:"; + this.DescLbl.TextAlign = ContentAlignment.MiddleLeft; + this.DescBox.Anchor = AnchorStyles.Top | AnchorStyles.Left | AnchorStyles.Right; + this.DescBox.Location = new Point(96, 80); + this.DescBox.Name = "DescBox"; + this.DescBox.Size = new Size(184, 21); + this.DescBox.TabIndex = 5; + this.DescBox.Text = ""; + this.OKBtn.Anchor = AnchorStyles.Bottom | AnchorStyles.Right; + this.OKBtn.DialogResult = DialogResult.OK; + this.OKBtn.Location = new Point(128, 146); + this.OKBtn.Name = "OKBtn"; + this.OKBtn.Size = new Size(72, 23); + this.OKBtn.TabIndex = 8; + this.OKBtn.Text = "OK"; + this.OKBtn.Click += new EventHandler(this.OKBtn_Click); + this.CancelBtn.Anchor = AnchorStyles.Bottom | AnchorStyles.Right; + this.CancelBtn.DialogResult = DialogResult.Cancel; + this.CancelBtn.Location = new Point(208, 146); + this.CancelBtn.Name = "CancelBtn"; + this.CancelBtn.Size = new Size(72, 23); + this.CancelBtn.TabIndex = 9; + this.CancelBtn.Text = "Cancel"; + this.DirLbl.Location = new Point(16, 104); + this.DirLbl.Name = "DirLbl"; + this.DirLbl.Size = new Size(72, 23); + this.DirLbl.TabIndex = 6; + this.DirLbl.Text = "Direction:"; + this.DirLbl.TextAlign = ContentAlignment.MiddleLeft; + this.DirBox.DropDownStyle = ComboBoxStyle.DropDownList; + this.DirBox.Location = new Point(96, 104); + this.DirBox.Name = "DirBox"; + this.DirBox.Size = new Size(184, 21); + this.DirBox.TabIndex = 7; + this.FromLbl.Location = new Point(16, 16); + this.FromLbl.Name = "FromLbl"; + this.FromLbl.Size = new Size(72, 23); + this.FromLbl.TabIndex = 0; + this.FromLbl.Text = "From:"; + this.FromLbl.TextAlign = ContentAlignment.MiddleLeft; + this.FromNameLbl.Location = new Point(96, 16); + this.FromNameLbl.Name = "FromNameLbl"; + this.FromNameLbl.Size = new Size(184, 23); + this.FromNameLbl.TabIndex = 1; + this.FromNameLbl.Text = ""; + this.FromNameLbl.TextAlign = ContentAlignment.MiddleLeft; + this.ToLbl.Location = new Point(16, 40); + this.ToLbl.Name = "ToLbl"; + this.ToLbl.Size = new Size(72, 23); + this.ToLbl.TabIndex = 2; + this.ToLbl.Text = "To:"; + this.ToLbl.TextAlign = ContentAlignment.MiddleLeft; + this.ToNameLbl.Location = new Point(96, 40); + this.ToNameLbl.Name = "ToNameLbl"; + this.ToNameLbl.Size = new Size(184, 23); + this.ToNameLbl.TabIndex = 3; + this.ToNameLbl.Text = ""; + this.ToNameLbl.TextAlign = ContentAlignment.MiddleLeft; + this.AcceptButton = (IButtonControl)this.OKBtn; + this.AutoScaleBaseSize = new Size(5, 14); + this.CancelButton = (IButtonControl)this.CancelBtn; + this.ClientSize = new Size(292, 184); + this.ControlBox = false; + this.Controls.AddRange(new Control[10] + { + (Control) this.ToNameLbl, + (Control) this.ToLbl, + (Control) this.FromNameLbl, + (Control) this.FromLbl, + (Control) this.DirBox, + (Control) this.DirLbl, + (Control) this.CancelBtn, + (Control) this.OKBtn, + (Control) this.DescBox, + (Control) this.DescLbl + }); + this.Font = new Font("Tahoma", 11f, FontStyle.Regular, GraphicsUnit.World); + this.FormBorderStyle = FormBorderStyle.FixedDialog; + this.MaximizeBox = false; + this.MinimizeBox = false; + this.Name = nameof(LinkDlg); + this.ShowInTaskbar = false; + this.SizeGripStyle = SizeGripStyle.Hide; + this.StartPosition = FormStartPosition.CenterParent; + this.Text = "Link Properties"; + this.ResumeLayout(false); + } + + private void OKBtn_Click(object sender, EventArgs e) + { + this.fLink.Description = this.DescBox.Text; + this.fLink.Direction = (LinkDirection)this.DirBox.SelectedItem; + } + } +} \ No newline at end of file diff --git a/Labyrinth3/IDE/Forms/LinkDlg.resx b/Labyrinth3/IDE/Forms/LinkDlg.resx new file mode 100644 index 0000000..3bdacd9 --- /dev/null +++ b/Labyrinth3/IDE/Forms/LinkDlg.resx @@ -0,0 +1,123 @@ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + text/microsoft-resx + + + 2.0 + + + System.Resources.ResXResourceReader, System.Windows.Forms, Version=4.0.0.0, Culture=neutral, PublicKeyToken=b77a5c561934e089 + + + System.Resources.ResXResourceWriter, System.Windows.Forms, Version=4.0.0.0, Culture=neutral, PublicKeyToken=b77a5c561934e089 + + + LinkDlg + + \ No newline at end of file diff --git a/Labyrinth3/IDE/Forms/MergeElementsDlg.cs b/Labyrinth3/IDE/Forms/MergeElementsDlg.cs new file mode 100644 index 0000000..5028581 --- /dev/null +++ b/Labyrinth3/IDE/Forms/MergeElementsDlg.cs @@ -0,0 +1,272 @@ +// Decompiled with JetBrains decompiler +// Type: Labyrinth.Forms.MergeElementsDlg +// Assembly: Labyrinth, Version=3.6.1928.15690, Culture=neutral, PublicKeyToken=null +// MVID: 1462002E-0BD1-49D2-9B56-C22E66C903E7 +// Assembly location: C:\Dropbox\Workspace\Programs\Labyrinth\Labyrinth.exe + +using Labyrinth.Controls; +using Labyrinth.Plot; +using System; +using System.Collections; +using System.ComponentModel; +using System.Drawing; +using System.Windows.Forms; + +namespace Labyrinth.Forms +{ + public class MergeElementsDlg : Form + { + private Container components = (Container)null; + private bool text = false; + private int selected = 0; + private Label NameLbl; + private Button OKBtn; + private Button CancelBtn; + private Label Step1Lbl; + private ListView ElementList; + private Label Step2Lbl; + private ColumnHeader ElementHdr; + private Label TypeLbl; + private ElementTypeBox TypeBox; + private ComboBox NameBox; + + public MergeElementsDlg() + { + this.InitializeComponent(); + this.ElementList.SmallImageList = LabyrinthData.ElementImages; + this.ElementList.ListViewItemSorter = (IComparer)new ListViewSorter(); + foreach (Element element in LabyrinthData.Project.Elements) + { + ListViewItem listViewItem = this.ElementList.Items.Add(element.Name); + listViewItem.ImageIndex = LabyrinthData.GetImageIndex(element.Type); + listViewItem.Tag = (object)element; + } + this.light_ok(); + } + + protected override void Dispose(bool disposing) + { + if (disposing && this.components != null) + this.components.Dispose(); + base.Dispose(disposing); + } + + private void InitializeComponent() + { + this.NameLbl = new Label(); + this.OKBtn = new Button(); + this.CancelBtn = new Button(); + this.Step1Lbl = new Label(); + this.ElementList = new ListView(); + this.ElementHdr = new ColumnHeader(); + this.Step2Lbl = new Label(); + this.TypeLbl = new Label(); + this.TypeBox = new ElementTypeBox(); + this.NameBox = new ComboBox(); + this.SuspendLayout(); + this.NameLbl.Anchor = AnchorStyles.Bottom | AnchorStyles.Left; + this.NameLbl.Location = new Point(16, 270); + this.NameLbl.Name = "NameLbl"; + this.NameLbl.Size = new Size(48, 23); + this.NameLbl.TabIndex = 3; + this.NameLbl.Text = "Name:"; + this.NameLbl.TextAlign = ContentAlignment.MiddleLeft; + this.OKBtn.Anchor = AnchorStyles.Bottom | AnchorStyles.Right; + this.OKBtn.DialogResult = DialogResult.OK; + this.OKBtn.Location = new Point(192, 344); + this.OKBtn.Name = "OKBtn"; + this.OKBtn.Size = new Size(74, 23); + this.OKBtn.TabIndex = 7; + this.OKBtn.Text = "OK"; + this.OKBtn.Click += new EventHandler(this.OKBtn_Click); + this.CancelBtn.Anchor = AnchorStyles.Bottom | AnchorStyles.Right; + this.CancelBtn.DialogResult = DialogResult.Cancel; + this.CancelBtn.Location = new Point(272, 344); + this.CancelBtn.Name = "CancelBtn"; + this.CancelBtn.Size = new Size(74, 23); + this.CancelBtn.TabIndex = 8; + this.CancelBtn.Text = "Cancel"; + this.Step1Lbl.Anchor = AnchorStyles.Top | AnchorStyles.Left | AnchorStyles.Right; + this.Step1Lbl.Location = new Point(16, 16); + this.Step1Lbl.Name = "Step1Lbl"; + this.Step1Lbl.Size = new Size(328, 23); + this.Step1Lbl.TabIndex = 0; + this.Step1Lbl.Text = "Step 1: Choose the elements to be merged together."; + this.Step1Lbl.TextAlign = ContentAlignment.MiddleLeft; + this.ElementList.Anchor = AnchorStyles.Top | AnchorStyles.Bottom | AnchorStyles.Left | AnchorStyles.Right; + this.ElementList.CheckBoxes = true; + this.ElementList.Columns.AddRange(new ColumnHeader[1] + { + this.ElementHdr + }); + this.ElementList.Location = new Point(16, 48); + this.ElementList.Name = "ElementList"; + this.ElementList.Size = new Size(328, 174); + this.ElementList.TabIndex = 1; + this.ElementList.View = View.Details; + this.ElementList.ColumnClick += new ColumnClickEventHandler(this.ElementList_ColumnClick); + this.ElementList.ItemCheck += new ItemCheckEventHandler(this.ElementList_ItemCheck); + this.ElementHdr.Text = "Element"; + this.ElementHdr.Width = 300; + this.Step2Lbl.Anchor = AnchorStyles.Bottom | AnchorStyles.Left | AnchorStyles.Right; + this.Step2Lbl.Location = new Point(16, 238); + this.Step2Lbl.Name = "Step2Lbl"; + this.Step2Lbl.Size = new Size(328, 23); + this.Step2Lbl.TabIndex = 2; + this.Step2Lbl.Text = "Step 2: Provide a name and type for the new merged element."; + this.Step2Lbl.TextAlign = ContentAlignment.MiddleLeft; + this.TypeLbl.Anchor = AnchorStyles.Bottom | AnchorStyles.Left; + this.TypeLbl.Location = new Point(16, 304); + this.TypeLbl.Name = "TypeLbl"; + this.TypeLbl.Size = new Size(48, 23); + this.TypeLbl.TabIndex = 5; + this.TypeLbl.Text = "Type:"; + this.TypeLbl.TextAlign = ContentAlignment.MiddleLeft; + this.TypeBox.Anchor = AnchorStyles.Bottom | AnchorStyles.Left | AnchorStyles.Right; + this.TypeBox.DrawMode = DrawMode.OwnerDrawVariable; + this.TypeBox.DropDownStyle = ComboBoxStyle.DropDownList; + this.TypeBox.Items.AddRange(new object[52] + { + (object) ElementType.Generic, + (object) ElementType.Character, + (object) ElementType.Organisation, + (object) ElementType.Website, + (object) ElementType.EmailAccount, + (object) ElementType.PhoneNumber, + (object) ElementType.File, + (object) ElementType.Puzzle, + (object) ElementType.Location, + (object) ElementType.Vehicle, + (object) ElementType.Concept, + (object) ElementType.Object, + (object) ElementType.Event, + (object) ElementType.Generic, + (object) ElementType.Character, + (object) ElementType.Organisation, + (object) ElementType.Website, + (object) ElementType.EmailAccount, + (object) ElementType.PhoneNumber, + (object) ElementType.File, + (object) ElementType.Puzzle, + (object) ElementType.Location, + (object) ElementType.Vehicle, + (object) ElementType.Concept, + (object) ElementType.Object, + (object) ElementType.Event, + (object) ElementType.Generic, + (object) ElementType.Character, + (object) ElementType.Organisation, + (object) ElementType.Website, + (object) ElementType.EmailAccount, + (object) ElementType.PhoneNumber, + (object) ElementType.File, + (object) ElementType.Puzzle, + (object) ElementType.Location, + (object) ElementType.Vehicle, + (object) ElementType.Concept, + (object) ElementType.Object, + (object) ElementType.Event, + (object) ElementType.Generic, + (object) ElementType.Character, + (object) ElementType.Organisation, + (object) ElementType.Website, + (object) ElementType.EmailAccount, + (object) ElementType.PhoneNumber, + (object) ElementType.File, + (object) ElementType.Puzzle, + (object) ElementType.Location, + (object) ElementType.Vehicle, + (object) ElementType.Concept, + (object) ElementType.Object, + (object) ElementType.Event + }); + this.TypeBox.Location = new Point(64, 304); + this.TypeBox.Name = "TypeBox"; + this.TypeBox.SelectedElementType = ElementType.Generic; + this.TypeBox.Size = new Size(280, 22); + this.TypeBox.TabIndex = 6; + this.NameBox.Anchor = AnchorStyles.Bottom | AnchorStyles.Left | AnchorStyles.Right; + this.NameBox.Location = new Point(64, 272); + this.NameBox.Name = "NameBox"; + this.NameBox.Size = new Size(280, 21); + this.NameBox.Sorted = true; + this.NameBox.TabIndex = 9; + this.AcceptButton = (IButtonControl)this.OKBtn; + this.AutoScaleBaseSize = new Size(5, 14); + this.CancelButton = (IButtonControl)this.CancelBtn; + this.ClientSize = new Size(360, 382); + this.ControlBox = false; + this.Controls.AddRange(new Control[9] + { + (Control) this.NameBox, + (Control) this.TypeBox, + (Control) this.TypeLbl, + (Control) this.Step2Lbl, + (Control) this.ElementList, + (Control) this.Step1Lbl, + (Control) this.CancelBtn, + (Control) this.OKBtn, + (Control) this.NameLbl + }); + this.Font = new Font("Tahoma", 11f, FontStyle.Regular, GraphicsUnit.World); + this.MaximizeBox = false; + this.MinimizeBox = false; + this.Name = nameof(MergeElementsDlg); + this.ShowInTaskbar = false; + this.SizeGripStyle = SizeGripStyle.Hide; + this.StartPosition = FormStartPosition.CenterParent; + this.Text = "Merge Elements"; + this.ResumeLayout(false); + } + + private void OKBtn_Click(object sender, EventArgs e) + { + ArrayList arrayList = new ArrayList(); + foreach (ListViewItem checkedItem in this.ElementList.CheckedItems) + { + Element tag = checkedItem.Tag as Element; + if (tag != null) + arrayList.Add((object)tag); + } + Element[] array = (Element[])arrayList.ToArray(typeof(Element)); + Element newelement = new Element(); + newelement.Name = this.NameBox.Text; + newelement.Type = this.TypeBox.SelectedElementType; + LabyrinthData.Project.Elements.Add(newelement); + LabyrinthData.Project.MergeElements(array, newelement); + } + + private void NameBox_TextChanged(object sender, EventArgs e) + { + this.text = this.NameBox.Text != ""; + this.light_ok(); + } + + private void ElementList_ItemCheck(object sender, ItemCheckEventArgs e) + { + this.selected = this.ElementList.CheckedItems.Count; + ListViewItem listViewItem = this.ElementList.Items[e.Index]; + if (e.NewValue == CheckState.Checked) + { + ++this.selected; + this.NameBox.Items.Add((object)listViewItem.Text); + } + if (e.NewValue == CheckState.Unchecked) + { + --this.selected; + this.NameBox.Items.Remove((object)listViewItem.Text); + } + this.light_ok(); + } + + private void ElementList_ColumnClick(object sender, ColumnClickEventArgs e) + { + ListViewSorter.Sort(this.ElementList, e.Column); + } + + private void light_ok() + { + this.OKBtn.Enabled = this.text && this.selected > 1; + } + } +} \ No newline at end of file diff --git a/Labyrinth3/IDE/Forms/MergeElementsDlg.resx b/Labyrinth3/IDE/Forms/MergeElementsDlg.resx new file mode 100644 index 0000000..e55f8bc --- /dev/null +++ b/Labyrinth3/IDE/Forms/MergeElementsDlg.resx @@ -0,0 +1,123 @@ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + text/microsoft-resx + + + 2.0 + + + System.Resources.ResXResourceReader, System.Windows.Forms, Version=4.0.0.0, Culture=neutral, PublicKeyToken=b77a5c561934e089 + + + System.Resources.ResXResourceWriter, System.Windows.Forms, Version=4.0.0.0, Culture=neutral, PublicKeyToken=b77a5c561934e089 + + + MergeElementsDlg + + \ No newline at end of file diff --git a/Labyrinth3/IDE/Forms/NoteDlg.cs b/Labyrinth3/IDE/Forms/NoteDlg.cs new file mode 100644 index 0000000..bab7ce9 --- /dev/null +++ b/Labyrinth3/IDE/Forms/NoteDlg.cs @@ -0,0 +1,111 @@ +// Decompiled with JetBrains decompiler +// Type: Labyrinth.Forms.NoteDlg +// Assembly: Labyrinth, Version=3.6.1928.15690, Culture=neutral, PublicKeyToken=null +// MVID: 1462002E-0BD1-49D2-9B56-C22E66C903E7 +// Assembly location: C:\Dropbox\Workspace\Programs\Labyrinth\Labyrinth.exe + +using Labyrinth.Plot; +using System; +using System.ComponentModel; +using System.Drawing; +using System.Windows.Forms; + +namespace Labyrinth.Forms +{ + public class NoteDlg : Form + { + private Container components = (Container)null; + private Note fNote = (Note)null; + private Label NameLbl; + private TextBox NameBox; + private Button OKBtn; + private Button CancelBtn; + private CheckBox TemplateBox; + + public NoteDlg(Note n) + { + this.InitializeComponent(); + this.fNote = n; + this.NameBox.Text = this.fNote.Title; + this.TemplateBox.Checked = this.fNote.IsTemplate; + } + + protected override void Dispose(bool disposing) + { + if (disposing && this.components != null) + this.components.Dispose(); + base.Dispose(disposing); + } + + private void InitializeComponent() + { + this.NameLbl = new Label(); + this.NameBox = new TextBox(); + this.OKBtn = new Button(); + this.CancelBtn = new Button(); + this.TemplateBox = new CheckBox(); + this.SuspendLayout(); + this.NameLbl.Location = new Point(16, 24); + this.NameLbl.Name = "NameLbl"; + this.NameLbl.Size = new Size(48, 23); + this.NameLbl.TabIndex = 0; + this.NameLbl.Text = "Name:"; + this.NameLbl.TextAlign = ContentAlignment.MiddleLeft; + this.NameBox.Anchor = AnchorStyles.Top | AnchorStyles.Left | AnchorStyles.Right; + this.NameBox.Location = new Point(64, 24); + this.NameBox.Name = "NameBox"; + this.NameBox.Size = new Size(216, 21); + this.NameBox.TabIndex = 1; + this.NameBox.Text = ""; + this.OKBtn.Anchor = AnchorStyles.Bottom | AnchorStyles.Right; + this.OKBtn.DialogResult = DialogResult.OK; + this.OKBtn.Location = new Point(128, 106); + this.OKBtn.Name = "OKBtn"; + this.OKBtn.Size = new Size(72, 23); + this.OKBtn.TabIndex = 3; + this.OKBtn.Text = "OK"; + this.OKBtn.Click += new EventHandler(this.OKBtn_Click); + this.CancelBtn.Anchor = AnchorStyles.Bottom | AnchorStyles.Right; + this.CancelBtn.DialogResult = DialogResult.Cancel; + this.CancelBtn.Location = new Point(208, 106); + this.CancelBtn.Name = "CancelBtn"; + this.CancelBtn.Size = new Size(72, 23); + this.CancelBtn.TabIndex = 4; + this.CancelBtn.Text = "Cancel"; + this.TemplateBox.Location = new Point(16, 64); + this.TemplateBox.Name = "TemplateBox"; + this.TemplateBox.Size = new Size(264, 24); + this.TemplateBox.TabIndex = 2; + this.TemplateBox.Text = "This note is an annotation template"; + this.AcceptButton = (IButtonControl)this.OKBtn; + this.AutoScaleBaseSize = new Size(5, 14); + this.CancelButton = (IButtonControl)this.CancelBtn; + this.ClientSize = new Size(292, 144); + this.ControlBox = false; + this.Controls.AddRange(new Control[5] + { + (Control) this.TemplateBox, + (Control) this.CancelBtn, + (Control) this.OKBtn, + (Control) this.NameBox, + (Control) this.NameLbl + }); + this.Font = new Font("Tahoma", 11f, FontStyle.Regular, GraphicsUnit.World); + this.FormBorderStyle = FormBorderStyle.FixedDialog; + this.MaximizeBox = false; + this.MinimizeBox = false; + this.Name = nameof(NoteDlg); + this.ShowInTaskbar = false; + this.SizeGripStyle = SizeGripStyle.Hide; + this.StartPosition = FormStartPosition.CenterParent; + this.Text = "Note Properties"; + this.ResumeLayout(false); + } + + private void OKBtn_Click(object sender, EventArgs e) + { + this.fNote.Title = this.NameBox.Text; + this.fNote.IsTemplate = this.TemplateBox.Checked; + } + } +} \ No newline at end of file diff --git a/Labyrinth3/IDE/Forms/NoteDlg.resx b/Labyrinth3/IDE/Forms/NoteDlg.resx new file mode 100644 index 0000000..b69e2c7 --- /dev/null +++ b/Labyrinth3/IDE/Forms/NoteDlg.resx @@ -0,0 +1,123 @@ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + text/microsoft-resx + + + 2.0 + + + System.Resources.ResXResourceReader, System.Windows.Forms, Version=4.0.0.0, Culture=neutral, PublicKeyToken=b77a5c561934e089 + + + System.Resources.ResXResourceWriter, System.Windows.Forms, Version=4.0.0.0, Culture=neutral, PublicKeyToken=b77a5c561934e089 + + + NoteDlg + + \ No newline at end of file diff --git a/Labyrinth3/IDE/Forms/ProjectDlg.cs b/Labyrinth3/IDE/Forms/ProjectDlg.cs new file mode 100644 index 0000000..6c294b2 --- /dev/null +++ b/Labyrinth3/IDE/Forms/ProjectDlg.cs @@ -0,0 +1,101 @@ +// Decompiled with JetBrains decompiler +// Type: Labyrinth.Forms.ProjectDlg +// Assembly: Labyrinth, Version=3.6.1928.15690, Culture=neutral, PublicKeyToken=null +// MVID: 1462002E-0BD1-49D2-9B56-C22E66C903E7 +// Assembly location: C:\Dropbox\Workspace\Programs\Labyrinth\Labyrinth.exe + +using Labyrinth.Plot; +using System; +using System.ComponentModel; +using System.Drawing; +using System.Windows.Forms; + +namespace Labyrinth.Forms +{ + public class ProjectDlg : Form + { + private Container components = (Container)null; + private Project fProject = (Project)null; + private Label NameLbl; + private TextBox NameBox; + private Button OKBtn; + private Button CancelBtn; + + public ProjectDlg(Project p) + { + this.InitializeComponent(); + this.fProject = p; + this.NameBox.Text = this.fProject.Name; + } + + protected override void Dispose(bool disposing) + { + if (disposing && this.components != null) + this.components.Dispose(); + base.Dispose(disposing); + } + + private void InitializeComponent() + { + this.NameLbl = new Label(); + this.NameBox = new TextBox(); + this.OKBtn = new Button(); + this.CancelBtn = new Button(); + this.SuspendLayout(); + this.NameLbl.Location = new Point(16, 24); + this.NameLbl.Name = "NameLbl"; + this.NameLbl.Size = new Size(48, 23); + this.NameLbl.TabIndex = 0; + this.NameLbl.Text = "Name:"; + this.NameLbl.TextAlign = ContentAlignment.MiddleLeft; + this.NameBox.Anchor = AnchorStyles.Top | AnchorStyles.Left | AnchorStyles.Right; + this.NameBox.Location = new Point(64, 24); + this.NameBox.Name = "NameBox"; + this.NameBox.Size = new Size(216, 21); + this.NameBox.TabIndex = 1; + this.NameBox.Text = ""; + this.OKBtn.Anchor = AnchorStyles.Bottom | AnchorStyles.Right; + this.OKBtn.DialogResult = DialogResult.OK; + this.OKBtn.Location = new Point(128, 64); + this.OKBtn.Name = "OKBtn"; + this.OKBtn.Size = new Size(72, 23); + this.OKBtn.TabIndex = 2; + this.OKBtn.Text = "OK"; + this.OKBtn.Click += new EventHandler(this.OKBtn_Click); + this.CancelBtn.Anchor = AnchorStyles.Bottom | AnchorStyles.Right; + this.CancelBtn.DialogResult = DialogResult.Cancel; + this.CancelBtn.Location = new Point(208, 64); + this.CancelBtn.Name = "CancelBtn"; + this.CancelBtn.Size = new Size(72, 23); + this.CancelBtn.TabIndex = 3; + this.CancelBtn.Text = "Cancel"; + this.AcceptButton = (IButtonControl)this.OKBtn; + this.AutoScaleBaseSize = new Size(5, 14); + this.CancelButton = (IButtonControl)this.CancelBtn; + this.ClientSize = new Size(292, 102); + this.ControlBox = false; + this.Controls.AddRange(new Control[4] + { + (Control) this.CancelBtn, + (Control) this.OKBtn, + (Control) this.NameBox, + (Control) this.NameLbl + }); + this.Font = new Font("Tahoma", 11f, FontStyle.Regular, GraphicsUnit.World); + this.FormBorderStyle = FormBorderStyle.FixedDialog; + this.MaximizeBox = false; + this.MinimizeBox = false; + this.Name = nameof(ProjectDlg); + this.ShowInTaskbar = false; + this.SizeGripStyle = SizeGripStyle.Hide; + this.StartPosition = FormStartPosition.CenterParent; + this.Text = "Project Properties"; + this.ResumeLayout(false); + } + + private void OKBtn_Click(object sender, EventArgs e) + { + this.fProject.Name = this.NameBox.Text; + } + } +} \ No newline at end of file diff --git a/Labyrinth3/IDE/Forms/ProjectDlg.resx b/Labyrinth3/IDE/Forms/ProjectDlg.resx new file mode 100644 index 0000000..040e060 --- /dev/null +++ b/Labyrinth3/IDE/Forms/ProjectDlg.resx @@ -0,0 +1,123 @@ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + text/microsoft-resx + + + 2.0 + + + System.Resources.ResXResourceReader, System.Windows.Forms, Version=4.0.0.0, Culture=neutral, PublicKeyToken=b77a5c561934e089 + + + System.Resources.ResXResourceWriter, System.Windows.Forms, Version=4.0.0.0, Culture=neutral, PublicKeyToken=b77a5c561934e089 + + + ProjectDlg + + \ No newline at end of file diff --git a/Labyrinth3/IDE/Forms/SketchAnnotationDlg.cs b/Labyrinth3/IDE/Forms/SketchAnnotationDlg.cs new file mode 100644 index 0000000..d294127 --- /dev/null +++ b/Labyrinth3/IDE/Forms/SketchAnnotationDlg.cs @@ -0,0 +1,419 @@ +// Decompiled with JetBrains decompiler +// Type: Labyrinth.Forms.SketchAnnotationDlg +// Assembly: Labyrinth, Version=3.6.1928.15690, Culture=neutral, PublicKeyToken=null +// MVID: 1462002E-0BD1-49D2-9B56-C22E66C903E7 +// Assembly location: C:\Dropbox\Workspace\Programs\Labyrinth\Labyrinth.exe + +using Labyrinth.Controls; +using Labyrinth.Plot; +using System; +using System.ComponentModel; +using System.Drawing; +using System.Drawing.Printing; +using System.Resources; +using System.Windows.Forms; + +namespace Labyrinth.Forms +{ + public class SketchAnnotationDlg : Form + { + private SketchAnnotation fNote = (SketchAnnotation)null; + private int fToolSize = 5; + private Color fForeColor = Color.Black; + private Color fBackColor = Color.White; + private Point fLastPoint = Point.Empty; + private ImageList ToolbarImages; + private Label TitleLbl; + private TextBox TitleBox; + private Button OKBtn; + private Button CancelBtn; + private TextBox DescBox; + private Label DescLbl; + private Panel ImagePanel; + private ToolBar Toolbar; + private PictureBox SketchBox; + private ToolBarButton ClearBtn; + private ColorPanel ColorPanel; + private Label SizeLbl; + private NumericUpDown SizeBox; + private ToolBarButton PrintBtn; + private ToolBarButton PrintPreviewBtn; + private ToolBarButton Sep1; + private ToolBarButton BrowseBtn; + private ToolBarButton FlipVertBtn; + private ToolBarButton FlipHorBtn; + private ToolBarButton RotClockBtn; + private ToolBarButton RotAntiBtn; + private ToolBarButton Sep2; + private ToolBarButton Sep3; + private IContainer components; + + public SketchAnnotationDlg(SketchAnnotation note) + { + this.InitializeComponent(); + this.fNote = note; + this.ColorPanel.Color1 = this.fForeColor; + this.ColorPanel.Color2 = this.fBackColor; + this.SizeBox.Value = (Decimal)this.fToolSize; + this.TitleBox.Text = this.fNote.Title; + this.DescBox.Text = this.fNote.Content; + this.SketchBox.Image = this.fNote.Sketch.Clone() as Image; + } + + protected override void Dispose(bool disposing) + { + if (disposing && this.components != null) + this.components.Dispose(); + base.Dispose(disposing); + } + + private void InitializeComponent() + { + this.components = (IContainer)new Container(); + ResourceManager resourceManager = new ResourceManager(typeof(SketchAnnotationDlg)); + this.ToolbarImages = new ImageList(this.components); + this.OKBtn = new Button(); + this.CancelBtn = new Button(); + this.TitleLbl = new Label(); + this.TitleBox = new TextBox(); + this.DescBox = new TextBox(); + this.DescLbl = new Label(); + this.ImagePanel = new Panel(); + this.SketchBox = new PictureBox(); + this.Toolbar = new ToolBar(); + this.PrintBtn = new ToolBarButton(); + this.PrintPreviewBtn = new ToolBarButton(); + this.Sep1 = new ToolBarButton(); + this.ClearBtn = new ToolBarButton(); + this.BrowseBtn = new ToolBarButton(); + this.ColorPanel = new ColorPanel(); + this.SizeLbl = new Label(); + this.SizeBox = new NumericUpDown(); + this.FlipVertBtn = new ToolBarButton(); + this.FlipHorBtn = new ToolBarButton(); + this.RotClockBtn = new ToolBarButton(); + this.RotAntiBtn = new ToolBarButton(); + this.Sep2 = new ToolBarButton(); + this.Sep3 = new ToolBarButton(); + this.ImagePanel.SuspendLayout(); + this.SizeBox.BeginInit(); + this.SuspendLayout(); + this.ToolbarImages.ColorDepth = ColorDepth.Depth8Bit; + this.ToolbarImages.ImageSize = new Size(16, 16); + this.ToolbarImages.ImageStream = (ImageListStreamer)resourceManager.GetObject("ToolbarImages.ImageStream"); + this.ToolbarImages.TransparentColor = Color.Magenta; + this.OKBtn.Anchor = AnchorStyles.Bottom | AnchorStyles.Right; + this.OKBtn.DialogResult = DialogResult.OK; + this.OKBtn.Location = new Point(348, 360); + this.OKBtn.Name = "OKBtn"; + this.OKBtn.TabIndex = 8; + this.OKBtn.Text = "OK"; + this.OKBtn.Click += new EventHandler(this.OKBtn_Click); + this.CancelBtn.Anchor = AnchorStyles.Bottom | AnchorStyles.Right; + this.CancelBtn.DialogResult = DialogResult.Cancel; + this.CancelBtn.Location = new Point(428, 360); + this.CancelBtn.Name = "CancelBtn"; + this.CancelBtn.TabIndex = 9; + this.CancelBtn.Text = "Cancel"; + this.TitleLbl.Location = new Point(16, 16); + this.TitleLbl.Name = "TitleLbl"; + this.TitleLbl.Size = new Size(64, 23); + this.TitleLbl.TabIndex = 0; + this.TitleLbl.Text = "Title:"; + this.TitleLbl.TextAlign = ContentAlignment.MiddleLeft; + this.TitleBox.Anchor = AnchorStyles.Top | AnchorStyles.Left | AnchorStyles.Right; + this.TitleBox.Location = new Point(88, 16); + this.TitleBox.Name = "TitleBox"; + this.TitleBox.Size = new Size(416, 21); + this.TitleBox.TabIndex = 1; + this.TitleBox.Text = ""; + this.DescBox.Anchor = AnchorStyles.Top | AnchorStyles.Left | AnchorStyles.Right; + this.DescBox.Location = new Point(88, 48); + this.DescBox.Name = "DescBox"; + this.DescBox.Size = new Size(416, 21); + this.DescBox.TabIndex = 3; + this.DescBox.Text = ""; + this.DescLbl.Location = new Point(16, 48); + this.DescLbl.Name = "DescLbl"; + this.DescLbl.Size = new Size(64, 23); + this.DescLbl.TabIndex = 2; + this.DescLbl.Text = "Description:"; + this.DescLbl.TextAlign = ContentAlignment.MiddleLeft; + this.ImagePanel.Anchor = AnchorStyles.Top | AnchorStyles.Bottom | AnchorStyles.Left | AnchorStyles.Right; + this.ImagePanel.Controls.AddRange(new Control[2] + { + (Control) this.SketchBox, + (Control) this.Toolbar + }); + this.ImagePanel.Location = new Point(16, 88); + this.ImagePanel.Name = "ImagePanel"; + this.ImagePanel.Size = new Size(488, 256); + this.ImagePanel.TabIndex = 4; + this.SketchBox.BorderStyle = BorderStyle.Fixed3D; + this.SketchBox.Cursor = Cursors.Cross; + this.SketchBox.Dock = DockStyle.Fill; + this.SketchBox.Location = new Point(0, 25); + this.SketchBox.Name = "SketchBox"; + this.SketchBox.Size = new Size(488, 231); + this.SketchBox.SizeMode = PictureBoxSizeMode.StretchImage; + this.SketchBox.TabIndex = 1; + this.SketchBox.TabStop = false; + this.SketchBox.MouseUp += new MouseEventHandler(this.SketchBox_MouseUp); + this.SketchBox.MouseMove += new MouseEventHandler(this.SketchBox_MouseMove); + this.SketchBox.MouseDown += new MouseEventHandler(this.SketchBox_MouseDown); + this.Toolbar.Appearance = ToolBarAppearance.Flat; + this.Toolbar.Buttons.AddRange(new ToolBarButton[11] + { + this.BrowseBtn, + this.Sep1, + this.PrintBtn, + this.PrintPreviewBtn, + this.Sep2, + this.ClearBtn, + this.Sep3, + this.FlipVertBtn, + this.FlipHorBtn, + this.RotClockBtn, + this.RotAntiBtn + }); + this.Toolbar.DropDownArrows = true; + this.Toolbar.ImageList = this.ToolbarImages; + this.Toolbar.Name = "Toolbar"; + this.Toolbar.ShowToolTips = true; + this.Toolbar.Size = new Size(488, 25); + this.Toolbar.TabIndex = 0; + this.Toolbar.ButtonClick += new ToolBarButtonClickEventHandler(this.Toolbar_ButtonClick); + this.PrintBtn.ImageIndex = 0; + this.PrintBtn.ToolTipText = "Print"; + this.PrintPreviewBtn.ImageIndex = 1; + this.PrintPreviewBtn.ToolTipText = "Print Preview"; + this.Sep1.Style = ToolBarButtonStyle.Separator; + this.ClearBtn.ImageIndex = 2; + this.ClearBtn.ToolTipText = "Clear"; + this.BrowseBtn.ImageIndex = 3; + this.BrowseBtn.ToolTipText = "Browse"; + this.ColorPanel.Anchor = AnchorStyles.Bottom | AnchorStyles.Left; + this.ColorPanel.BorderStyle = BorderStyle.Fixed3D; + this.ColorPanel.Color1 = Color.Black; + this.ColorPanel.Color2 = Color.White; + this.ColorPanel.Location = new Point(16, 352); + this.ColorPanel.Name = "ColorPanel"; + this.ColorPanel.Size = new Size(32, 32); + this.ColorPanel.TabIndex = 5; + this.ColorPanel.ForeColorClick += new EventHandler(this.ColorPanel_ForeColorClick); + this.ColorPanel.BackColorClick += new EventHandler(this.ColorPanel_BackColorClick); + this.SizeLbl.Anchor = AnchorStyles.Bottom | AnchorStyles.Left; + this.SizeLbl.Location = new Point(64, 360); + this.SizeLbl.Name = "SizeLbl"; + this.SizeLbl.Size = new Size(64, 23); + this.SizeLbl.TabIndex = 6; + this.SizeLbl.Text = "Tool size:"; + this.SizeLbl.TextAlign = ContentAlignment.MiddleLeft; + this.SizeBox.Anchor = AnchorStyles.Bottom | AnchorStyles.Left; + this.SizeBox.Location = new Point(136, 360); + this.SizeBox.Name = "SizeBox"; + this.SizeBox.Size = new Size(56, 21); + this.SizeBox.TabIndex = 7; + this.SizeBox.ValueChanged += new EventHandler(this.SizeBox_ValueChanged); + this.FlipVertBtn.ImageIndex = 5; + this.FlipVertBtn.ToolTipText = "Flip Vertically"; + this.FlipHorBtn.ImageIndex = 4; + this.FlipHorBtn.ToolTipText = "Flip Horizontally"; + this.RotClockBtn.ImageIndex = 6; + this.RotClockBtn.ToolTipText = "Rotate Clockwise"; + this.RotAntiBtn.ImageIndex = 7; + this.RotAntiBtn.ToolTipText = "Rotate Anticlockwise"; + this.Sep2.Style = ToolBarButtonStyle.Separator; + this.Sep3.Style = ToolBarButtonStyle.Separator; + this.AutoScaleBaseSize = new Size(5, 14); + this.CancelButton = (IButtonControl)this.CancelBtn; + this.ClientSize = new Size(520, 398); + this.Controls.AddRange(new Control[10] + { + (Control) this.SizeBox, + (Control) this.SizeLbl, + (Control) this.ColorPanel, + (Control) this.ImagePanel, + (Control) this.DescBox, + (Control) this.DescLbl, + (Control) this.TitleBox, + (Control) this.TitleLbl, + (Control) this.CancelBtn, + (Control) this.OKBtn + }); + this.Font = new Font("Tahoma", 11f, FontStyle.Regular, GraphicsUnit.World, (byte)0); + this.Icon = (Icon)resourceManager.GetObject("$this.Icon"); + this.MinimizeBox = false; + this.Name = nameof(SketchAnnotationDlg); + this.ShowInTaskbar = false; + this.SizeGripStyle = SizeGripStyle.Hide; + this.StartPosition = FormStartPosition.CenterParent; + this.Text = "Sketch Annotation Properties"; + this.ImagePanel.ResumeLayout(false); + this.SizeBox.EndInit(); + this.ResumeLayout(false); + } + + private void OKBtn_Click(object sender, EventArgs e) + { + this.fNote.Title = this.TitleBox.Text; + this.fNote.Content = this.DescBox.Text; + this.fNote.Sketch = this.SketchBox.Image; + } + + private void SketchBox_MouseDown(object sender, MouseEventArgs e) + { + if (e.Button == MouseButtons.Left) + this.draw(this.fForeColor); + if (e.Button != MouseButtons.Right) + return; + this.draw(this.fBackColor); + } + + private void SketchBox_MouseMove(object sender, MouseEventArgs e) + { + if (e.Button == MouseButtons.Left) + this.draw(this.fForeColor); + if (e.Button != MouseButtons.Right) + return; + this.draw(this.fBackColor); + } + + private void SketchBox_MouseUp(object sender, MouseEventArgs e) + { + this.fLastPoint = Point.Empty; + } + + private Point get_pixel() + { + Point client = this.SketchBox.PointToClient(Cursor.Position); + return new Point(client.X * this.SketchBox.Image.Width / this.SketchBox.Width, client.Y * this.SketchBox.Image.Height / this.SketchBox.Height); + } + + private void draw(Color c) + { + Point pixel = this.get_pixel(); + if (!this.fLastPoint.IsEmpty) + { + Graphics.FromImage(this.SketchBox.Image).DrawLine(new Pen(c, (float)this.fToolSize), this.fLastPoint, pixel); + this.SketchBox.Refresh(); + } + this.fLastPoint = pixel; + } + + private void Toolbar_ButtonClick(object sender, ToolBarButtonClickEventArgs e) + { + if (e.Button == this.PrintBtn) + { + PrintDialog printDialog = new PrintDialog(); + printDialog.Document = this.create_print_doc(); + if (printDialog.ShowDialog() != DialogResult.OK) + return; + for (int index = 0; index != (int)printDialog.PrinterSettings.Copies; ++index) + printDialog.Document.Print(); + } + else if (e.Button == this.PrintPreviewBtn) + { + int num = (int)new PrintPreviewDialog() + { + Document = this.create_print_doc() + }.ShowDialog(); + } + else if (e.Button == this.ClearBtn) + { + Graphics.FromImage(this.SketchBox.Image).Clear(this.fBackColor); + this.SketchBox.Refresh(); + } + else if (e.Button == this.BrowseBtn) + { + OpenFileDialog openFileDialog = new OpenFileDialog(); + openFileDialog.Filter = "Image Files|*.jpg;*.jpeg;*.gif;*.bmp| All Files|*.*"; + if (openFileDialog.ShowDialog() != DialogResult.OK || MessageBox.Show("Do you want to replace your sketch with the contents of this file?", "Labyrinth", MessageBoxButtons.YesNo, MessageBoxIcon.Question) != DialogResult.Yes) + return; + this.SketchBox.Image = (Image)new Bitmap(Image.FromFile(openFileDialog.FileName), this.SketchBox.Image.Size); + } + else if (e.Button == this.FlipVertBtn) + { + this.SketchBox.Image.RotateFlip(RotateFlipType.Rotate180FlipX); + this.SketchBox.Refresh(); + } + else if (e.Button == this.FlipHorBtn) + { + this.SketchBox.Image.RotateFlip(RotateFlipType.RotateNoneFlipX); + this.SketchBox.Refresh(); + } + else if (e.Button == this.RotClockBtn) + { + this.SketchBox.Image.RotateFlip(RotateFlipType.Rotate90FlipNone); + this.SketchBox.Refresh(); + } + else + { + if (e.Button != this.RotAntiBtn) + return; + this.SketchBox.Image.RotateFlip(RotateFlipType.Rotate270FlipNone); + this.SketchBox.Refresh(); + } + } + + private PrintDocument create_print_doc() + { + PrintDocument printDocument = new PrintDocument(); + printDocument.DocumentName = LabyrinthData.Project.Name + ": " + this.fNote.Title; + printDocument.PrintController = (PrintController)new StandardPrintController(); + printDocument.DefaultPageSettings = LabyrinthData.PageSettings; + printDocument.PrinterSettings = LabyrinthData.PrinterSettings; + printDocument.PrintPage += new PrintPageEventHandler(this.PrintPage); + return printDocument; + } + + private void PrintPage(object sender, PrintPageEventArgs e) + { + StringFormat format = new StringFormat(); + format.Alignment = StringAlignment.Center; + format.LineAlignment = StringAlignment.Center; + format.Trimming = StringTrimming.EllipsisCharacter; + string str = LabyrinthData.Project.Name + ": " + this.fNote.Title; + int height = (int)e.Graphics.MeasureString(str, this.Font, e.MarginBounds.Width).Height; + RectangleF layoutRectangle; + Rectangle marginBounds1 = e.MarginBounds; + double x = (double)marginBounds1.X; + marginBounds1 = e.MarginBounds; + double y = (double)marginBounds1.Y; + marginBounds1 = e.MarginBounds; + double width = (double)marginBounds1.Width; + double num = (double)height; + layoutRectangle = new RectangleF((float)x, (float)y, (float)width, (float)num); + e.Graphics.DrawString(str, this.Font, SystemBrushes.WindowText, layoutRectangle, format); + Rectangle marginBounds2 = e.MarginBounds; + marginBounds2.Y += height; + marginBounds2.Height -= height; + e.Graphics.DrawImage(this.SketchBox.Image, marginBounds2); + } + + private void ColorPanel_ForeColorClick(object sender, EventArgs e) + { + ColorDialog colorDialog = new ColorDialog(); + colorDialog.Color = this.fForeColor; + if (colorDialog.ShowDialog() != DialogResult.OK) + return; + this.fForeColor = colorDialog.Color; + this.ColorPanel.Color1 = colorDialog.Color; + } + + private void ColorPanel_BackColorClick(object sender, EventArgs e) + { + ColorDialog colorDialog = new ColorDialog(); + colorDialog.Color = this.fBackColor; + if (colorDialog.ShowDialog() != DialogResult.OK) + return; + this.fBackColor = colorDialog.Color; + this.ColorPanel.Color2 = colorDialog.Color; + } + + private void SizeBox_ValueChanged(object sender, EventArgs e) + { + this.fToolSize = (int)this.SizeBox.Value; + } + } +} \ No newline at end of file diff --git a/Labyrinth3/IDE/Forms/SketchAnnotationDlg.resx b/Labyrinth3/IDE/Forms/SketchAnnotationDlg.resx new file mode 100644 index 0000000..e07b5b7 --- /dev/null +++ b/Labyrinth3/IDE/Forms/SketchAnnotationDlg.resx @@ -0,0 +1,193 @@ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + text/microsoft-resx + + + 2.0 + + + System.Resources.ResXResourceReader, System.Windows.Forms, Version=4.0.0.0, Culture=neutral, PublicKeyToken=b77a5c561934e089 + + + System.Resources.ResXResourceWriter, System.Windows.Forms, Version=4.0.0.0, Culture=neutral, PublicKeyToken=b77a5c561934e089 + + + + + AAABAAEAEBAQAAAAAAAoAQAAFgAAACgAAAAQAAAAIAAAAAEABAAAAAAAgAAAAAAAAAAAAAAAEAAAABAA + AAAAAAAAAACAAACAAAAAgIAAgAAAAIAAgACAgAAAgICAAMDAwAAAAP8AAP8AAAD//wD/AAAA/wD/AP// + AAD///8AAAAAAAAAAAAAAAAAAAAAAAAA//8AAAAAAADyLwAAAAAHsPufDwD7AAfw/J8LCA8AB7D8vw8L + gAAH8PzPCwAAAAew//8Pv78AB/AAAAv7+wAHv7+/v7+/AAd3d3d3d3cAAAAAAAAAAAAAAAAAAAAAAAAA + AAAAAAAAAAAAAAAAAAD//wAA4H8AAOB/AACAAQAAgAEAAIABAACAAQAAgAEAAIABAACAAQAAgAEAAIAB + AAD//wAA//8AAP//AAD//wAA + + + + SketchAnnotationDlg + + + 17, 17 + + + + 57 + + + + AAEAAAD/////AQAAAAAAAAAMAgAAAFdTeXN0ZW0uV2luZG93cy5Gb3JtcywgVmVyc2lvbj00LjAuMC4w + LCBDdWx0dXJlPW5ldXRyYWwsIFB1YmxpY0tleVRva2VuPWI3N2E1YzU2MTkzNGUwODkFAQAAACZTeXN0 + ZW0uV2luZG93cy5Gb3Jtcy5JbWFnZUxpc3RTdHJlYW1lcgEAAAAERGF0YQcCAgAAAAkDAAAADwMAAABq + CgAAAk1TRnQBSQFMAgEBCAEAAQkBAAEIAQABEAEAARABAAT/AQkBEAj/AUIBTQE2AQQGAAE2AQQCAAEo + AwABQAMAATADAAEBAQABCAYAAQwYAAGAAgABgAMAAoABAAGAAwABgAEAAYABAAKAAgADwAEAAcAB3AHA + AQAB8AHKAaYBAAEzBQABMwEAATMBAAEzAQACMwIAAxYBAAMcAQADIgEAAykBAANVAQADTQEAA0IBAAM5 + AQABgAF8Af8BAAJQAf8BAAGTAQAB1gEAAf8B7AHMAQABxgHWAe8BAAHWAucBAAGQAakBrQIAAf8BMwMA + AWYDAAGZAwABzAIAATMDAAIzAgABMwFmAgABMwGZAgABMwHMAgABMwH/AgABZgMAAWYBMwIAAmYCAAFm + AZkCAAFmAcwCAAFmAf8CAAGZAwABmQEzAgABmQFmAgACmQIAAZkBzAIAAZkB/wIAAcwDAAHMATMCAAHM + AWYCAAHMAZkCAALMAgABzAH/AgAB/wFmAgAB/wGZAgAB/wHMAQABMwH/AgAB/wEAATMBAAEzAQABZgEA + ATMBAAGZAQABMwEAAcwBAAEzAQAB/wEAAf8BMwIAAzMBAAIzAWYBAAIzAZkBAAIzAcwBAAIzAf8BAAEz + AWYCAAEzAWYBMwEAATMCZgEAATMBZgGZAQABMwFmAcwBAAEzAWYB/wEAATMBmQIAATMBmQEzAQABMwGZ + AWYBAAEzApkBAAEzAZkBzAEAATMBmQH/AQABMwHMAgABMwHMATMBAAEzAcwBZgEAATMBzAGZAQABMwLM + AQABMwHMAf8BAAEzAf8BMwEAATMB/wFmAQABMwH/AZkBAAEzAf8BzAEAATMC/wEAAWYDAAFmAQABMwEA + AWYBAAFmAQABZgEAAZkBAAFmAQABzAEAAWYBAAH/AQABZgEzAgABZgIzAQABZgEzAWYBAAFmATMBmQEA + AWYBMwHMAQABZgEzAf8BAAJmAgACZgEzAQADZgEAAmYBmQEAAmYBzAEAAWYBmQIAAWYBmQEzAQABZgGZ + AWYBAAFmApkBAAFmAZkBzAEAAWYBmQH/AQABZgHMAgABZgHMATMBAAFmAcwBmQEAAWYCzAEAAWYBzAH/ + AQABZgH/AgABZgH/ATMBAAFmAf8BmQEAAWYB/wHMAQABzAEAAf8BAAH/AQABzAEAApkCAAGZATMBmQEA + AZkBAAGZAQABmQEAAcwBAAGZAwABmQIzAQABmQEAAWYBAAGZATMBzAEAAZkBAAH/AQABmQFmAgABmQFm + ATMBAAGZATMBZgEAAZkBZgGZAQABmQFmAcwBAAGZATMB/wEAApkBMwEAApkBZgEAA5kBAAKZAcwBAAKZ + Af8BAAGZAcwCAAGZAcwBMwEAAWYBzAFmAQABmQHMAZkBAAGZAswBAAGZAcwB/wEAAZkB/wIAAZkB/wEz + AQABmQHMAWYBAAGZAf8BmQEAAZkB/wHMAQABmQL/AQABzAMAAZkBAAEzAQABzAEAAWYBAAHMAQABmQEA + AcwBAAHMAQABmQEzAgABzAIzAQABzAEzAWYBAAHMATMBmQEAAcwBMwHMAQABzAEzAf8BAAHMAWYCAAHM + AWYBMwEAAZkCZgEAAcwBZgGZAQABzAFmAcwBAAGZAWYB/wEAAcwBmQIAAcwBmQEzAQABzAGZAWYBAAHM + ApkBAAHMAZkBzAEAAcwBmQH/AQACzAIAAswBMwEAAswBZgEAAswBmQEAA8wBAALMAf8BAAHMAf8CAAHM + Af8BMwEAAZkB/wFmAQABzAH/AZkBAAHMAf8BzAEAAcwC/wEAAcwBAAEzAQAB/wEAAWYBAAH/AQABmQEA + AcwBMwIAAf8CMwEAAf8BMwFmAQAB/wEzAZkBAAH/ATMBzAEAAf8BMwH/AQAB/wFmAgAB/wFmATMBAAHM + AmYBAAH/AWYBmQEAAf8BZgHMAQABzAFmAf8BAAH/AZkCAAH/AZkBMwEAAf8BmQFmAQAB/wKZAQAB/wGZ + AcwBAAH/AZkB/wEAAf8BzAIAAf8BzAEzAQAB/wHMAWYBAAH/AcwBmQEAAf8CzAEAAf8BzAH/AQAC/wEz + AQABzAH/AWYBAAL/AZkBAAL/AcwBAAJmAf8BAAFmAf8BZgEAAWYC/wEAAf8CZgEAAf8BZgH/AQAC/wFm + AQABIQEAAaUBAANfAQADdwEAA4YBAAOWAQADywEAA7IBAAPXAQAD3QEAA+MBAAPqAQAD8QEAA/gBAAHw + AfsB/wEAAaQCoAEAA4ADAAH/AgAB/wMAAv8BAAH/AwAB/wEAAf8BAAL/AgAD//8A/wD/AP8AjAAC7D4A + AuwOAAIBDgAC7A4AAuwOAALsDQAEAQwABOwMAATsCwABAQEAAuwBAAEBCgAGAQsABOwMAATsCgACAQEA + AuwBAAIBCwACAQ4AAuwCAAQBAgAEAQIAAuwKAAoBBQAF7AIBBewEAAIBCAADAQIAAwEIAAIBBQAKAQUA + BewCAQXsBAACAQgAAwECAAMBCAACAQYAAgEBAALsAQACAQsAAgEKAAMBBAADAQEAAQECAAEBAQADAQQA + AwEIAAEBAQAC7AEAAQEKAAYBCQAIAQgACAELAALsDQAEAQwABAEMAAQBDQAC7A4AAgEuAALs/wBJAAr/ + JwAJBwEAAQcEAAf/GgAJAxIAAQcDAAb/AgACBxYAAfsBAAkDBQAGBwP7AgcFAAX/AgACBwH+FgAB/wH7 + AQAJAwQABgcDAAIHAQABBwMABf8BAAQHFgAB+wH/AfsBAAkDDwACBwIABf8BAAEHAf4CBxYAAf8B+wH/ + AfsMAAoHAQABBwEAAQcCAAX/AgAC/gEHFgAB+wH/AfsB/wH7Af8B+wH/AfsRAAEHAQABBwMABv8CAAIH + FgAB/wH7Af8B+wH/AfsB/wH7Af8JAAj/AQABBwEAAQcCAAf/GQAB+wH/AfsQAAH/BQAB/wYACv8pAAj/ + BQAH/y0AAf8FAAH/BQAH/wEAAQcrAAj/BAAH/2gAAUIBTQE+BwABPgMAASgDAAFAAwABMAMAAQEBAAEB + BQABgAEBFgAD/4EAEP8B/gF/Bv8B/gF/Af4BfwH+AX8B/gF/Af4BfwH8AT8B/AE/AfwBPwH6AV8B+AEf + AfwBPwH8AT8B8gFPAf4BfwH+AWEBhgF/AeABBwHAAQMBzwHxAY8B8wHgAQcBwAEDAc8B8QGPAfMB8gFP + Af4BfwHjAcUBowHHAfoBXwH4AR8B8AEPAfABDwH+AX8B/AE/AfwBPwH8AT8B/gF/Af4BfwT/Af4BfyD/ + AQABDAT/AcABBwEAAQgB7wH9AQABHwGAAQMBAAEBAccB/wEAAQ8BAAEBAQABAwHDAfsBAAEHAQABAQEA + AQMB4wH3AQABAwEAAQEBAAELAfEB5wEAAQEDAAELAfgBzwUAAQMB/AEfAQABHwGAAgABBwH+AT8BAAEf + AcACAAEPAfwBHwEAAR8B4AEBAQABDwH4Ac8BjwHxAeABBwEAAQ8B4QHnAf8B+QHwAQcBAAEfAcMB8wH/ + AXUB8AEDAQABPwHHAf0B/wGPAfgBAwEAAX8E/xYACw== + + + \ No newline at end of file diff --git a/Labyrinth3/IDE/Forms/StructureDlg.cs b/Labyrinth3/IDE/Forms/StructureDlg.cs new file mode 100644 index 0000000..b63cc56 --- /dev/null +++ b/Labyrinth3/IDE/Forms/StructureDlg.cs @@ -0,0 +1,101 @@ +// Decompiled with JetBrains decompiler +// Type: Labyrinth.Forms.StructureDlg +// Assembly: Labyrinth, Version=3.6.1928.15690, Culture=neutral, PublicKeyToken=null +// MVID: 1462002E-0BD1-49D2-9B56-C22E66C903E7 +// Assembly location: C:\Dropbox\Workspace\Programs\Labyrinth\Labyrinth.exe + +using Labyrinth.Plot; +using System; +using System.ComponentModel; +using System.Drawing; +using System.Windows.Forms; + +namespace Labyrinth.Forms +{ + public class StructureDlg : Form + { + private Container components = (Container)null; + private Structure fStructure = (Structure)null; + private Label NameLbl; + private TextBox NameBox; + private Button OKBtn; + private Button CancelBtn; + + public StructureDlg(Structure s) + { + this.InitializeComponent(); + this.fStructure = s; + this.NameBox.Text = this.fStructure.Name; + } + + protected override void Dispose(bool disposing) + { + if (disposing && this.components != null) + this.components.Dispose(); + base.Dispose(disposing); + } + + private void InitializeComponent() + { + this.NameLbl = new Label(); + this.NameBox = new TextBox(); + this.OKBtn = new Button(); + this.CancelBtn = new Button(); + this.SuspendLayout(); + this.NameLbl.Location = new Point(16, 24); + this.NameLbl.Name = "NameLbl"; + this.NameLbl.Size = new Size(48, 23); + this.NameLbl.TabIndex = 0; + this.NameLbl.Text = "Name:"; + this.NameLbl.TextAlign = ContentAlignment.MiddleLeft; + this.NameBox.Anchor = AnchorStyles.Top | AnchorStyles.Left | AnchorStyles.Right; + this.NameBox.Location = new Point(64, 24); + this.NameBox.Name = "NameBox"; + this.NameBox.Size = new Size(216, 21); + this.NameBox.TabIndex = 1; + this.NameBox.Text = ""; + this.OKBtn.Anchor = AnchorStyles.Bottom | AnchorStyles.Right; + this.OKBtn.DialogResult = DialogResult.OK; + this.OKBtn.Location = new Point(128, 64); + this.OKBtn.Name = "OKBtn"; + this.OKBtn.Size = new Size(72, 23); + this.OKBtn.TabIndex = 2; + this.OKBtn.Text = "OK"; + this.OKBtn.Click += new EventHandler(this.OKBtn_Click); + this.CancelBtn.Anchor = AnchorStyles.Bottom | AnchorStyles.Right; + this.CancelBtn.DialogResult = DialogResult.Cancel; + this.CancelBtn.Location = new Point(208, 64); + this.CancelBtn.Name = "CancelBtn"; + this.CancelBtn.Size = new Size(72, 23); + this.CancelBtn.TabIndex = 3; + this.CancelBtn.Text = "Cancel"; + this.AcceptButton = (IButtonControl)this.OKBtn; + this.AutoScaleBaseSize = new Size(5, 14); + this.CancelButton = (IButtonControl)this.CancelBtn; + this.ClientSize = new Size(292, 102); + this.ControlBox = false; + this.Controls.AddRange(new Control[4] + { + (Control) this.CancelBtn, + (Control) this.OKBtn, + (Control) this.NameBox, + (Control) this.NameLbl + }); + this.Font = new Font("Tahoma", 11f, FontStyle.Regular, GraphicsUnit.World); + this.FormBorderStyle = FormBorderStyle.FixedDialog; + this.MaximizeBox = false; + this.MinimizeBox = false; + this.Name = nameof(StructureDlg); + this.ShowInTaskbar = false; + this.SizeGripStyle = SizeGripStyle.Hide; + this.StartPosition = FormStartPosition.CenterParent; + this.Text = "Structure Properties"; + this.ResumeLayout(false); + } + + private void OKBtn_Click(object sender, EventArgs e) + { + this.fStructure.Name = this.NameBox.Text; + } + } +} \ No newline at end of file diff --git a/Labyrinth3/IDE/Forms/StructureDlg.resx b/Labyrinth3/IDE/Forms/StructureDlg.resx new file mode 100644 index 0000000..57ac311 --- /dev/null +++ b/Labyrinth3/IDE/Forms/StructureDlg.resx @@ -0,0 +1,123 @@ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + text/microsoft-resx + + + 2.0 + + + System.Resources.ResXResourceReader, System.Windows.Forms, Version=4.0.0.0, Culture=neutral, PublicKeyToken=b77a5c561934e089 + + + System.Resources.ResXResourceWriter, System.Windows.Forms, Version=4.0.0.0, Culture=neutral, PublicKeyToken=b77a5c561934e089 + + + StructureDlg + + \ No newline at end of file diff --git a/Labyrinth3/IDE/Forms/TaskDlg.cs b/Labyrinth3/IDE/Forms/TaskDlg.cs new file mode 100644 index 0000000..41d5431 --- /dev/null +++ b/Labyrinth3/IDE/Forms/TaskDlg.cs @@ -0,0 +1,196 @@ +// Decompiled with JetBrains decompiler +// Type: Labyrinth.Forms.TaskDlg +// Assembly: Labyrinth, Version=3.6.1928.15690, Culture=neutral, PublicKeyToken=null +// MVID: 1462002E-0BD1-49D2-9B56-C22E66C903E7 +// Assembly location: C:\Dropbox\Workspace\Programs\Labyrinth\Labyrinth.exe + +using Labyrinth.Plot; +using System; +using System.ComponentModel; +using System.Diagnostics; +using System.Drawing; +using System.Resources; +using System.Windows.Forms; + +namespace Labyrinth.Forms +{ + public class TaskDlg : Form + { + private Task fTask = (Task)null; + private ImageList ToolbarImages; + private Label TitleLbl; + private TextBox TitleBox; + private Button OKBtn; + private Button CancelBtn; + private RichTextBox DetailsBox; + private CheckBox DueByBox; + private DateTimePicker DueDateBox; + private CheckBox CompletedBox; + private Label ImportanceLbl; + private ComboBox ImportanceBox; + private IContainer components; + + public TaskDlg(Task t) + { + this.InitializeComponent(); + this.fTask = t; + foreach (Importance importance in Enum.GetValues(typeof(Importance))) + this.ImportanceBox.Items.Add((object)importance); + this.TitleBox.Text = this.fTask.Title; + this.DetailsBox.Text = this.fTask.Details; + this.ImportanceBox.SelectedItem = (object)this.fTask.Importance; + this.DueByBox.Checked = this.fTask.HasDeadline; + if (this.fTask.HasDeadline) + this.DueDateBox.Value = this.fTask.Deadline; + this.CompletedBox.Checked = this.fTask.Completed; + this.DueByBox_CheckedChanged((object)null, (EventArgs)null); + } + + protected override void Dispose(bool disposing) + { + if (disposing && this.components != null) + this.components.Dispose(); + base.Dispose(disposing); + } + + private void InitializeComponent() + { + this.components = (IContainer)new Container(); + ResourceManager resourceManager = new ResourceManager(typeof(TaskDlg)); + this.ToolbarImages = new ImageList(this.components); + this.OKBtn = new Button(); + this.CancelBtn = new Button(); + this.TitleLbl = new Label(); + this.TitleBox = new TextBox(); + this.DetailsBox = new RichTextBox(); + this.DueByBox = new CheckBox(); + this.DueDateBox = new DateTimePicker(); + this.CompletedBox = new CheckBox(); + this.ImportanceLbl = new Label(); + this.ImportanceBox = new ComboBox(); + this.SuspendLayout(); + this.ToolbarImages.ColorDepth = ColorDepth.Depth8Bit; + this.ToolbarImages.ImageSize = new Size(16, 16); + this.ToolbarImages.ImageStream = (ImageListStreamer)resourceManager.GetObject("ToolbarImages.ImageStream"); + this.ToolbarImages.TransparentColor = Color.Magenta; + this.OKBtn.Anchor = AnchorStyles.Bottom | AnchorStyles.Right; + this.OKBtn.DialogResult = DialogResult.OK; + this.OKBtn.Location = new Point(152, 326); + this.OKBtn.Name = "OKBtn"; + this.OKBtn.Size = new Size(72, 23); + this.OKBtn.TabIndex = 8; + this.OKBtn.Text = "OK"; + this.OKBtn.Click += new EventHandler(this.OKBtn_Click); + this.CancelBtn.Anchor = AnchorStyles.Bottom | AnchorStyles.Right; + this.CancelBtn.DialogResult = DialogResult.Cancel; + this.CancelBtn.Location = new Point(232, 326); + this.CancelBtn.Name = "CancelBtn"; + this.CancelBtn.Size = new Size(72, 23); + this.CancelBtn.TabIndex = 9; + this.CancelBtn.Text = "Cancel"; + this.TitleLbl.Location = new Point(16, 16); + this.TitleLbl.Name = "TitleLbl"; + this.TitleLbl.Size = new Size(48, 23); + this.TitleLbl.TabIndex = 0; + this.TitleLbl.Text = "Title:"; + this.TitleLbl.TextAlign = ContentAlignment.MiddleLeft; + this.TitleBox.Anchor = AnchorStyles.Top | AnchorStyles.Left | AnchorStyles.Right; + this.TitleBox.Location = new Point(72, 16); + this.TitleBox.Name = "TitleBox"; + this.TitleBox.Size = new Size(232, 21); + this.TitleBox.TabIndex = 1; + this.TitleBox.Text = ""; + this.DetailsBox.Anchor = AnchorStyles.Top | AnchorStyles.Bottom | AnchorStyles.Left | AnchorStyles.Right; + this.DetailsBox.Location = new Point(16, 56); + this.DetailsBox.Name = "DetailsBox"; + this.DetailsBox.Size = new Size(288, 166); + this.DetailsBox.TabIndex = 2; + this.DetailsBox.Text = ""; + this.DetailsBox.LinkClicked += new LinkClickedEventHandler(this.DetailsBox_LinkClicked); + this.DueByBox.Anchor = AnchorStyles.Bottom | AnchorStyles.Left; + this.DueByBox.Location = new Point(16, 270); + this.DueByBox.Name = "DueByBox"; + this.DueByBox.Size = new Size(80, 24); + this.DueByBox.TabIndex = 5; + this.DueByBox.Text = "Due by:"; + this.DueByBox.CheckedChanged += new EventHandler(this.DueByBox_CheckedChanged); + this.DueDateBox.Anchor = AnchorStyles.Bottom | AnchorStyles.Left | AnchorStyles.Right; + this.DueDateBox.Location = new Point(104, 270); + this.DueDateBox.Name = "DueDateBox"; + this.DueDateBox.TabIndex = 6; + this.CompletedBox.Anchor = AnchorStyles.Bottom | AnchorStyles.Left; + this.CompletedBox.Location = new Point(16, 294); + this.CompletedBox.Name = "CompletedBox"; + this.CompletedBox.Size = new Size(80, 24); + this.CompletedBox.TabIndex = 7; + this.CompletedBox.Text = "Completed"; + this.ImportanceLbl.Anchor = AnchorStyles.Bottom | AnchorStyles.Left; + this.ImportanceLbl.Location = new Point(16, 238); + this.ImportanceLbl.Name = "ImportanceLbl"; + this.ImportanceLbl.Size = new Size(80, 23); + this.ImportanceLbl.TabIndex = 3; + this.ImportanceLbl.Text = "Importance:"; + this.ImportanceLbl.TextAlign = ContentAlignment.MiddleLeft; + this.ImportanceBox.Anchor = AnchorStyles.Bottom | AnchorStyles.Left | AnchorStyles.Right; + this.ImportanceBox.DropDownStyle = ComboBoxStyle.DropDownList; + this.ImportanceBox.Location = new Point(104, 238); + this.ImportanceBox.Name = "ImportanceBox"; + this.ImportanceBox.Size = new Size(200, 21); + this.ImportanceBox.TabIndex = 4; + this.AutoScaleBaseSize = new Size(5, 14); + this.CancelButton = (IButtonControl)this.CancelBtn; + this.ClientSize = new Size(320, 364); + this.Controls.AddRange(new Control[10] + { + (Control) this.ImportanceBox, + (Control) this.ImportanceLbl, + (Control) this.CompletedBox, + (Control) this.DueDateBox, + (Control) this.DueByBox, + (Control) this.TitleBox, + (Control) this.TitleLbl, + (Control) this.CancelBtn, + (Control) this.OKBtn, + (Control) this.DetailsBox + }); + this.Font = new Font("Tahoma", 11f, FontStyle.Regular, GraphicsUnit.World, (byte)0); + this.Icon = (Icon)resourceManager.GetObject("$this.Icon"); + this.MinimizeBox = false; + this.Name = nameof(TaskDlg); + this.ShowInTaskbar = false; + this.SizeGripStyle = SizeGripStyle.Hide; + this.StartPosition = FormStartPosition.CenterParent; + this.Text = "Task Properties"; + this.ResumeLayout(false); + } + + private void DetailsBox_LinkClicked(object sender, LinkClickedEventArgs e) + { + try + { + Process.Start(e.LinkText); + } + catch (Exception ex) + { + LabyrinthData.Log((object)ex); + } + } + + private void OKBtn_Click(object sender, EventArgs e) + { + this.fTask.Title = this.TitleBox.Text; + this.fTask.Details = this.DetailsBox.Text; + this.fTask.Completed = this.CompletedBox.Checked; + this.fTask.Importance = (Importance)this.ImportanceBox.SelectedItem; + this.fTask.HasDeadline = this.DueByBox.Checked; + if (this.fTask.HasDeadline) + this.fTask.Deadline = this.DueDateBox.Value; + this.fTask.Details = this.fTask.Details.Replace("\n", Environment.NewLine); + } + + private void DueByBox_CheckedChanged(object sender, EventArgs e) + { + this.DueDateBox.Enabled = this.DueByBox.Checked; + } + } +} \ No newline at end of file diff --git a/Labyrinth3/IDE/Forms/TaskDlg.resx b/Labyrinth3/IDE/Forms/TaskDlg.resx new file mode 100644 index 0000000..0dfe51e --- /dev/null +++ b/Labyrinth3/IDE/Forms/TaskDlg.resx @@ -0,0 +1,187 @@ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + text/microsoft-resx + + + 2.0 + + + System.Resources.ResXResourceReader, System.Windows.Forms, Version=4.0.0.0, Culture=neutral, PublicKeyToken=b77a5c561934e089 + + + System.Resources.ResXResourceWriter, System.Windows.Forms, Version=4.0.0.0, Culture=neutral, PublicKeyToken=b77a5c561934e089 + + + + + AAABAAEAEBAQAAAAAAAoAQAAFgAAACgAAAAQAAAAIAAAAAEABAAAAAAAgAAAAAAAAAAAAAAAEAAAABAA + AAAAAAAAAACAAACAAAAAgIAAgAAAAIAAgACAgAAAgICAAMDAwAAAAP8AAP8AAAD//wD/AAAA/wD/AP// + AAD///8AAAAAAAAAAAAAB3d3d3dwAACP//////cAAI//iP//9wAAj/8Yj//3AACP8RGI//cAAI8R8Rj/ + 9wAAj///GI/3AACP///xiPcAAI////8Y9wAAj/////H3AACP//////cAAI/3d3d/9wAACIf4iHiAAAAA + AIiIAAAAAAAAAAAAAAD//wAA4AcAAMADAADAAwAAwAMAAMADAADAAwAAwAMAAMADAADAAwAAwAMAAMAD + AADAAwAA4AcAAPw/AAD//wAA + + + + TaskDlg + + + 17, 17 + + + + 57 + + + + AAEAAAD/////AQAAAAAAAAAMAgAAAFdTeXN0ZW0uV2luZG93cy5Gb3JtcywgVmVyc2lvbj00LjAuMC4w + LCBDdWx0dXJlPW5ldXRyYWwsIFB1YmxpY0tleVRva2VuPWI3N2E1YzU2MTkzNGUwODkFAQAAACZTeXN0 + ZW0uV2luZG93cy5Gb3Jtcy5JbWFnZUxpc3RTdHJlYW1lcgEAAAAERGF0YQcCAgAAAAkDAAAADwMAAADs + CAAAAk1TRnQBSQFMAgEBCQEAAQ4BAAEIAQABEAEAARABAAT/AQkBEAj/AUIBTQE2AQQGAAE2AQQCAAEo + AwABQAMAATADAAEBAQABCAYAAQwYAAGAAgABgAMAAoABAAGAAwABgAEAAYABAAKAAgADwAEAAcAB3AHA + AQAB8AHKAaYBAAEzBQABMwEAATMBAAEzAQACMwIAAxYBAAMcAQADIgEAAykBAANVAQADTQEAA0IBAAM5 + AQABgAF8Af8BAAJQAf8BAAGTAQAB1gEAAf8B7AHMAQABxgHWAe8BAAHWAucBAAGQAakBrQIAAf8BMwMA + AWYDAAGZAwABzAIAATMDAAIzAgABMwFmAgABMwGZAgABMwHMAgABMwH/AgABZgMAAWYBMwIAAmYCAAFm + AZkCAAFmAcwCAAFmAf8CAAGZAwABmQEzAgABmQFmAgACmQIAAZkBzAIAAZkB/wIAAcwDAAHMATMCAAHM + AWYCAAHMAZkCAALMAgABzAH/AgAB/wFmAgAB/wGZAgAB/wHMAQABMwH/AgAB/wEAATMBAAEzAQABZgEA + ATMBAAGZAQABMwEAAcwBAAEzAQAB/wEAAf8BMwIAAzMBAAIzAWYBAAIzAZkBAAIzAcwBAAIzAf8BAAEz + AWYCAAEzAWYBMwEAATMCZgEAATMBZgGZAQABMwFmAcwBAAEzAWYB/wEAATMBmQIAATMBmQEzAQABMwGZ + AWYBAAEzApkBAAEzAZkBzAEAATMBmQH/AQABMwHMAgABMwHMATMBAAEzAcwBZgEAATMBzAGZAQABMwLM + AQABMwHMAf8BAAEzAf8BMwEAATMB/wFmAQABMwH/AZkBAAEzAf8BzAEAATMC/wEAAWYDAAFmAQABMwEA + AWYBAAFmAQABZgEAAZkBAAFmAQABzAEAAWYBAAH/AQABZgEzAgABZgIzAQABZgEzAWYBAAFmATMBmQEA + AWYBMwHMAQABZgEzAf8BAAJmAgACZgEzAQADZgEAAmYBmQEAAmYBzAEAAWYBmQIAAWYBmQEzAQABZgGZ + AWYBAAFmApkBAAFmAZkBzAEAAWYBmQH/AQABZgHMAgABZgHMATMBAAFmAcwBmQEAAWYCzAEAAWYBzAH/ + AQABZgH/AgABZgH/ATMBAAFmAf8BmQEAAWYB/wHMAQABzAEAAf8BAAH/AQABzAEAApkCAAGZATMBmQEA + AZkBAAGZAQABmQEAAcwBAAGZAwABmQIzAQABmQEAAWYBAAGZATMBzAEAAZkBAAH/AQABmQFmAgABmQFm + ATMBAAGZATMBZgEAAZkBZgGZAQABmQFmAcwBAAGZATMB/wEAApkBMwEAApkBZgEAA5kBAAKZAcwBAAKZ + Af8BAAGZAcwCAAGZAcwBMwEAAWYBzAFmAQABmQHMAZkBAAGZAswBAAGZAcwB/wEAAZkB/wIAAZkB/wEz + AQABmQHMAWYBAAGZAf8BmQEAAZkB/wHMAQABmQL/AQABzAMAAZkBAAEzAQABzAEAAWYBAAHMAQABmQEA + AcwBAAHMAQABmQEzAgABzAIzAQABzAEzAWYBAAHMATMBmQEAAcwBMwHMAQABzAEzAf8BAAHMAWYCAAHM + AWYBMwEAAZkCZgEAAcwBZgGZAQABzAFmAcwBAAGZAWYB/wEAAcwBmQIAAcwBmQEzAQABzAGZAWYBAAHM + ApkBAAHMAZkBzAEAAcwBmQH/AQACzAIAAswBMwEAAswBZgEAAswBmQEAA8wBAALMAf8BAAHMAf8CAAHM + Af8BMwEAAZkB/wFmAQABzAH/AZkBAAHMAf8BzAEAAcwC/wEAAcwBAAEzAQAB/wEAAWYBAAH/AQABmQEA + AcwBMwIAAf8CMwEAAf8BMwFmAQAB/wEzAZkBAAH/ATMBzAEAAf8BMwH/AQAB/wFmAgAB/wFmATMBAAHM + AmYBAAH/AWYBmQEAAf8BZgHMAQABzAFmAf8BAAH/AZkCAAH/AZkBMwEAAf8BmQFmAQAB/wKZAQAB/wGZ + AcwBAAH/AZkB/wEAAf8BzAIAAf8BzAEzAQAB/wHMAWYBAAH/AcwBmQEAAf8CzAEAAf8BzAH/AQAC/wEz + AQABzAH/AWYBAAL/AZkBAAL/AcwBAAJmAf8BAAFmAf8BZgEAAWYC/wEAAf8CZgEAAf8BZgH/AQAC/wFm + AQABIQEAAaUBAANfAQADdwEAA4YBAAOWAQADywEAA7IBAAPXAQAD3QEAA+MBAAPqAQAD8QEAA/gBAAHw + AfsB/wEAAaQCoAEAA4ADAAH/AgAB/wMAAv8BAAH/AwAB/wEAAf8BAAL/AgAD/8MABAQDAAYENAABBwEE + BQABBwIEAQc2AAIEBAABBwIENwABBwEEBAACBAEHOAAHBDkAAQcBBAIAAgQBBzoAAgQBAAIEOwABBwME + AQc8AAMEPQABBwEEAQc+AAEE/wA5AAMEPQADBD0AAwS9AAMEPQADBD0AAwS9AAMEPQADBD0AAwT/ANQA + AewOAAHsAQAB7CwAAexCAAHsPQAB7EIAAew9AAHsQgAB7P8AJgABQgFNAT4HAAE+AwABKAMAAUADAAEw + AwABAQEAAQEFAAGAAQEWAAP/AQAC/wYAAv8GAAL/BgABwwGBBgAB5wHDBgAB8wHHBgAB8wHHBgAB+AEP + BgAB+QGPBgAB/AGfBgAB/AEfBgAB/gE/BgAB/gE/BgAB/wF/BgAC/wYAAv8GABD/AY8H/wGMAQEBgAED + AcABDwHwAQMBjwn/AYABPwEAAQMBAAEDCP8BjwH/AYABAwHAAQ8B8AEDAYwBAQb/AY8B/wGAAT8BAAED + AQABAwr/AYABAwHAAQ8B8AEDAY8H/wGMAQEBgAE/AQABAwEAAQMBjyP/AeABDwr/AeABHwHgAX8B+AE/ + Av8B8QGPAfgB/wHxAR8BEAE4AfEBjwH4Af8B8wGfAboB1wHxAY8B/AF/AfMBnwIAAfABHwH8AX8B8wGf + AdYBNwHxAY8B/gE/AfMBnwHGAdcB8QGPAf4BPwHzAZ8B7gHWAfEBjwH/AR8B8wGfAewBOAHgAR8B/gEP + AeEBDxr/FgAL + + + \ No newline at end of file diff --git a/Labyrinth3/IDE/Forms/TextAnnotationDlg.cs b/Labyrinth3/IDE/Forms/TextAnnotationDlg.cs new file mode 100644 index 0000000..6fce18d --- /dev/null +++ b/Labyrinth3/IDE/Forms/TextAnnotationDlg.cs @@ -0,0 +1,122 @@ +// Decompiled with JetBrains decompiler +// Type: Labyrinth.Forms.TextAnnotationDlg +// Assembly: Labyrinth, Version=3.6.1928.15690, Culture=neutral, PublicKeyToken=null +// MVID: 1462002E-0BD1-49D2-9B56-C22E66C903E7 +// Assembly location: C:\Dropbox\Workspace\Programs\Labyrinth\Labyrinth.exe + +using Labyrinth.Controls; +using Labyrinth.Plot; +using System; +using System.Drawing; +using System.Resources; +using System.Windows.Forms; + +namespace Labyrinth.Forms +{ + public class TextAnnotationDlg : Form + { + private TextAnnotation fNote = (TextAnnotation)null; + private Label TitleLbl; + private TextBox TitleBox; + private Button OKBtn; + private Button CancelBtn; + private Panel ContentPanel; + private RTFPanel RTFPanel; + + public TextAnnotationDlg(TextAnnotation note) + { + this.InitializeComponent(); + Application.Idle += new EventHandler(this.update_rtfpanel); + this.fNote = note; + this.TitleBox.Text = this.fNote.Title; + if (this.fNote.RTF != "") + this.RTFPanel.RTF = this.fNote.RTF; + else + this.RTFPanel.Text = this.fNote.Content; + } + + private void InitializeComponent() + { + ResourceManager resourceManager = new ResourceManager(typeof(TextAnnotationDlg)); + this.OKBtn = new Button(); + this.CancelBtn = new Button(); + this.TitleLbl = new Label(); + this.TitleBox = new TextBox(); + this.ContentPanel = new Panel(); + this.RTFPanel = new RTFPanel(); + this.ContentPanel.SuspendLayout(); + this.SuspendLayout(); + this.OKBtn.Anchor = AnchorStyles.Bottom | AnchorStyles.Right; + this.OKBtn.DialogResult = DialogResult.OK; + this.OKBtn.Location = new Point(340, 280); + this.OKBtn.Name = "OKBtn"; + this.OKBtn.TabIndex = 3; + this.OKBtn.Text = "OK"; + this.OKBtn.Click += new EventHandler(this.OKBtn_Click); + this.CancelBtn.Anchor = AnchorStyles.Bottom | AnchorStyles.Right; + this.CancelBtn.DialogResult = DialogResult.Cancel; + this.CancelBtn.Location = new Point(420, 280); + this.CancelBtn.Name = "CancelBtn"; + this.CancelBtn.TabIndex = 4; + this.CancelBtn.Text = "Cancel"; + this.TitleLbl.Location = new Point(16, 16); + this.TitleLbl.Name = "TitleLbl"; + this.TitleLbl.Size = new Size(48, 23); + this.TitleLbl.TabIndex = 0; + this.TitleLbl.Text = "Title:"; + this.TitleLbl.TextAlign = ContentAlignment.MiddleLeft; + this.TitleBox.Anchor = AnchorStyles.Top | AnchorStyles.Left | AnchorStyles.Right; + this.TitleBox.Location = new Point(72, 16); + this.TitleBox.Name = "TitleBox"; + this.TitleBox.Size = new Size(424, 21); + this.TitleBox.TabIndex = 1; + this.TitleBox.Text = ""; + this.ContentPanel.Anchor = AnchorStyles.Top | AnchorStyles.Bottom | AnchorStyles.Left | AnchorStyles.Right; + this.ContentPanel.Controls.AddRange(new Control[1] + { + (Control) this.RTFPanel + }); + this.ContentPanel.Location = new Point(16, 56); + this.ContentPanel.Name = "ContentPanel"; + this.ContentPanel.Size = new Size(480, 208); + this.ContentPanel.TabIndex = 2; + this.RTFPanel.Dock = DockStyle.Fill; + this.RTFPanel.Name = "RTFPanel"; + this.RTFPanel.Size = new Size(480, 208); + this.RTFPanel.TabIndex = 0; + this.AutoScaleBaseSize = new Size(5, 14); + this.CancelButton = (IButtonControl)this.CancelBtn; + this.ClientSize = new Size(512, 318); + this.Controls.AddRange(new Control[5] + { + (Control) this.ContentPanel, + (Control) this.TitleBox, + (Control) this.TitleLbl, + (Control) this.CancelBtn, + (Control) this.OKBtn + }); + this.Font = new Font("Tahoma", 11f, FontStyle.Regular, GraphicsUnit.World, (byte)0); + this.Icon = (Icon)resourceManager.GetObject("$this.Icon"); + this.MinimizeBox = false; + this.Name = nameof(TextAnnotationDlg); + this.ShowInTaskbar = false; + this.SizeGripStyle = SizeGripStyle.Hide; + this.StartPosition = FormStartPosition.CenterParent; + this.Text = "Text Annotation Properties"; + this.ContentPanel.ResumeLayout(false); + this.ResumeLayout(false); + } + + private void OKBtn_Click(object sender, EventArgs e) + { + this.fNote.Title = this.TitleBox.Text; + this.fNote.Content = this.RTFPanel.Text; + this.fNote.RTF = this.RTFPanel.RTF; + } + + private void update_rtfpanel(object sender, EventArgs e) + { + this.RTFPanel.UpdateUI(); + } + } +} \ No newline at end of file diff --git a/Labyrinth3/IDE/Forms/TextAnnotationDlg.resx b/Labyrinth3/IDE/Forms/TextAnnotationDlg.resx new file mode 100644 index 0000000..24d1cdb --- /dev/null +++ b/Labyrinth3/IDE/Forms/TextAnnotationDlg.resx @@ -0,0 +1,138 @@ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + text/microsoft-resx + + + 2.0 + + + System.Resources.ResXResourceReader, System.Windows.Forms, Version=4.0.0.0, Culture=neutral, PublicKeyToken=b77a5c561934e089 + + + System.Resources.ResXResourceWriter, System.Windows.Forms, Version=4.0.0.0, Culture=neutral, PublicKeyToken=b77a5c561934e089 + + + + + AAABAAEAEBAQAAAAAAAoAQAAFgAAACgAAAAQAAAAIAAAAAEABAAAAAAAgAAAAAAAAAAAAAAAEAAAABAA + AAAAAAAAAACAAACAAAAAgIAAgAAAAIAAgACAgAAAgICAAMDAwAAAAP8AAP8AAAD//wD/AAAA/wD/AP// + AAD///8AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAHv7+/vwD7AAf7+/v7CA8AB7+/v78L + gAAH+/v7+wAAAAe/v7+/v78AB/v7+/v7+wAHv7+/v7+/AAd3d3d3d3cAAAAAAAAAAAAAAAAAAAAAAAAA + AAAAAAAAAAAAAAAAAAD//wAA//8AAP//AACAAQAAgAEAAIABAACAAQAAgAEAAIABAACAAQAAgAEAAIAB + AAD//wAA//8AAP//AAD//wAA + + + + TextAnnotationDlg + + + + 57 + + \ No newline at end of file diff --git a/Labyrinth3/IDE/Forms/TimelineDlg.cs b/Labyrinth3/IDE/Forms/TimelineDlg.cs new file mode 100644 index 0000000..83660c8 --- /dev/null +++ b/Labyrinth3/IDE/Forms/TimelineDlg.cs @@ -0,0 +1,111 @@ +// Decompiled with JetBrains decompiler +// Type: Labyrinth.Forms.TimelineDlg +// Assembly: Labyrinth, Version=3.6.1928.15690, Culture=neutral, PublicKeyToken=null +// MVID: 1462002E-0BD1-49D2-9B56-C22E66C903E7 +// Assembly location: C:\Dropbox\Workspace\Programs\Labyrinth\Labyrinth.exe + +using Labyrinth.Plot; +using System; +using System.ComponentModel; +using System.Drawing; +using System.Windows.Forms; + +namespace Labyrinth.Forms +{ + public class TimelineDlg : Form + { + private Container components = (Container)null; + private Timeline fTimeline = (Timeline)null; + private Label NameLbl; + private TextBox NameBox; + private Button OKBtn; + private Button CancelBtn; + private CheckBox SortBox; + + public TimelineDlg(Timeline tl) + { + this.InitializeComponent(); + this.fTimeline = tl; + this.NameBox.Text = this.fTimeline.Name; + this.SortBox.Checked = this.fTimeline.Sorting; + } + + protected override void Dispose(bool disposing) + { + if (disposing && this.components != null) + this.components.Dispose(); + base.Dispose(disposing); + } + + private void InitializeComponent() + { + this.NameLbl = new Label(); + this.NameBox = new TextBox(); + this.OKBtn = new Button(); + this.CancelBtn = new Button(); + this.SortBox = new CheckBox(); + this.SuspendLayout(); + this.NameLbl.Location = new Point(16, 24); + this.NameLbl.Name = "NameLbl"; + this.NameLbl.Size = new Size(48, 23); + this.NameLbl.TabIndex = 0; + this.NameLbl.Text = "Name:"; + this.NameLbl.TextAlign = ContentAlignment.MiddleLeft; + this.NameBox.Anchor = AnchorStyles.Top | AnchorStyles.Left | AnchorStyles.Right; + this.NameBox.Location = new Point(64, 24); + this.NameBox.Name = "NameBox"; + this.NameBox.Size = new Size(216, 21); + this.NameBox.TabIndex = 1; + this.NameBox.Text = ""; + this.OKBtn.Anchor = AnchorStyles.Bottom | AnchorStyles.Right; + this.OKBtn.DialogResult = DialogResult.OK; + this.OKBtn.Location = new Point(128, 106); + this.OKBtn.Name = "OKBtn"; + this.OKBtn.Size = new Size(72, 23); + this.OKBtn.TabIndex = 3; + this.OKBtn.Text = "OK"; + this.OKBtn.Click += new EventHandler(this.OKBtn_Click); + this.CancelBtn.Anchor = AnchorStyles.Bottom | AnchorStyles.Right; + this.CancelBtn.DialogResult = DialogResult.Cancel; + this.CancelBtn.Location = new Point(208, 106); + this.CancelBtn.Name = "CancelBtn"; + this.CancelBtn.Size = new Size(72, 23); + this.CancelBtn.TabIndex = 4; + this.CancelBtn.Text = "Cancel"; + this.SortBox.Location = new Point(16, 64); + this.SortBox.Name = "SortBox"; + this.SortBox.Size = new Size(128, 24); + this.SortBox.TabIndex = 2; + this.SortBox.Text = "Sort timeline points"; + this.AcceptButton = (IButtonControl)this.OKBtn; + this.AutoScaleBaseSize = new Size(5, 14); + this.CancelButton = (IButtonControl)this.CancelBtn; + this.ClientSize = new Size(292, 144); + this.ControlBox = false; + this.Controls.AddRange(new Control[5] + { + (Control) this.SortBox, + (Control) this.CancelBtn, + (Control) this.OKBtn, + (Control) this.NameBox, + (Control) this.NameLbl + }); + this.Font = new Font("Tahoma", 11f, FontStyle.Regular, GraphicsUnit.World, (byte)0); + this.FormBorderStyle = FormBorderStyle.FixedDialog; + this.MaximizeBox = false; + this.MinimizeBox = false; + this.Name = nameof(TimelineDlg); + this.ShowInTaskbar = false; + this.SizeGripStyle = SizeGripStyle.Hide; + this.StartPosition = FormStartPosition.CenterParent; + this.Text = "Timeline Properties"; + this.ResumeLayout(false); + } + + private void OKBtn_Click(object sender, EventArgs e) + { + this.fTimeline.Name = this.NameBox.Text; + this.fTimeline.Sorting = this.SortBox.Checked; + } + } +} \ No newline at end of file diff --git a/Labyrinth3/IDE/Forms/TimelineDlg.resx b/Labyrinth3/IDE/Forms/TimelineDlg.resx new file mode 100644 index 0000000..7f083f5 --- /dev/null +++ b/Labyrinth3/IDE/Forms/TimelineDlg.resx @@ -0,0 +1,123 @@ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + text/microsoft-resx + + + 2.0 + + + System.Resources.ResXResourceReader, System.Windows.Forms, Version=4.0.0.0, Culture=neutral, PublicKeyToken=b77a5c561934e089 + + + System.Resources.ResXResourceWriter, System.Windows.Forms, Version=4.0.0.0, Culture=neutral, PublicKeyToken=b77a5c561934e089 + + + TimelineDlg + + \ No newline at end of file diff --git a/Labyrinth3/IDE/Forms/TimelinePointDlg.cs b/Labyrinth3/IDE/Forms/TimelinePointDlg.cs new file mode 100644 index 0000000..85e69e6 --- /dev/null +++ b/Labyrinth3/IDE/Forms/TimelinePointDlg.cs @@ -0,0 +1,193 @@ +// Decompiled with JetBrains decompiler +// Type: Labyrinth.Forms.TimelinePointDlg +// Assembly: Labyrinth, Version=3.6.1928.15690, Culture=neutral, PublicKeyToken=null +// MVID: 1462002E-0BD1-49D2-9B56-C22E66C903E7 +// Assembly location: C:\Dropbox\Workspace\Programs\Labyrinth\Labyrinth.exe + +using Labyrinth.Plot; +using System; +using System.ComponentModel; +using System.Drawing; +using System.Windows.Forms; + +namespace Labyrinth.Forms +{ + public class TimelinePointDlg : Form + { + private Container components = (Container)null; + private TimelinePoint fTimelinePoint = (TimelinePoint)null; + private Label NameLbl; + private TextBox NameBox; + private Button OKBtn; + private Button CancelBtn; + private Label DateLbl; + private DateTimePicker DateBox; + private DateTimePicker TimeBox; + private Label TimeLbl; + private Label ScheduleLbl; + private ComboBox ScheduleBox; + + public TimelinePointDlg(TimelinePoint tlp) + { + this.InitializeComponent(); + this.fTimelinePoint = tlp; + foreach (ScheduleType scheduleType in Enum.GetValues(typeof(ScheduleType))) + this.ScheduleBox.Items.Add((object)scheduleType); + this.NameBox.Text = this.fTimelinePoint.Name; + this.ScheduleBox.SelectedItem = (object)this.fTimelinePoint.UseSchedule; + if (this.fTimelinePoint.UseSchedule != ScheduleType.None) + this.DateBox.Value = this.fTimelinePoint.Schedule; + if (this.fTimelinePoint.UseSchedule == ScheduleType.DateTime) + this.TimeBox.Value = this.fTimelinePoint.Schedule; + this.ScheduleBox_SelectedIndexChanged((object)null, (EventArgs)null); + } + + protected override void Dispose(bool disposing) + { + if (disposing && this.components != null) + this.components.Dispose(); + base.Dispose(disposing); + } + + private void InitializeComponent() + { + this.NameLbl = new Label(); + this.NameBox = new TextBox(); + this.OKBtn = new Button(); + this.CancelBtn = new Button(); + this.DateLbl = new Label(); + this.DateBox = new DateTimePicker(); + this.TimeBox = new DateTimePicker(); + this.TimeLbl = new Label(); + this.ScheduleLbl = new Label(); + this.ScheduleBox = new ComboBox(); + this.SuspendLayout(); + this.NameLbl.Location = new Point(16, 24); + this.NameLbl.Name = "NameLbl"; + this.NameLbl.Size = new Size(48, 23); + this.NameLbl.TabIndex = 0; + this.NameLbl.Text = "Name:"; + this.NameLbl.TextAlign = ContentAlignment.MiddleLeft; + this.NameBox.Anchor = AnchorStyles.Top | AnchorStyles.Left | AnchorStyles.Right; + this.NameBox.Location = new Point(80, 24); + this.NameBox.Name = "NameBox"; + this.NameBox.Size = new Size(200, 21); + this.NameBox.TabIndex = 1; + this.NameBox.Text = ""; + this.OKBtn.Anchor = AnchorStyles.Bottom | AnchorStyles.Right; + this.OKBtn.DialogResult = DialogResult.OK; + this.OKBtn.Location = new Point(128, 178); + this.OKBtn.Name = "OKBtn"; + this.OKBtn.Size = new Size(72, 23); + this.OKBtn.TabIndex = 8; + this.OKBtn.Text = "OK"; + this.OKBtn.Click += new EventHandler(this.OKBtn_Click); + this.CancelBtn.Anchor = AnchorStyles.Bottom | AnchorStyles.Right; + this.CancelBtn.DialogResult = DialogResult.Cancel; + this.CancelBtn.Location = new Point(208, 178); + this.CancelBtn.Name = "CancelBtn"; + this.CancelBtn.Size = new Size(72, 23); + this.CancelBtn.TabIndex = 9; + this.CancelBtn.Text = "Cancel"; + this.DateLbl.Location = new Point(16, 104); + this.DateLbl.Name = "DateLbl"; + this.DateLbl.Size = new Size(48, 23); + this.DateLbl.TabIndex = 4; + this.DateLbl.Text = "Date:"; + this.DateLbl.TextAlign = ContentAlignment.MiddleLeft; + this.DateBox.Format = DateTimePickerFormat.Short; + this.DateBox.Location = new Point(80, 104); + this.DateBox.Name = "DateBox"; + this.DateBox.TabIndex = 5; + this.TimeBox.CustomFormat = "HH:mm"; + this.TimeBox.Format = DateTimePickerFormat.Custom; + this.TimeBox.Location = new Point(80, 136); + this.TimeBox.Name = "TimeBox"; + this.TimeBox.ShowUpDown = true; + this.TimeBox.TabIndex = 7; + this.TimeLbl.Location = new Point(16, 136); + this.TimeLbl.Name = "TimeLbl"; + this.TimeLbl.Size = new Size(48, 23); + this.TimeLbl.TabIndex = 6; + this.TimeLbl.Text = "Time:"; + this.TimeLbl.TextAlign = ContentAlignment.MiddleLeft; + this.ScheduleLbl.Location = new Point(16, 72); + this.ScheduleLbl.Name = "ScheduleLbl"; + this.ScheduleLbl.Size = new Size(56, 23); + this.ScheduleLbl.TabIndex = 2; + this.ScheduleLbl.Text = "Schedule:"; + this.ScheduleLbl.TextAlign = ContentAlignment.MiddleLeft; + this.ScheduleBox.DropDownStyle = ComboBoxStyle.DropDownList; + this.ScheduleBox.Location = new Point(80, 72); + this.ScheduleBox.Name = "ScheduleBox"; + this.ScheduleBox.Size = new Size(200, 21); + this.ScheduleBox.TabIndex = 3; + this.ScheduleBox.SelectedIndexChanged += new EventHandler(this.ScheduleBox_SelectedIndexChanged); + this.AcceptButton = (IButtonControl)this.OKBtn; + this.AutoScaleBaseSize = new Size(5, 14); + this.CancelButton = (IButtonControl)this.CancelBtn; + this.ClientSize = new Size(292, 216); + this.ControlBox = false; + this.Controls.AddRange(new Control[10] + { + (Control) this.ScheduleBox, + (Control) this.ScheduleLbl, + (Control) this.TimeLbl, + (Control) this.TimeBox, + (Control) this.DateBox, + (Control) this.DateLbl, + (Control) this.CancelBtn, + (Control) this.OKBtn, + (Control) this.NameBox, + (Control) this.NameLbl + }); + this.Font = new Font("Tahoma", 11f, FontStyle.Regular, GraphicsUnit.World); + this.FormBorderStyle = FormBorderStyle.FixedDialog; + this.MaximizeBox = false; + this.MinimizeBox = false; + this.Name = nameof(TimelinePointDlg); + this.ShowInTaskbar = false; + this.SizeGripStyle = SizeGripStyle.Hide; + this.StartPosition = FormStartPosition.CenterParent; + this.Text = "Timeline Point Properties"; + this.ResumeLayout(false); + } + + private void OKBtn_Click(object sender, EventArgs e) + { + this.fTimelinePoint.Name = this.NameBox.Text; + this.fTimelinePoint.UseSchedule = (ScheduleType)this.ScheduleBox.SelectedItem; + DateTime dateTime; + if (this.fTimelinePoint.UseSchedule == ScheduleType.Date) + { + int year = this.DateBox.Value.Year; + int month = this.DateBox.Value.Month; + dateTime = this.DateBox.Value; + int day = dateTime.Day; + this.fTimelinePoint.Schedule = new DateTime(year, month, day, 0, 0, 0); + } + if (this.fTimelinePoint.UseSchedule != ScheduleType.DateTime) + return; + dateTime = this.DateBox.Value; + int year1 = dateTime.Year; + dateTime = this.DateBox.Value; + int month1 = dateTime.Month; + dateTime = this.DateBox.Value; + int day1 = dateTime.Day; + dateTime = this.TimeBox.Value; + int hour = dateTime.Hour; + dateTime = this.TimeBox.Value; + int minute = dateTime.Minute; + this.fTimelinePoint.Schedule = new DateTime(year1, month1, day1, hour, minute, 0); + } + + private void ScheduleBox_SelectedIndexChanged(object sender, EventArgs e) + { + ScheduleType selectedItem = (ScheduleType)this.ScheduleBox.SelectedItem; + this.DateLbl.Enabled = selectedItem != ScheduleType.None; + this.DateBox.Enabled = selectedItem != ScheduleType.None; + this.TimeLbl.Enabled = selectedItem == ScheduleType.DateTime; + this.TimeBox.Enabled = selectedItem == ScheduleType.DateTime; + } + } +} \ No newline at end of file diff --git a/Labyrinth3/IDE/Forms/TimelinePointDlg.resx b/Labyrinth3/IDE/Forms/TimelinePointDlg.resx new file mode 100644 index 0000000..10bfefe --- /dev/null +++ b/Labyrinth3/IDE/Forms/TimelinePointDlg.resx @@ -0,0 +1,123 @@ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + text/microsoft-resx + + + 2.0 + + + System.Resources.ResXResourceReader, System.Windows.Forms, Version=4.0.0.0, Culture=neutral, PublicKeyToken=b77a5c561934e089 + + + System.Resources.ResXResourceWriter, System.Windows.Forms, Version=4.0.0.0, Culture=neutral, PublicKeyToken=b77a5c561934e089 + + + TimelinePointDlg + + \ No newline at end of file diff --git a/Labyrinth3/IDE/LabyrinthData.cs b/Labyrinth3/IDE/LabyrinthData.cs new file mode 100644 index 0000000..9550e85 --- /dev/null +++ b/Labyrinth3/IDE/LabyrinthData.cs @@ -0,0 +1,230 @@ +// Decompiled with JetBrains decompiler +// Type: Labyrinth.LabyrinthData +// Assembly: Labyrinth, Version=3.6.1928.15690, Culture=neutral, PublicKeyToken=null +// MVID: 1462002E-0BD1-49D2-9B56-C22E66C903E7 +// Assembly location: C:\Dropbox\Workspace\Programs\Labyrinth\Labyrinth.exe + +using Labyrinth.Extensibility; +using Labyrinth.Pages; +using Labyrinth.Plot; +using System; +using System.Drawing; +using System.Drawing.Printing; +using System.IO; +using System.Reflection; +using System.Resources; +using System.Windows.Forms; + +namespace Labyrinth +{ + public class LabyrinthData + { + private static Project fProject = new Project(); + private static string fFileName = ""; + private static string fMostRecent = ""; + private static PageSettings fPageSettings = new PageSettings(); + private static PrinterSettings fPrinterSettings = new PrinterSettings(); + private static ImageList fImages = (ImageList)null; + + public static Project Project + { + get + { + return LabyrinthData.fProject; + } + set + { + LabyrinthData.fProject = value; + } + } + + public static string FileName + { + get + { + return LabyrinthData.fFileName; + } + set + { + LabyrinthData.fFileName = value; + } + } + + public static string MostRecent + { + get + { + return LabyrinthData.fMostRecent; + } + set + { + LabyrinthData.fMostRecent = value; + } + } + + public static PageSettings PageSettings + { + get + { + return LabyrinthData.fPageSettings; + } + } + + public static PrinterSettings PrinterSettings + { + get + { + return LabyrinthData.fPrinterSettings; + } + } + + public static ImageList ElementImages + { + get + { + if (LabyrinthData.fImages == null) + { + LabyrinthData.fImages = new ImageList(); + LabyrinthData.fImages.ColorDepth = ColorDepth.Depth8Bit; + LabyrinthData.fImages.ImageSize = new Size(16, 16); + LabyrinthData.fImages.TransparentColor = Color.Magenta; + ResourceManager resourceManager = new ResourceManager(typeof(MainForm)); + LabyrinthData.fImages.ImageStream = (ImageListStreamer)resourceManager.GetObject("ElementImages.ImageStream"); + } + return LabyrinthData.fImages; + } + } + + public static string HTMLHeader(string title) + { + return "" + Environment.NewLine + "" + Environment.NewLine + "" + title + "" + Environment.NewLine + LabyrinthData.HTMLStyles + Environment.NewLine + ""; + } + + public static string HTMLGenerator + { + get + { + AssemblyName name = Assembly.GetEntryAssembly().GetName(); + return name.Name + " " + name.Version.ToString(2); + } + } + + public static string HTMLStyles + { + get + { + return ""; + } + } + + public static int GetImageIndex(ElementType type) + { + switch (type) + { + case ElementType.Generic: + return 1; + + case ElementType.Character: + return 2; + + case ElementType.Organisation: + return 3; + + case ElementType.Website: + return 4; + + case ElementType.EmailAccount: + return 5; + + case ElementType.PhoneNumber: + return 6; + + case ElementType.File: + return 7; + + case ElementType.Puzzle: + return 8; + + case ElementType.Location: + return 9; + + case ElementType.Vehicle: + return 10; + + case ElementType.Concept: + return 11; + + case ElementType.Object: + return 12; + + case ElementType.Event: + return 13; + + default: + return 0; + } + } + + public static int GetImageIndex(Annotation a) + { + if (a is TextAnnotation) + return 14; + if (a is LinkAnnotation) + return 15; + return a is SketchAnnotation ? 16 : 0; + } + + public static int GetImageIndex(Task t) + { + if (!t.HasDeadline) + return 21; + return !(t.Deadline - DateTime.Now > TimeSpan.Zero) ? 23 : 22; + } + + public static int GetImageIndex(object obj) + { + if (obj is ElementPage) + return LabyrinthData.GetImageIndex((obj as ElementPage).Element.Type); + if (obj is Element) + return LabyrinthData.GetImageIndex((obj as Element).Type); + if (obj is AnnotationPage) + return 14; + if (obj is Annotation) + return LabyrinthData.GetImageIndex(obj as Annotation); + if (obj is Labyrinth.Plot.Link) + return 17; + if (obj is Structure || obj is StructurePage) + return 18; + if (obj is Timeline || obj is TimelinePage) + return 19; + if (obj is SearchPage) + return 20; + if (obj is TaskPage) + return 21; + if (obj is Task) + return LabyrinthData.GetImageIndex(obj as Task); + if (obj is CalendarPage) + return 24; + if (obj is Note || obj is NotePage) + return 25; + return obj is IPage ? 26 : 0; + } + + public static void Log(object obj) + { + try + { + string location = Assembly.GetEntryAssembly().Location; + int length = location.LastIndexOf("."); + StreamWriter streamWriter = File.AppendText(location.Substring(0, length) + ".log"); + streamWriter.WriteLine(LabyrinthData.HTMLGenerator + "; " + (object)DateTime.Now); + streamWriter.WriteLine(obj); + streamWriter.WriteLine(); + streamWriter.Close(); + } + catch + { + } + } + } +} \ No newline at end of file diff --git a/Labyrinth3/IDE/LabyrinthData.resx b/Labyrinth3/IDE/LabyrinthData.resx new file mode 100644 index 0000000..cf5f155 --- /dev/null +++ b/Labyrinth3/IDE/LabyrinthData.resx @@ -0,0 +1,206 @@ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + text/microsoft-resx + + + 2.0 + + + System.Resources.ResXResourceReader, System.Windows.Forms, Version=4.0.0.0, Culture=neutral, PublicKeyToken=b77a5c561934e089 + + + System.Resources.ResXResourceWriter, System.Windows.Forms, Version=4.0.0.0, Culture=neutral, PublicKeyToken=b77a5c561934e089 + + + + False + + + LabyrinthData + + + + AAEAAAD/////AQAAAAAAAAAMAgAAAFdTeXN0ZW0uV2luZG93cy5Gb3JtcywgVmVyc2lvbj00LjAuMC4w + LCBDdWx0dXJlPW5ldXRyYWwsIFB1YmxpY0tleVRva2VuPWI3N2E1YzU2MTkzNGUwODkFAQAAACZTeXN0 + ZW0uV2luZG93cy5Gb3Jtcy5JbWFnZUxpc3RTdHJlYW1lcgEAAAAERGF0YQcCAgAAAAkDAAAADwMAAADK + DwAAAk1TRnQBSQFMAgEBEwEAARgBAAEIAQABEAEAARABAAT/AQkBEAj/AUIBTQE2AQQGAAE2AQQCAAEo + AwABQAMAAVADAAEBAQABCAYAARQYAAGAAgABgAMAAoABAAGAAwABgAEAAYABAAKAAgADwAEAAcAB3AHA + AQAB8AHKAaYBAAEzBQABMwEAATMBAAEzAQACMwIAAxYBAAMcAQADIgEAAykBAANVAQADTQEAA0IBAAM5 + AQABgAF8Af8BAAJQAf8BAAGTAQAB1gEAAf8B7AHMAQABxgHWAe8BAAHWAucBAAGQAakBrQIAAf8BMwMA + AWYDAAGZAwABzAIAATMDAAIzAgABMwFmAgABMwGZAgABMwHMAgABMwH/AgABZgMAAWYBMwIAAmYCAAFm + AZkCAAFmAcwCAAFmAf8CAAGZAwABmQEzAgABmQFmAgACmQIAAZkBzAIAAZkB/wIAAcwDAAHMATMCAAHM + AWYCAAHMAZkCAALMAgABzAH/AgAB/wFmAgAB/wGZAgAB/wHMAQABMwH/AgAB/wEAATMBAAEzAQABZgEA + ATMBAAGZAQABMwEAAcwBAAEzAQAB/wEAAf8BMwIAAzMBAAIzAWYBAAIzAZkBAAIzAcwBAAIzAf8BAAEz + AWYCAAEzAWYBMwEAATMCZgEAATMBZgGZAQABMwFmAcwBAAEzAWYB/wEAATMBmQIAATMBmQEzAQABMwGZ + AWYBAAEzApkBAAEzAZkBzAEAATMBmQH/AQABMwHMAgABMwHMATMBAAEzAcwBZgEAATMBzAGZAQABMwLM + AQABMwHMAf8BAAEzAf8BMwEAATMB/wFmAQABMwH/AZkBAAEzAf8BzAEAATMC/wEAAWYDAAFmAQABMwEA + AWYBAAFmAQABZgEAAZkBAAFmAQABzAEAAWYBAAH/AQABZgEzAgABZgIzAQABZgEzAWYBAAFmATMBmQEA + AWYBMwHMAQABZgEzAf8BAAJmAgACZgEzAQADZgEAAmYBmQEAAmYBzAEAAWYBmQIAAWYBmQEzAQABZgGZ + AWYBAAFmApkBAAFmAZkBzAEAAWYBmQH/AQABZgHMAgABZgHMATMBAAFmAcwBmQEAAWYCzAEAAWYBzAH/ + AQABZgH/AgABZgH/ATMBAAFmAf8BmQEAAWYB/wHMAQABzAEAAf8BAAH/AQABzAEAApkCAAGZATMBmQEA + AZkBAAGZAQABmQEAAcwBAAGZAwABmQIzAQABmQEAAWYBAAGZATMBzAEAAZkBAAH/AQABmQFmAgABmQFm + ATMBAAGZATMBZgEAAZkBZgGZAQABmQFmAcwBAAGZATMB/wEAApkBMwEAApkBZgEAA5kBAAKZAcwBAAKZ + Af8BAAGZAcwCAAGZAcwBMwEAAWYBzAFmAQABmQHMAZkBAAGZAswBAAGZAcwB/wEAAZkB/wIAAZkB/wEz + AQABmQHMAWYBAAGZAf8BmQEAAZkB/wHMAQABmQL/AQABzAMAAZkBAAEzAQABzAEAAWYBAAHMAQABmQEA + AcwBAAHMAQABmQEzAgABzAIzAQABzAEzAWYBAAHMATMBmQEAAcwBMwHMAQABzAEzAf8BAAHMAWYCAAHM + AWYBMwEAAZkCZgEAAcwBZgGZAQABzAFmAcwBAAGZAWYB/wEAAcwBmQIAAcwBmQEzAQABzAGZAWYBAAHM + ApkBAAHMAZkBzAEAAcwBmQH/AQACzAIAAswBMwEAAswBZgEAAswBmQEAA8wBAALMAf8BAAHMAf8CAAHM + Af8BMwEAAZkB/wFmAQABzAH/AZkBAAHMAf8BzAEAAcwC/wEAAcwBAAEzAQAB/wEAAWYBAAH/AQABmQEA + AcwBMwIAAf8CMwEAAf8BMwFmAQAB/wEzAZkBAAH/ATMBzAEAAf8BMwH/AQAB/wFmAgAB/wFmATMBAAHM + AmYBAAH/AWYBmQEAAf8BZgHMAQABzAFmAf8BAAH/AZkCAAH/AZkBMwEAAf8BmQFmAQAB/wKZAQAB/wGZ + AcwBAAH/AZkB/wEAAf8BzAIAAf8BzAEzAQAB/wHMAWYBAAH/AcwBmQEAAf8CzAEAAf8BzAH/AQAC/wEz + AQABzAH/AWYBAAL/AZkBAAL/AcwBAAJmAf8BAAFmAf8BZgEAAWYC/wEAAf8CZgEAAf8BZgH/AQAC/wFm + AQABIQEAAaUBAANfAQADdwEAA4YBAAOWAQADywEAA7IBAAPXAQAD3QEAA+MBAAPqAQAD8QEAA/gBAAHw + AfsB/wEAAaQCoAEAA4ADAAH/AgAB/wMAAv8BAAH/AwAB/wEAAf8BAAL/AgAD/4oAA+w6AAPsGAAB/wkA + Af8fAAHsFQAB/wkAAf8YAAHsBQAB7DkAAewEAAHsGAAB/wYAAf8aAAHsHQAB/wMAAQcCAAH/GQAB7AUA + A+wWAAH/AwABBwIAAf8ZAAHsAgAB7DwAAewBAAHsHQAB/wUAAf8aAAHsnwAB/wUAAf//ABgADuwCAALs + AQAD7AEAB+wCAAHsAQAE/wEAB+wfAAHsDwAB7AQAAf8CAgH/BwAB7BIAAfsB/wH7Af8B+wH/AfsB/wIA + Af8B+wEAAewCAAH7Af8CAAH7AgAB/wIAAf8B+wEAAewCAAH7AQAB/wH7AfkB/wEAAf8CAAH/AfsBAAHs + EgAB/wH7Af8B+wH/AfsB/wH7AQABBwEAAf8BAAHsAgAB/wH7AgAB/wIAAfsBAAEHAQAB/wEAAewCAAH/ + AQAB/wH8AfkB/wEAAfsBAAEHAQAB/wEAAewSAAH7Af8B+wH/AfsB/wH7Af8BAAH7AQcCAAHsAgAB+wH/ + AgAB+wIAAf8BAAH7AQcCAAHsAgAB+wEAAf8B/AH7Af8BAAH/AQAB+wEHAgAB7BIAAf8B+wH/AfsB/wH7 + Af8B+wUAAewCAAH/AfsCAAH/AgAB+wUAAewCAAH/AQAB/wL8Af8BAAH7BQAB7BIAAfsB/wH7Af8B+wH/ + AfsB/wH7Af8B+wH/AQAB7AIAAfsB/wH7AQAB+wH/AQAB/wH7Af8B+wH/AQAB7AIAAfsBAAT/AQAB/wH7 + Af8B+wH/AQAB7BIAAf8B+wH/AfsB/wH7Af8B+wH/AfsB/wH7AQAB7AIAAf8B+wH/AQAB/wH7AQAB+wH/ + AfsB/wH7AQAB7AIAAf8GAAH7Af8B+wH/AfsBAAHsEgAB+wH/AfsB/wH7Af8B+wH/AfsB/wH7Af8BAAHs + AgAB+wH/AfsB/wIAAfsB/wH7Af8B+wH/AQAB7AIAAfsB/wH7Af8B+wH/AfsB/wH7Af8B+wH/AQAB7P8A + 5wABBQEAAeweAAIFHAACBQEAAf8BBwH/OQADBQEAAewB/wEHAf8BBwcABQIqAAQFAQcCAAHsAQcB/wEH + BgAFAgEAAfonAAQFAQcDBQIAAewB/wHsBQAFAgEAAvoLAAIFCwADAQoABAUBBwYFAgAB7AUABQIBAAL6 + CwACBRgAAwUBBwkFDAAC+gsAAgUYAAIFAQcKBQcABfoBAAH6CwACBRAAAwEFAAEFAQcKBQkABfoMAAIF + GAABBwoFGwACBRoACAUcAAIFHAAFBT0AAgX/AD4ABfwJAAf/CwACAwMAAgMXAAL8DgAB/wPsA/8LAAED + BQABAxcAAfwCAAb8BwAH/wcAAgMCAAEDBQABAxYAAfwCAAL8AQAC/AIAAfwGAAH/BewB/wcABgMDAAID + FgAB/AIAAvwBAAL8AgAB/AYAB/8HAAIDAgAHAxYAAfwCAAL8AQAC/AIAAfwGAAH/BewB/wsABwMWAAH8 + AgAC/AEAAvwCAAH8BgAH/wsABwMXAAH8AgAE/AEAAfwHAAH/A+wD/w4AAQMaAAL8BQAC/AcABf8QAAED + HAAF/AkABf8PAAMDPQADA/8ADQACBU0ABOwKAAjsKAAC7AQHAuwIAAjsBwAF7AEABewWAAHsBgcB7AgA + COwHAAXsAQAF7AkAAgUKAAHsCAcB7AgABuwJAATsAQAE7AoAAgUKAAHsCAcB7AoAAuweAAIFCgAB7AgH + AewKAALsHgACBQoAAewIBwHsCQAE7AsAAuwDAALsCwACBQsAAewGBwHsCgAE7AsAAuwDAALsCwACBQsA + AuwEBwLsCgAE7AsAAuwDAALsCwACBQ0ABOzmAAFCAU0BPgcAAT4DAAEoAwABQAMAAVADAAEBAQABAQUA + AYABAhYAA/8BAAb/AgAG/wIAAf8BgwL/AQcBwQIAAfABcwL/AQcBwQIAAfMB7wL/AQcBwQIAAfcC3wH9 + AgECAAH3Ab8B3wH9AQABAQIAAfYBfwHbAW0BAAEBAgAB7gEPAdsBbQEAAQECAAHtAfMBwAEBAYABAwIA + AesB8wL/AcEBBwIAAccD/wHBAQcCAAHPA/8B4wGPAgAE/wHjAY8CAAT/AeMBjwIABv8CAAL/AfgH/wH3 + AX8B4AF/Af8BzwHAAQABwAEAAcABAAH/AccBgAEAAYABAAGAAQAB/AEDAYABAAGAAQABgAEAAfMBxwGA + AQABgAEAAYABAAHvAc8BgAEAAYABAAGAAQAB7wH/AYABAAGAAQABgAEAAfMB/wGAAQABgAEAAYABAAH8 + AX8BgAEAAYABAAGAAQAB/wGfAYABAAGAAQABgAEAAf8B7wGAAQEBgAEBAYABAQH/Ae8H/wGfBv8B8AF/ + Gv8B/AF/Av8B/gF/Af4BfwH4AR8C/wH8AT8B/gF/AfABBwHgAT8B/gF/Af4BfwHgAQEB4AEfAv8B/gF/ + AcABAAHgAQ8B/gF/AfABfwGAAQEB4AEHAfwBPwHgAX8BAAEBAeABBwH8AT8B8AF/AgAB4AEHAfwBPwH+ + AQ8BAAEBAfABBwH8AT8B/gEHAQABAwH4AQcB/AE/Af4BDwEAAQcB/AEHAfwBPwH+AX8BgAEPAv8B/AE/ + Av8B4AEfAv8B/gF/Av8B+AE/Bv8B/gF/Ff8B9wL/AeABDwH4AUMB/wH3AfwBHwHgAQ8B+AFDAf8B9wHz + Af8B4AEPAcgB4wHWAdMB9gEHAeABDwGAAeMB1QG1AewBmwHgAQ8BgAEDAdUBtQHsAZsB4AEPAYABAwHM + AZMB7AGbAeABDwHIAQMB3QG/AewBmwHgAQ8B+AEDAd0BvwH2ARcB4AEPAfgBAwHdAb8B8wHnAeABDwH/ + AR8C/wH8AR8B4AEfAf4BDwT/AeABPwH+AQ8H/wEfEP8B/gF/Bv8B/AE/Bv8B/gF/AfwBPwHgAQcE/wHw + AQ8B4AEHAcABAQH+AX8B8AEPAeABBwHAAQEB/AE/AeABBwHwAQ8B4AEDAfwBPwHgAQcB+AEfAfABhwH8 + AT8B4AEHAfwBPwH5Ac8B/AE/AeABBwH4AR8B8AGHAfwBPwHwAQ8B+AEfAfABhwH8AT8B8AEPAfgBHwHw + AYcB/AE/AfwBPwH8AT8B+QHPAf4Bfxb/FgAL + + + + + 30, 37 + + \ No newline at end of file diff --git a/Labyrinth3/IDE/LabyrinthMain.cs b/Labyrinth3/IDE/LabyrinthMain.cs new file mode 100644 index 0000000..f5c485e --- /dev/null +++ b/Labyrinth3/IDE/LabyrinthMain.cs @@ -0,0 +1,52 @@ +// Decompiled with JetBrains decompiler +// Type: Labyrinth.LabyrinthMain +// Assembly: Labyrinth, Version=3.6.1928.15690, Culture=neutral, PublicKeyToken=null +// MVID: 1462002E-0BD1-49D2-9B56-C22E66C903E7 +// Assembly location: C:\Dropbox\Workspace\Programs\Labyrinth\Labyrinth.exe + +using System; +using System.Collections; +using System.Diagnostics; +using System.Windows.Forms; + +namespace Labyrinth +{ + public class LabyrinthMain + { + [STAThread] + private static void Main(string[] args) + { + foreach (var resource in typeof(LabyrinthMain).Assembly.GetManifestResourceNames()) + { + Debug.WriteLine(resource); + } + + try + { + StartupData sd = new StartupData(); + ArrayList arrayList = new ArrayList((ICollection)args); + if (arrayList.Count != 0) + { + int index1 = arrayList.IndexOf((object)"/addin"); + if (index1 != -1) + { + sd.AddInPath = arrayList[index1 + 1] as string; + arrayList.RemoveRange(index1, 2); + } + if (arrayList.Count != 0) + { + int index2 = arrayList.Count - 1; + sd.FileName = arrayList[index2] as string; + arrayList.RemoveAt(index2); + } + } + Application.Run((Form)new MainForm(sd)); + } + catch (Exception ex) + { + LabyrinthData.Log((object)ex); + int num = (int)MessageBox.Show(ex.Message + "\n" + (object)ex.InnerException, "Labyrinth", MessageBoxButtons.OK, MessageBoxIcon.Hand); + } + } + } +} \ No newline at end of file diff --git a/Labyrinth3/IDE/ListViewSorter.cs b/Labyrinth3/IDE/ListViewSorter.cs new file mode 100644 index 0000000..8afb74d --- /dev/null +++ b/Labyrinth3/IDE/ListViewSorter.cs @@ -0,0 +1,96 @@ +// Decompiled with JetBrains decompiler +// Type: Labyrinth.ListViewSorter +// Assembly: Labyrinth, Version=3.6.1928.15690, Culture=neutral, PublicKeyToken=null +// MVID: 1462002E-0BD1-49D2-9B56-C22E66C903E7 +// Assembly location: C:\Dropbox\Workspace\Programs\Labyrinth\Labyrinth.exe + +using System; +using System.Collections; +using System.Windows.Forms; + +namespace Labyrinth +{ + public class ListViewSorter : IComparer + { + private int fColumn = 0; + private bool fAscending = true; + + public int Column + { + get + { + return this.fColumn; + } + set + { + this.fColumn = value; + } + } + + public bool Ascending + { + get + { + return this.fAscending; + } + set + { + this.fAscending = value; + } + } + + public void SetColumn(int col) + { + if (this.fColumn == col) + { + this.fAscending = !this.fAscending; + } + else + { + this.fColumn = col; + this.fAscending = true; + } + } + + public int Compare(object x, object y) + { + ListViewItem listViewItem1 = x as ListViewItem; + ListViewItem listViewItem2 = y as ListViewItem; + if (listViewItem1 == null || listViewItem2 == null) + throw new ArgumentException(); + string text1 = listViewItem1.SubItems[this.Column].Text; + string text2 = listViewItem2.SubItems[this.Column].Text; + try + { + return int.Parse(text1).CompareTo((object)int.Parse(text2)) * (this.fAscending ? 1 : -1); + } + catch + { + } + try + { + return float.Parse(text1).CompareTo((object)float.Parse(text2)) * (this.fAscending ? 1 : -1); + } + catch + { + } + try + { + return DateTime.Parse(text1).CompareTo((object)DateTime.Parse(text2)) * (this.fAscending ? 1 : -1); + } + catch + { + } + return text1.CompareTo(text2) * (this.fAscending ? 1 : -1); + } + + public static void Sort(ListView list, int column) + { + ListViewSorter listViewItemSorter = list.ListViewItemSorter as ListViewSorter; + if (listViewItemSorter == null) + return; + listViewItemSorter.SetColumn(column); + list.Sort(); + } + } +} \ No newline at end of file diff --git a/Labyrinth3/IDE/MainForm.cs b/Labyrinth3/IDE/MainForm.cs new file mode 100644 index 0000000..59c9610 --- /dev/null +++ b/Labyrinth3/IDE/MainForm.cs @@ -0,0 +1,3106 @@ +// Decompiled with JetBrains decompiler +// Type: Labyrinth.MainForm +// Assembly: Labyrinth, Version=3.6.1928.15690, Culture=neutral, PublicKeyToken=null +// MVID: 1462002E-0BD1-49D2-9B56-C22E66C903E7 +// Assembly location: C:\Dropbox\Workspace\Programs\Labyrinth\Labyrinth.exe + +using Labyrinth.Collections; +using Labyrinth.Events; +using Labyrinth.Extensibility; +using Labyrinth.Forms; +using Labyrinth.Pages; +using Labyrinth.Plot; +using System; +using System.Collections; +using System.ComponentModel; +using System.Drawing; +using System.Drawing.Printing; +using System.IO; +using System.Reflection; +using System.Resources; +using System.Text; +using System.Windows.Forms; +using System.Xml; +using System.Xml.Serialization; + +namespace Labyrinth +{ + public class MainForm : Form, IApplication + { + private AddInManager fAddInMgr = new AddInManager(); + private ArrayList fCustomSearches = new ArrayList(); + private const string FileFilter = "Plot Files|*.plt|All Files|*.*"; + private StatusBarPanel NoteStatusPanel; + private MenuItem ViewPageTabs; + private MenuItem ToolsMergeElements; + private MenuItem WindowMenu; + private MenuItem WindowCloseAll; + private MenuItem WindowCloseAllExcept; + private MenuItem WindowClose; + private MenuItem Sep7; + private MenuItem WindowPages; + private MenuItem Sep8; + private MainMenu MainMenu; + private StatusBarPanel NameStatusPanel; + private StatusBarPanel ElementStatusPanel; + private StatusBarPanel StructureStatusPanel; + private StatusBarPanel TimelineStatusPanel; + private StatusBar StatusBar; + private ToolBar MainToolBar; + private MenuItem FileMenu; + private MenuItem HelpMenu; + private MenuItem FileNew; + private MenuItem FileOpen; + private MenuItem FileSave; + private MenuItem FileSaveAs; + private MenuItem Sep1; + private MenuItem FileExit; + private MenuItem HelpAbout; + private ToolBarButton MainNewBtn; + private ToolBarButton MainOpenBtn; + private Crownwood.Magic.Controls.TabControl Explorer; + private Splitter ExplorerSplitter; + private Crownwood.Magic.Controls.TabControl Pages; + private Crownwood.Magic.Controls.TabPage ElementPage; + private Crownwood.Magic.Controls.TabPage StructurePage; + private Crownwood.Magic.Controls.TabPage TimelinePage; + private MenuItem ViewMenu; + private MenuItem ViewExplorer; + private ImageList ElementImages; + private ImageList Images; + private ColumnHeader StructureNameHdr; + private ColumnHeader TimelineNameHdr; + private ToolBar ElementToolbar; + private ToolBarButton ElementNewBtn; + private ToolBarButton ElementDeleteBtn; + private ToolBarButton ElementPropertiesBtn; + private ToolBar StructureToolbar; + private ToolBarButton StructureNewBtn; + private ToolBarButton StructureDeleteBtn; + private ToolBarButton StructurePropertiesBtn; + private ToolBar TimelineToolbar; + private ToolBarButton TimelineNewBtn; + private ToolBarButton TimelineDeleteBtn; + private ToolBarButton TimelinePropertiesBtn; + private ListView StructureList; + private ListView TimelineList; + private ToolBarButton ElementViewBtn; + private ToolBarButton StructureViewBtn; + private ToolBarButton TimelineViewBtn; + private MenuItem EditMenu; + private MenuItem EditElements; + private MenuItem EditStructures; + private MenuItem EditTimelines; + private MenuItem EditElementsNew; + private MenuItem EditElementsDelete; + private MenuItem EditElementsProperties; + private MenuItem EditElementsView; + private MenuItem EditStructuresNew; + private MenuItem EditStructuresDelete; + private MenuItem EditStructuresProperties; + private MenuItem EditStructuresView; + private MenuItem EditTimelinesNew; + private MenuItem EditTimelinesDelete; + private MenuItem EditTimelinesProperties; + private MenuItem EditTimelinesView; + private ToolBarButton MainSaveBtn; + private ContextMenu ElementContextMenu; + private ContextMenu StructureContextMenu; + private ContextMenu TimelineContextMenu; + private MenuItem ElementNew; + private MenuItem ElementDelete; + private MenuItem ElementProperties; + private MenuItem ElementView; + private MenuItem StructureNew; + private MenuItem StructureDelete; + private MenuItem StructureProperties; + private MenuItem StructureView; + private MenuItem TimelineNew; + private MenuItem TimelineDelete; + private MenuItem TimelineProperties; + private MenuItem TimelineView; + private ListView ElementList; + private ColumnHeader ElementNameHdr; + private MenuItem EditProjectProperties; + private ToolBarButton Sep2; + private ToolBarButton MainPropertiesBtn; + private MenuItem ViewToolbar; + private MenuItem ViewStatusbar; + private ToolBarButton MainSearchBtn; + private MenuItem HelpContents; + private MenuItem FilePageSetup; + private MenuItem Sep4; + private MenuItem ToolsSearch; + private MenuItem ToolsMenu; + private MenuItem ToolsAddIns; + private MenuItem ToolsAddinsNone; + private IContainer components; + private MenuItem FileImport; + private MenuItem Sep5; + private ToolBarButton MainTasksBtn; + private MenuItem Sep3; + private MenuItem ToolsTaskList; + private MenuItem ToolsAnnotations; + private ToolBarButton MainAnnotationsBtn; + private MenuItem ToolsCalendar; + private ToolBarButton MainCalendarBtn; + private Crownwood.Magic.Controls.TabPage NotePage; + private ListView NoteList; + private ToolBar NoteToolbar; + private ContextMenu NoteContextMenu; + private MenuItem EditNotes; + private MenuItem EditNotesNew; + private MenuItem EditNotesDelete; + private MenuItem EditNotesProperties; + private MenuItem EditNotesView; + private MenuItem Sep6; + private ColumnHeader NoteNameHdr; + private ToolBarButton NoteNewBtn; + private ToolBarButton NoteDeleteBtn; + private ToolBarButton NotePropertiesBtn; + private ToolBarButton NoteViewBtn; + private MenuItem NoteNew; + private MenuItem NoteDelete; + private MenuItem NoteProperties; + private MenuItem NoteView; + + public Project Project + { + get + { + return LabyrinthData.Project; + } + } + + public string FileName + { + get + { + return LabyrinthData.FileName; + } + set + { + LabyrinthData.FileName = value; + } + } + + public MainMenu Menubar + { + get + { + return this.MainMenu; + } + } + + public ToolBar Toolbar + { + get + { + return this.MainToolBar; + } + } + + public StatusBar Statusbar + { + get + { + return this.StatusBar; + } + } + + public PageSettings PageSettings + { + get + { + return LabyrinthData.PageSettings; + } + } + + public PrinterSettings PrinterSettings + { + get + { + return LabyrinthData.PrinterSettings; + } + } + + public IPage ActivePage + { + get + { + if (this.Pages.SelectedTab == null) + return (IPage)null; + return this.Pages.SelectedTab.Control as IPage; + } + } + + public IPage[] OpenPages + { + get + { + ArrayList arrayList = new ArrayList(); + foreach (Crownwood.Magic.Controls.TabPage tabPage in (CollectionBase)this.Pages.TabPages) + { + if (tabPage.Control is IPage) + arrayList.Add((object)tabPage.Control); + } + return (IPage[])arrayList.ToArray(); + } + } + + public IAddIn[] AddIns + { + get + { + return (IAddIn[])this.fAddInMgr.AddIns.ToArray(typeof(IAddIn)); + } + } + + public ImageList Glyphs + { + get + { + return LabyrinthData.ElementImages; + } + } + + public void OpenElement(Element e) + { + this.view_element(e); + } + + public void OpenStructure(Structure s) + { + this.view_structure(s); + } + + public void OpenTimeline(Timeline tl) + { + this.view_timeline(tl); + } + + public void OpenNote(Note n) + { + this.view_note(n); + } + + public void OpenSearch() + { + this.view_search(); + } + + public void OpenAnnotations() + { + this.view_annotations(); + } + + public void OpenTasks() + { + this.view_tasks(); + } + + public void OpenCalendar() + { + this.view_calendar(); + } + + public void NewProject() + { + this.new_project(); + this.ElementPage.Selected = true; + this.Pages.TabPages.Clear(); + this.update_ui(); + } + + public bool OpenProject(string filename) + { + bool flag = this.open_project(filename); + this.ElementPage.Selected = true; + this.Pages.TabPages.Clear(); + this.update_ui(); + return flag; + } + + public bool SaveProject(string filename) + { + bool flag = this.save_project(filename); + this.update_ui(); + return flag; + } + + public void OpenPage(IPage page) + { + foreach (Crownwood.Magic.Controls.TabPage tabPage in (CollectionBase)this.Pages.TabPages) + { + if (tabPage.Control as IPage == page) + { + tabPage.Selected = true; + return; + } + } + int imageIndex = LabyrinthData.GetImageIndex((object)page); + Crownwood.Magic.Controls.TabPage tabPage1 = new Crownwood.Magic.Controls.TabPage(page.Title, page as Control, imageIndex); + this.Pages.TabPages.Add(tabPage1); + tabPage1.Selected = true; + } + + public bool ClosePage(IPage page) + { + foreach (Crownwood.Magic.Controls.TabPage tabPage in (CollectionBase)this.Pages.TabPages) + { + if (tabPage.Control as IPage == page) + { + this.Pages.TabPages.Remove(tabPage); + return true; + } + } + return false; + } + + public void UpdateUI() + { + this.update_ui(); + } + + public int GetImageIndex(object obj) + { + return LabyrinthData.GetImageIndex(obj); + } + + public event EventHandler ProjectCreated; + + public event EventHandler ProjectOpened; + + public event EventHandler ProjectSaved; + + public event EventHandler ProjectClosing; + + public event ElementEventHandler ElementAdded; + + public event ElementEventHandler ElementModified; + + public event ElementEventHandler ElementDeleted; + + public event StructureEventHandler StructureAdded; + + public event StructureEventHandler StructureModified; + + public event StructureEventHandler StructureDeleted; + + public event TimelineEventHandler TimelineAdded; + + public event TimelineEventHandler TimelineModified; + + public event TimelineEventHandler TimelineDeleted; + + public event NoteEventHandler NoteAdded; + + public event NoteEventHandler NoteModified; + + public event NoteEventHandler NoteDeleted; + + protected void OnProjectCreated(EventArgs e) + { + try + { + if (this.ProjectCreated == null) + return; + this.ProjectCreated((object)this, e); + } + catch (Exception ex) + { + LabyrinthData.Log((object)ex); + } + } + + protected void OnProjectOpened(EventArgs e) + { + try + { + if (this.ProjectOpened == null) + return; + this.ProjectOpened((object)this, e); + } + catch (Exception ex) + { + LabyrinthData.Log((object)ex); + } + } + + protected void OnProjectSaved(EventArgs e) + { + try + { + if (this.ProjectSaved == null) + return; + this.ProjectSaved((object)this, e); + } + catch (Exception ex) + { + LabyrinthData.Log((object)ex); + } + } + + protected void OnProjectClosing(EventArgs e) + { + try + { + if (this.ProjectClosing == null) + return; + this.ProjectClosing((object)this, e); + } + catch (Exception ex) + { + LabyrinthData.Log((object)ex); + } + } + + protected void OnElementAdded(ElementEventArgs e) + { + try + { + if (this.ElementAdded == null) + return; + this.ElementAdded((object)this, e); + } + catch (Exception ex) + { + LabyrinthData.Log((object)ex); + } + } + + protected void OnElementModified(ElementEventArgs e) + { + try + { + if (this.ElementModified == null) + return; + this.ElementModified((object)this, e); + } + catch (Exception ex) + { + LabyrinthData.Log((object)ex); + } + } + + protected void OnElementDeleted(ElementEventArgs e) + { + try + { + if (this.ElementDeleted == null) + return; + this.ElementDeleted((object)this, e); + } + catch (Exception ex) + { + LabyrinthData.Log((object)ex); + } + } + + protected void OnStructureAdded(StructureEventArgs e) + { + try + { + if (this.StructureAdded == null) + return; + this.StructureAdded((object)this, e); + } + catch (Exception ex) + { + LabyrinthData.Log((object)ex); + } + } + + protected void OnStructureModified(StructureEventArgs e) + { + try + { + if (this.StructureModified == null) + return; + this.StructureModified((object)this, e); + } + catch (Exception ex) + { + LabyrinthData.Log((object)ex); + } + } + + protected void OnStructureDeleted(StructureEventArgs e) + { + try + { + if (this.StructureDeleted == null) + return; + this.StructureDeleted((object)this, e); + } + catch (Exception ex) + { + LabyrinthData.Log((object)ex); + } + } + + protected void OnTimelineAdded(TimelineEventArgs e) + { + try + { + if (this.TimelineAdded == null) + return; + this.TimelineAdded((object)this, e); + } + catch (Exception ex) + { + LabyrinthData.Log((object)ex); + } + } + + protected void OnTimelineModified(TimelineEventArgs e) + { + try + { + if (this.TimelineModified == null) + return; + this.TimelineModified((object)this, e); + } + catch (Exception ex) + { + LabyrinthData.Log((object)ex); + } + } + + protected void OnTimelineDeleted(TimelineEventArgs e) + { + try + { + if (this.TimelineDeleted == null) + return; + this.TimelineDeleted((object)this, e); + } + catch (Exception ex) + { + LabyrinthData.Log((object)ex); + } + } + + protected void OnNoteAdded(NoteEventArgs e) + { + try + { + if (this.NoteAdded == null) + return; + this.NoteAdded((object)this, e); + } + catch (Exception ex) + { + LabyrinthData.Log((object)ex); + } + } + + protected void OnNoteModified(NoteEventArgs e) + { + try + { + if (this.NoteModified == null) + return; + this.NoteModified((object)this, e); + } + catch (Exception ex) + { + LabyrinthData.Log((object)ex); + } + } + + protected void OnNoteDeleted(NoteEventArgs e) + { + try + { + if (this.NoteDeleted == null) + return; + this.NoteDeleted((object)this, e); + } + catch (Exception ex) + { + LabyrinthData.Log((object)ex); + } + } + + public MainForm(StartupData sd) + { + this.InitializeComponent(); + this.ElementList.ListViewItemSorter = (IComparer)new ListViewSorter(); + this.StructureList.ListViewItemSorter = (IComparer)new ListViewSorter(); + this.TimelineList.ListViewItemSorter = (IComparer)new ListViewSorter(); + this.NoteList.ListViewItemSorter = (IComparer)new ListViewSorter(); + this.ElementList.SmallImageList = (ImageList)null; + this.ElementList.SmallImageList = this.ElementImages; + this.Pages.Appearance = Crownwood.Magic.Controls.TabControl.VisualAppearance.MultiDocument; + this.ElementPage.Selected = true; + Application.Idle += new EventHandler(this.OnIdle); + try + { + this.fAddInMgr.Load(Application.StartupPath + "\\AddIns", (IApplication)this); + if (sd.AddInPath != "") + this.fAddInMgr.Load(sd.AddInPath, (IApplication)this); + this.load_addins(); + } + catch (Exception ex) + { + LabyrinthData.Log((object)ex); + } + try + { + if (sd.FileName != "") + this.open_project(sd.FileName); + else + this.new_project(); + } + catch (Exception ex) + { + LabyrinthData.Log((object)ex); + } + this.update_ui(); + } + + private void MainForm_Closing(object sender, CancelEventArgs e) + { + if (this.ask_for_save()) + { + this.OnProjectClosing(new EventArgs()); + foreach (IAddIn addIn in this.fAddInMgr.AddIns) + { + try + { + addIn.Unload(); + } + catch (Exception ex) + { + LabyrinthData.Log((object)ex); + } + } + } + else + e.Cancel = true; + } + + protected override void Dispose(bool disposing) + { + if (disposing && this.components != null) + this.components.Dispose(); + base.Dispose(disposing); + } + + private void load_addins() + { + foreach (IAddIn addIn in this.fAddInMgr.AddIns) + { + foreach (IAddInComponent component in addIn.Components) + { + IExplorerPage explorerPage = component as IExplorerPage; + if (explorerPage != null) + this.Explorer.TabPages.Add(new Crownwood.Magic.Controls.TabPage(explorerPage.Name, explorerPage.Control, explorerPage.Icon)); + ICustomSearch customSearch = component as ICustomSearch; + if (customSearch != null) + this.fCustomSearches.Add((object)customSearch); + } + } + } + + private void InitializeComponent() + { + this.components = (IContainer)new Container(); + ResourceManager resourceManager = new ResourceManager(typeof(MainForm)); + this.MainMenu = new MainMenu(); + this.FileMenu = new MenuItem(); + this.FileNew = new MenuItem(); + this.FileOpen = new MenuItem(); + this.FileSave = new MenuItem(); + this.FileSaveAs = new MenuItem(); + this.Sep1 = new MenuItem(); + this.FileImport = new MenuItem(); + this.Sep4 = new MenuItem(); + this.FilePageSetup = new MenuItem(); + this.Sep5 = new MenuItem(); + this.FileExit = new MenuItem(); + this.EditMenu = new MenuItem(); + this.EditElements = new MenuItem(); + this.EditElementsNew = new MenuItem(); + this.EditElementsDelete = new MenuItem(); + this.EditElementsProperties = new MenuItem(); + this.EditElementsView = new MenuItem(); + this.EditStructures = new MenuItem(); + this.EditStructuresNew = new MenuItem(); + this.EditStructuresDelete = new MenuItem(); + this.EditStructuresProperties = new MenuItem(); + this.EditStructuresView = new MenuItem(); + this.EditTimelines = new MenuItem(); + this.EditTimelinesNew = new MenuItem(); + this.EditTimelinesDelete = new MenuItem(); + this.EditTimelinesProperties = new MenuItem(); + this.EditTimelinesView = new MenuItem(); + this.EditNotes = new MenuItem(); + this.EditNotesNew = new MenuItem(); + this.EditNotesDelete = new MenuItem(); + this.EditNotesProperties = new MenuItem(); + this.EditNotesView = new MenuItem(); + this.Sep6 = new MenuItem(); + this.EditProjectProperties = new MenuItem(); + this.ViewMenu = new MenuItem(); + this.ViewExplorer = new MenuItem(); + this.ViewToolbar = new MenuItem(); + this.ViewStatusbar = new MenuItem(); + this.ViewPageTabs = new MenuItem(); + this.ToolsMenu = new MenuItem(); + this.ToolsSearch = new MenuItem(); + this.ToolsTaskList = new MenuItem(); + this.ToolsAnnotations = new MenuItem(); + this.ToolsCalendar = new MenuItem(); + this.Sep3 = new MenuItem(); + this.ToolsAddIns = new MenuItem(); + this.ToolsAddinsNone = new MenuItem(); + this.ToolsMergeElements = new MenuItem(); + this.WindowMenu = new MenuItem(); + this.WindowClose = new MenuItem(); + this.WindowCloseAll = new MenuItem(); + this.WindowCloseAllExcept = new MenuItem(); + this.Sep7 = new MenuItem(); + this.WindowPages = new MenuItem(); + this.HelpMenu = new MenuItem(); + this.HelpContents = new MenuItem(); + this.HelpAbout = new MenuItem(); + this.StatusBar = new StatusBar(); + this.NameStatusPanel = new StatusBarPanel(); + this.ElementStatusPanel = new StatusBarPanel(); + this.StructureStatusPanel = new StatusBarPanel(); + this.TimelineStatusPanel = new StatusBarPanel(); + this.NoteStatusPanel = new StatusBarPanel(); + this.MainToolBar = new ToolBar(); + this.MainNewBtn = new ToolBarButton(); + this.MainOpenBtn = new ToolBarButton(); + this.MainSaveBtn = new ToolBarButton(); + this.Sep2 = new ToolBarButton(); + this.MainPropertiesBtn = new ToolBarButton(); + this.MainTasksBtn = new ToolBarButton(); + this.MainAnnotationsBtn = new ToolBarButton(); + this.MainCalendarBtn = new ToolBarButton(); + this.MainSearchBtn = new ToolBarButton(); + this.Images = new ImageList(this.components); + this.Explorer = new Crownwood.Magic.Controls.TabControl(); + this.ElementImages = new ImageList(this.components); + this.ElementPage = new Crownwood.Magic.Controls.TabPage(); + this.ElementList = new ListView(); + this.ElementNameHdr = new ColumnHeader(); + this.ElementContextMenu = new ContextMenu(); + this.ElementNew = new MenuItem(); + this.ElementDelete = new MenuItem(); + this.ElementProperties = new MenuItem(); + this.ElementView = new MenuItem(); + this.ElementToolbar = new ToolBar(); + this.ElementNewBtn = new ToolBarButton(); + this.ElementDeleteBtn = new ToolBarButton(); + this.ElementPropertiesBtn = new ToolBarButton(); + this.ElementViewBtn = new ToolBarButton(); + this.StructurePage = new Crownwood.Magic.Controls.TabPage(); + this.StructureList = new ListView(); + this.StructureNameHdr = new ColumnHeader(); + this.StructureContextMenu = new ContextMenu(); + this.StructureNew = new MenuItem(); + this.StructureDelete = new MenuItem(); + this.StructureProperties = new MenuItem(); + this.StructureView = new MenuItem(); + this.StructureToolbar = new ToolBar(); + this.StructureNewBtn = new ToolBarButton(); + this.StructureDeleteBtn = new ToolBarButton(); + this.StructurePropertiesBtn = new ToolBarButton(); + this.StructureViewBtn = new ToolBarButton(); + this.TimelinePage = new Crownwood.Magic.Controls.TabPage(); + this.TimelineList = new ListView(); + this.TimelineNameHdr = new ColumnHeader(); + this.TimelineContextMenu = new ContextMenu(); + this.TimelineNew = new MenuItem(); + this.TimelineDelete = new MenuItem(); + this.TimelineProperties = new MenuItem(); + this.TimelineView = new MenuItem(); + this.TimelineToolbar = new ToolBar(); + this.TimelineNewBtn = new ToolBarButton(); + this.TimelineDeleteBtn = new ToolBarButton(); + this.TimelinePropertiesBtn = new ToolBarButton(); + this.TimelineViewBtn = new ToolBarButton(); + this.NotePage = new Crownwood.Magic.Controls.TabPage(); + this.NoteList = new ListView(); + this.NoteNameHdr = new ColumnHeader(); + this.NoteContextMenu = new ContextMenu(); + this.NoteNew = new MenuItem(); + this.NoteDelete = new MenuItem(); + this.NoteProperties = new MenuItem(); + this.NoteView = new MenuItem(); + this.NoteToolbar = new ToolBar(); + this.NoteNewBtn = new ToolBarButton(); + this.NoteDeleteBtn = new ToolBarButton(); + this.NotePropertiesBtn = new ToolBarButton(); + this.NoteViewBtn = new ToolBarButton(); + this.ExplorerSplitter = new Splitter(); + this.Pages = new Crownwood.Magic.Controls.TabControl(); + this.Sep8 = new MenuItem(); + this.NameStatusPanel.BeginInit(); + this.ElementStatusPanel.BeginInit(); + this.StructureStatusPanel.BeginInit(); + this.TimelineStatusPanel.BeginInit(); + this.NoteStatusPanel.BeginInit(); + this.ElementPage.SuspendLayout(); + this.StructurePage.SuspendLayout(); + this.TimelinePage.SuspendLayout(); + this.NotePage.SuspendLayout(); + this.SuspendLayout(); + this.MainMenu.MenuItems.AddRange(new MenuItem[6] + { + this.FileMenu, + this.EditMenu, + this.ViewMenu, + this.ToolsMenu, + this.WindowMenu, + this.HelpMenu + }); + this.FileMenu.Index = 0; + this.FileMenu.MenuItems.AddRange(new MenuItem[10] + { + this.FileNew, + this.FileOpen, + this.FileSave, + this.FileSaveAs, + this.Sep1, + this.FileImport, + this.Sep4, + this.FilePageSetup, + this.Sep5, + this.FileExit + }); + this.FileMenu.Text = "File"; + this.FileNew.Index = 0; + this.FileNew.Shortcut = Shortcut.CtrlN; + this.FileNew.Text = "New"; + this.FileNew.Click += new EventHandler(this.FileNew_Click); + this.FileOpen.Index = 1; + this.FileOpen.Shortcut = Shortcut.CtrlO; + this.FileOpen.Text = "Open..."; + this.FileOpen.Click += new EventHandler(this.FileOpen_Click); + this.FileSave.Index = 2; + this.FileSave.Shortcut = Shortcut.CtrlS; + this.FileSave.Text = "Save"; + this.FileSave.Click += new EventHandler(this.FileSave_Click); + this.FileSaveAs.Index = 3; + this.FileSaveAs.Text = "Save As..."; + this.FileSaveAs.Click += new EventHandler(this.FileSaveAs_Click); + this.Sep1.Index = 4; + this.Sep1.Text = "-"; + this.FileImport.Index = 5; + this.FileImport.Text = "Import..."; + this.FileImport.Click += new EventHandler(this.FileImport_Click); + this.Sep4.Index = 6; + this.Sep4.Text = "-"; + this.FilePageSetup.Index = 7; + this.FilePageSetup.Text = "Page Setup"; + this.FilePageSetup.Click += new EventHandler(this.FilePageSetup_Click); + this.Sep5.Index = 8; + this.Sep5.Text = "-"; + this.FileExit.Index = 9; + this.FileExit.Text = "Exit"; + this.FileExit.Click += new EventHandler(this.FileExit_Click); + this.EditMenu.Index = 1; + this.EditMenu.MenuItems.AddRange(new MenuItem[6] + { + this.EditElements, + this.EditStructures, + this.EditTimelines, + this.EditNotes, + this.Sep6, + this.EditProjectProperties + }); + this.EditMenu.Text = "Edit"; + this.EditElements.Index = 0; + this.EditElements.MenuItems.AddRange(new MenuItem[4] + { + this.EditElementsNew, + this.EditElementsDelete, + this.EditElementsProperties, + this.EditElementsView + }); + this.EditElements.Text = "Elements"; + this.EditElementsNew.Index = 0; + this.EditElementsNew.Text = "New..."; + this.EditElementsNew.Click += new EventHandler(this.EditElementsNew_Click); + this.EditElementsDelete.Index = 1; + this.EditElementsDelete.Text = "Delete"; + this.EditElementsDelete.Click += new EventHandler(this.EditElementsDelete_Click); + this.EditElementsProperties.Index = 2; + this.EditElementsProperties.Text = "Properties"; + this.EditElementsProperties.Click += new EventHandler(this.EditElementsProperties_Click); + this.EditElementsView.Index = 3; + this.EditElementsView.Text = "Open"; + this.EditElementsView.Click += new EventHandler(this.EditElementsView_Click); + this.EditStructures.Index = 1; + this.EditStructures.MenuItems.AddRange(new MenuItem[4] + { + this.EditStructuresNew, + this.EditStructuresDelete, + this.EditStructuresProperties, + this.EditStructuresView + }); + this.EditStructures.Text = "Structures"; + this.EditStructuresNew.Index = 0; + this.EditStructuresNew.Text = "New..."; + this.EditStructuresNew.Click += new EventHandler(this.EditStructuresNew_Click); + this.EditStructuresDelete.Index = 1; + this.EditStructuresDelete.Text = "Delete"; + this.EditStructuresDelete.Click += new EventHandler(this.EditStructuresDelete_Click); + this.EditStructuresProperties.Index = 2; + this.EditStructuresProperties.Text = "Properties"; + this.EditStructuresProperties.Click += new EventHandler(this.EditStructuresProperties_Click); + this.EditStructuresView.Index = 3; + this.EditStructuresView.Text = "Open"; + this.EditStructuresView.Click += new EventHandler(this.EditStructuresView_Click); + this.EditTimelines.Index = 2; + this.EditTimelines.MenuItems.AddRange(new MenuItem[4] + { + this.EditTimelinesNew, + this.EditTimelinesDelete, + this.EditTimelinesProperties, + this.EditTimelinesView + }); + this.EditTimelines.Text = "Timelines"; + this.EditTimelinesNew.Index = 0; + this.EditTimelinesNew.Text = "New..."; + this.EditTimelinesNew.Click += new EventHandler(this.EditTimelinesNew_Click); + this.EditTimelinesDelete.Index = 1; + this.EditTimelinesDelete.Text = "Delete"; + this.EditTimelinesDelete.Click += new EventHandler(this.EditTimelinesDelete_Click); + this.EditTimelinesProperties.Index = 2; + this.EditTimelinesProperties.Text = "Properties"; + this.EditTimelinesProperties.Click += new EventHandler(this.EditTimelinesProperties_Click); + this.EditTimelinesView.Index = 3; + this.EditTimelinesView.Text = "Open"; + this.EditTimelinesView.Click += new EventHandler(this.EditTimelinesView_Click); + this.EditNotes.Index = 3; + this.EditNotes.MenuItems.AddRange(new MenuItem[4] + { + this.EditNotesNew, + this.EditNotesDelete, + this.EditNotesProperties, + this.EditNotesView + }); + this.EditNotes.Text = "Notes"; + this.EditNotesNew.Index = 0; + this.EditNotesNew.Text = "New..."; + this.EditNotesNew.Click += new EventHandler(this.EditNotesNew_Click); + this.EditNotesDelete.Index = 1; + this.EditNotesDelete.Text = "Delete"; + this.EditNotesDelete.Click += new EventHandler(this.EditNotesDelete_Click); + this.EditNotesProperties.Index = 2; + this.EditNotesProperties.Text = "Properties"; + this.EditNotesProperties.Click += new EventHandler(this.EditNotesProperties_Click); + this.EditNotesView.Index = 3; + this.EditNotesView.Text = "Open"; + this.EditNotesView.Click += new EventHandler(this.EditNotesView_Click); + this.Sep6.Index = 4; + this.Sep6.Text = "-"; + this.EditProjectProperties.Index = 5; + this.EditProjectProperties.Text = "Project Properties"; + this.EditProjectProperties.Click += new EventHandler(this.EditProjectProperties_Click); + this.ViewMenu.Index = 2; + this.ViewMenu.MenuItems.AddRange(new MenuItem[4] + { + this.ViewExplorer, + this.ViewToolbar, + this.ViewStatusbar, + this.ViewPageTabs + }); + this.ViewMenu.Text = "View"; + this.ViewExplorer.Index = 0; + this.ViewExplorer.Text = "Explorer"; + this.ViewExplorer.Click += new EventHandler(this.ViewExplorer_Click); + this.ViewToolbar.Index = 1; + this.ViewToolbar.Text = "Toolbar"; + this.ViewToolbar.Click += new EventHandler(this.ViewToolbar_Click); + this.ViewStatusbar.Index = 2; + this.ViewStatusbar.Text = "Statusbar"; + this.ViewStatusbar.Click += new EventHandler(this.ViewStatusbar_Click); + this.ViewPageTabs.Index = 3; + this.ViewPageTabs.Text = "Page Tabs"; + this.ViewPageTabs.Click += new EventHandler(this.ViewPageTabs_Click); + this.ToolsMenu.Index = 3; + this.ToolsMenu.MenuItems.AddRange(new MenuItem[8] + { + this.ToolsSearch, + this.ToolsTaskList, + this.ToolsAnnotations, + this.ToolsCalendar, + this.Sep3, + this.ToolsMergeElements, + this.Sep8, + this.ToolsAddIns + }); + this.ToolsMenu.Text = "Tools"; + this.ToolsSearch.Index = 0; + this.ToolsSearch.Shortcut = Shortcut.F3; + this.ToolsSearch.Text = "Search"; + this.ToolsSearch.Click += new EventHandler(this.ToolsSearch_Click); + this.ToolsTaskList.Index = 1; + this.ToolsTaskList.Text = "Task List"; + this.ToolsTaskList.Click += new EventHandler(this.ToolsTaskList_Click); + this.ToolsAnnotations.Index = 2; + this.ToolsAnnotations.Text = "Annotations"; + this.ToolsAnnotations.Click += new EventHandler(this.ToolsAnnotations_Click); + this.ToolsCalendar.Index = 3; + this.ToolsCalendar.Text = "Calendar"; + this.ToolsCalendar.Click += new EventHandler(this.ToolsCalendar_Click); + this.Sep3.Index = 4; + this.Sep3.Text = "-"; + this.ToolsAddIns.Index = 7; + this.ToolsAddIns.MenuItems.AddRange(new MenuItem[1] + { + this.ToolsAddinsNone + }); + this.ToolsAddIns.Text = "Add-Ins"; + this.ToolsAddIns.Popup += new EventHandler(this.ToolsAddIns_Popup); + this.ToolsAddinsNone.Enabled = false; + this.ToolsAddinsNone.Index = 0; + this.ToolsAddinsNone.Text = "None"; + this.ToolsMergeElements.Index = 5; + this.ToolsMergeElements.Text = "Merge Elements..."; + this.ToolsMergeElements.Click += new EventHandler(this.ToolsMergeElements_Click); + this.WindowMenu.Index = 4; + this.WindowMenu.MenuItems.AddRange(new MenuItem[5] + { + this.WindowClose, + this.WindowCloseAll, + this.WindowCloseAllExcept, + this.Sep7, + this.WindowPages + }); + this.WindowMenu.Text = "Window"; + this.WindowMenu.Popup += new EventHandler(this.WindowMenu_Popup); + this.WindowClose.Index = 0; + this.WindowClose.Text = "&Close"; + this.WindowClose.Click += new EventHandler(this.WindowClose_Click); + this.WindowCloseAll.Index = 1; + this.WindowCloseAll.Text = "Close &All"; + this.WindowCloseAll.Click += new EventHandler(this.WindowCloseAll_Click); + this.WindowCloseAllExcept.Index = 2; + this.WindowCloseAllExcept.Text = "Close All E&xcept"; + this.WindowCloseAllExcept.Click += new EventHandler(this.WindowCloseAllExcept_Click); + this.Sep7.Index = 3; + this.Sep7.Text = "-"; + this.WindowPages.Index = 4; + this.WindowPages.Text = "Pages"; + this.HelpMenu.Index = 5; + this.HelpMenu.MenuItems.AddRange(new MenuItem[2] + { + this.HelpContents, + this.HelpAbout + }); + this.HelpMenu.Text = "Help"; + this.HelpContents.Index = 0; + this.HelpContents.Shortcut = Shortcut.F1; + this.HelpContents.Text = "Contents"; + this.HelpContents.Click += new EventHandler(this.HelpContents_Click); + this.HelpAbout.Index = 1; + this.HelpAbout.Text = "About"; + this.HelpAbout.Click += new EventHandler(this.HelpAbout_Click); + this.StatusBar.Location = new Point(0, 379); + this.StatusBar.Name = "StatusBar"; + this.StatusBar.Panels.AddRange(new StatusBarPanel[5] + { + this.NameStatusPanel, + this.ElementStatusPanel, + this.StructureStatusPanel, + this.TimelineStatusPanel, + this.NoteStatusPanel + }); + this.StatusBar.ShowPanels = true; + this.StatusBar.Size = new Size(712, 22); + this.StatusBar.TabIndex = 1; + this.StatusBar.PanelClick += new StatusBarPanelClickEventHandler(this.StatusBar_PanelClick); + this.NameStatusPanel.AutoSize = StatusBarPanelAutoSize.Spring; + this.NameStatusPanel.Text = "Project: X"; + this.NameStatusPanel.Width = 407; + this.ElementStatusPanel.AutoSize = StatusBarPanelAutoSize.Contents; + this.ElementStatusPanel.Text = "Elements: X"; + this.ElementStatusPanel.Width = 75; + this.StructureStatusPanel.AutoSize = StatusBarPanelAutoSize.Contents; + this.StructureStatusPanel.Text = "Structures: X"; + this.StructureStatusPanel.Width = 80; + this.TimelineStatusPanel.AutoSize = StatusBarPanelAutoSize.Contents; + this.TimelineStatusPanel.Text = "Timelines: X"; + this.TimelineStatusPanel.Width = 77; + this.NoteStatusPanel.AutoSize = StatusBarPanelAutoSize.Contents; + this.NoteStatusPanel.Text = "Notes: X"; + this.NoteStatusPanel.Width = 57; + this.MainToolBar.Appearance = ToolBarAppearance.Flat; + this.MainToolBar.Buttons.AddRange(new ToolBarButton[9] + { + this.MainNewBtn, + this.MainOpenBtn, + this.MainSaveBtn, + this.Sep2, + this.MainPropertiesBtn, + this.MainTasksBtn, + this.MainAnnotationsBtn, + this.MainCalendarBtn, + this.MainSearchBtn + }); + this.MainToolBar.DropDownArrows = true; + this.MainToolBar.ImageList = this.Images; + this.MainToolBar.Name = "MainToolBar"; + this.MainToolBar.ShowToolTips = true; + this.MainToolBar.Size = new Size(712, 25); + this.MainToolBar.TabIndex = 0; + this.MainToolBar.ButtonClick += new ToolBarButtonClickEventHandler(this.MainToolBar_ButtonClick); + this.MainNewBtn.ImageIndex = 0; + this.MainNewBtn.ToolTipText = "New"; + this.MainOpenBtn.ImageIndex = 1; + this.MainOpenBtn.ToolTipText = "Open"; + this.MainSaveBtn.ImageIndex = 2; + this.MainSaveBtn.ToolTipText = "Save"; + this.Sep2.Style = ToolBarButtonStyle.Separator; + this.MainPropertiesBtn.ImageIndex = 5; + this.MainPropertiesBtn.ToolTipText = "Project Properties"; + this.MainTasksBtn.ImageIndex = 15; + this.MainTasksBtn.ToolTipText = "Task List"; + this.MainAnnotationsBtn.ImageIndex = 16; + this.MainAnnotationsBtn.ToolTipText = "Annotations List"; + this.MainCalendarBtn.ImageIndex = 17; + this.MainCalendarBtn.ToolTipText = "Calendar"; + this.MainSearchBtn.ImageIndex = 6; + this.MainSearchBtn.ToolTipText = "Search"; + this.Images.ColorDepth = ColorDepth.Depth8Bit; + this.Images.ImageSize = new Size(16, 16); + this.Images.ImageStream = (ImageListStreamer)resourceManager.GetObject("Images.ImageStream"); + this.Images.TransparentColor = Color.Magenta; + this.Explorer.Dock = DockStyle.Left; + this.Explorer.HideTabsMode = Crownwood.Magic.Controls.TabControl.HideTabsModes.ShowAlways; + this.Explorer.ImageList = this.ElementImages; + this.Explorer.Location = new Point(0, 25); + this.Explorer.Name = "Explorer"; + this.Explorer.SelectedIndex = 0; + this.Explorer.SelectedTab = this.ElementPage; + this.Explorer.SelectedTextOnly = true; + this.Explorer.ShowArrows = true; + this.Explorer.ShrinkPagesToFit = false; + this.Explorer.Size = new Size(208, 354); + this.Explorer.TabIndex = 2; + this.Explorer.TabPages.AddRange(new Crownwood.Magic.Controls.TabPage[4] + { + this.ElementPage, + this.StructurePage, + this.TimelinePage, + this.NotePage + }); + this.ElementImages.ColorDepth = ColorDepth.Depth8Bit; + this.ElementImages.ImageSize = new Size(16, 16); + this.ElementImages.ImageStream = (ImageListStreamer)resourceManager.GetObject("ElementImages.ImageStream"); + this.ElementImages.TransparentColor = Color.Magenta; + this.ElementPage.Controls.AddRange(new Control[2] + { + (Control) this.ElementList, + (Control) this.ElementToolbar + }); + this.ElementPage.ImageIndex = 1; + this.ElementPage.Name = "ElementPage"; + this.ElementPage.Size = new Size(208, 329); + this.ElementPage.TabIndex = 0; + this.ElementPage.Title = "Elements"; + this.ElementList.Columns.AddRange(new ColumnHeader[1] + { + this.ElementNameHdr + }); + this.ElementList.ContextMenu = this.ElementContextMenu; + this.ElementList.Dock = DockStyle.Fill; + this.ElementList.FullRowSelect = true; + this.ElementList.LargeImageList = this.ElementImages; + this.ElementList.Location = new Point(0, 25); + this.ElementList.Name = "ElementList"; + this.ElementList.Size = new Size(208, 304); + this.ElementList.SmallImageList = this.ElementImages; + this.ElementList.Sorting = SortOrder.Ascending; + this.ElementList.TabIndex = 1; + this.ElementList.View = View.Details; + this.ElementList.MouseDown += new MouseEventHandler(this.ElementList_MouseDown); + this.ElementList.DoubleClick += new EventHandler(this.ElementList_DoubleClick); + this.ElementList.ColumnClick += new ColumnClickEventHandler(this.ElementList_ColumnClick); + this.ElementList.ItemDrag += new ItemDragEventHandler(this.ElementList_ItemDrag); + this.ElementNameHdr.Text = "Name"; + this.ElementNameHdr.Width = 120; + this.ElementContextMenu.MenuItems.AddRange(new MenuItem[4] + { + this.ElementNew, + this.ElementDelete, + this.ElementProperties, + this.ElementView + }); + this.ElementNew.Index = 0; + this.ElementNew.Shortcut = Shortcut.F2; + this.ElementNew.Text = "New Element..."; + this.ElementNew.Click += new EventHandler(this.EditElementsNew_Click); + this.ElementDelete.Index = 1; + this.ElementDelete.Text = "Delete Element"; + this.ElementDelete.Click += new EventHandler(this.EditElementsDelete_Click); + this.ElementProperties.Index = 2; + this.ElementProperties.Shortcut = Shortcut.F4; + this.ElementProperties.Text = "Element Properties"; + this.ElementProperties.Click += new EventHandler(this.EditElementsProperties_Click); + this.ElementView.Index = 3; + this.ElementView.Shortcut = Shortcut.F10; + this.ElementView.Text = "Open Element"; + this.ElementView.Click += new EventHandler(this.EditElementsView_Click); + this.ElementToolbar.Appearance = ToolBarAppearance.Flat; + this.ElementToolbar.Buttons.AddRange(new ToolBarButton[4] + { + this.ElementNewBtn, + this.ElementDeleteBtn, + this.ElementPropertiesBtn, + this.ElementViewBtn + }); + this.ElementToolbar.DropDownArrows = true; + this.ElementToolbar.ImageList = this.Images; + this.ElementToolbar.Name = "ElementToolbar"; + this.ElementToolbar.ShowToolTips = true; + this.ElementToolbar.Size = new Size(208, 25); + this.ElementToolbar.TabIndex = 0; + this.ElementToolbar.ButtonClick += new ToolBarButtonClickEventHandler(this.ElementToolbar_ButtonClick); + this.ElementNewBtn.ImageIndex = 7; + this.ElementNewBtn.ToolTipText = "New"; + this.ElementDeleteBtn.ImageIndex = 4; + this.ElementDeleteBtn.ToolTipText = "Delete"; + this.ElementPropertiesBtn.ImageIndex = 5; + this.ElementPropertiesBtn.ToolTipText = "Properties"; + this.ElementViewBtn.ImageIndex = 11; + this.ElementViewBtn.ToolTipText = "View"; + this.StructurePage.Controls.AddRange(new Control[2] + { + (Control) this.StructureList, + (Control) this.StructureToolbar + }); + this.StructurePage.ImageIndex = 18; + this.StructurePage.Name = "StructurePage"; + this.StructurePage.Selected = false; + this.StructurePage.Size = new Size(208, 329); + this.StructurePage.TabIndex = 1; + this.StructurePage.Title = "Structures"; + this.StructureList.Columns.AddRange(new ColumnHeader[1] + { + this.StructureNameHdr + }); + this.StructureList.ContextMenu = this.StructureContextMenu; + this.StructureList.Dock = DockStyle.Fill; + this.StructureList.FullRowSelect = true; + this.StructureList.Location = new Point(0, 39); + this.StructureList.Name = "StructureList"; + this.StructureList.Size = new Size(208, 290); + this.StructureList.SmallImageList = this.ElementImages; + this.StructureList.Sorting = SortOrder.Ascending; + this.StructureList.TabIndex = 2; + this.StructureList.View = View.Details; + this.StructureList.MouseDown += new MouseEventHandler(this.StructureList_MouseDown); + this.StructureList.DoubleClick += new EventHandler(this.StructureList_DoubleClick); + this.StructureList.ColumnClick += new ColumnClickEventHandler(this.StructureList_ColumnClick); + this.StructureList.ItemDrag += new ItemDragEventHandler(this.StructureList_ItemDrag); + this.StructureNameHdr.Text = "Name"; + this.StructureNameHdr.Width = 120; + this.StructureContextMenu.MenuItems.AddRange(new MenuItem[4] + { + this.StructureNew, + this.StructureDelete, + this.StructureProperties, + this.StructureView + }); + this.StructureNew.Index = 0; + this.StructureNew.Shortcut = Shortcut.F2; + this.StructureNew.Text = "New Structure..."; + this.StructureNew.Click += new EventHandler(this.EditStructuresNew_Click); + this.StructureDelete.Index = 1; + this.StructureDelete.Text = "Delete Structure"; + this.StructureDelete.Click += new EventHandler(this.EditStructuresDelete_Click); + this.StructureProperties.Index = 2; + this.StructureProperties.Shortcut = Shortcut.F4; + this.StructureProperties.Text = "Structure Properties"; + this.StructureProperties.Click += new EventHandler(this.EditStructuresProperties_Click); + this.StructureView.Index = 3; + this.StructureView.Shortcut = Shortcut.F10; + this.StructureView.Text = "Open Structure"; + this.StructureView.Click += new EventHandler(this.EditStructuresView_Click); + this.StructureToolbar.Appearance = ToolBarAppearance.Flat; + this.StructureToolbar.Buttons.AddRange(new ToolBarButton[4] + { + this.StructureNewBtn, + this.StructureDeleteBtn, + this.StructurePropertiesBtn, + this.StructureViewBtn + }); + this.StructureToolbar.DropDownArrows = true; + this.StructureToolbar.ImageList = this.Images; + this.StructureToolbar.Name = "StructureToolbar"; + this.StructureToolbar.ShowToolTips = true; + this.StructureToolbar.Size = new Size(208, 39); + this.StructureToolbar.TabIndex = 1; + this.StructureToolbar.ButtonClick += new ToolBarButtonClickEventHandler(this.StructureToolbar_ButtonClick); + this.StructureNewBtn.ImageIndex = 8; + this.StructureNewBtn.ToolTipText = "New"; + this.StructureDeleteBtn.ImageIndex = 4; + this.StructureDeleteBtn.ToolTipText = "Delete"; + this.StructurePropertiesBtn.ImageIndex = 5; + this.StructurePropertiesBtn.ToolTipText = "Properties"; + this.StructureViewBtn.ImageIndex = 12; + this.StructureViewBtn.ToolTipText = "View"; + this.TimelinePage.Controls.AddRange(new Control[2] + { + (Control) this.TimelineList, + (Control) this.TimelineToolbar + }); + this.TimelinePage.ImageIndex = 19; + this.TimelinePage.Name = "TimelinePage"; + this.TimelinePage.Selected = false; + this.TimelinePage.Size = new Size(208, 329); + this.TimelinePage.TabIndex = 2; + this.TimelinePage.Title = "Timelines"; + this.TimelineList.Columns.AddRange(new ColumnHeader[1] + { + this.TimelineNameHdr + }); + this.TimelineList.ContextMenu = this.TimelineContextMenu; + this.TimelineList.Dock = DockStyle.Fill; + this.TimelineList.Font = new Font("Tahoma", 11f, FontStyle.Regular, GraphicsUnit.World); + this.TimelineList.FullRowSelect = true; + this.TimelineList.Location = new Point(0, 39); + this.TimelineList.Name = "TimelineList"; + this.TimelineList.Size = new Size(208, 290); + this.TimelineList.SmallImageList = this.ElementImages; + this.TimelineList.Sorting = SortOrder.Ascending; + this.TimelineList.TabIndex = 2; + this.TimelineList.View = View.Details; + this.TimelineList.MouseDown += new MouseEventHandler(this.TimelineList_MouseDown); + this.TimelineList.DoubleClick += new EventHandler(this.TimelineList_DoubleClick); + this.TimelineList.ColumnClick += new ColumnClickEventHandler(this.TimelineList_ColumnClick); + this.TimelineList.ItemDrag += new ItemDragEventHandler(this.TimelineList_ItemDrag); + this.TimelineNameHdr.Text = "Name"; + this.TimelineNameHdr.Width = 120; + this.TimelineContextMenu.MenuItems.AddRange(new MenuItem[4] + { + this.TimelineNew, + this.TimelineDelete, + this.TimelineProperties, + this.TimelineView + }); + this.TimelineNew.Index = 0; + this.TimelineNew.Shortcut = Shortcut.F2; + this.TimelineNew.Text = "New Timeline..."; + this.TimelineNew.Click += new EventHandler(this.EditTimelinesNew_Click); + this.TimelineDelete.Index = 1; + this.TimelineDelete.Text = "Delete Timeline"; + this.TimelineDelete.Click += new EventHandler(this.EditTimelinesDelete_Click); + this.TimelineProperties.Index = 2; + this.TimelineProperties.Shortcut = Shortcut.F4; + this.TimelineProperties.Text = "Timeline Properties"; + this.TimelineProperties.Click += new EventHandler(this.EditTimelinesProperties_Click); + this.TimelineView.Index = 3; + this.TimelineView.Shortcut = Shortcut.F10; + this.TimelineView.Text = "Open Timeline"; + this.TimelineView.Click += new EventHandler(this.EditTimelinesView_Click); + this.TimelineToolbar.Appearance = ToolBarAppearance.Flat; + this.TimelineToolbar.Buttons.AddRange(new ToolBarButton[4] + { + this.TimelineNewBtn, + this.TimelineDeleteBtn, + this.TimelinePropertiesBtn, + this.TimelineViewBtn + }); + this.TimelineToolbar.DropDownArrows = true; + this.TimelineToolbar.ImageList = this.Images; + this.TimelineToolbar.Name = "TimelineToolbar"; + this.TimelineToolbar.ShowToolTips = true; + this.TimelineToolbar.Size = new Size(208, 39); + this.TimelineToolbar.TabIndex = 1; + this.TimelineToolbar.ButtonClick += new ToolBarButtonClickEventHandler(this.TimelineToolbar_ButtonClick); + this.TimelineNewBtn.ImageIndex = 9; + this.TimelineNewBtn.ToolTipText = "New"; + this.TimelineDeleteBtn.ImageIndex = 4; + this.TimelineDeleteBtn.ToolTipText = "Delete"; + this.TimelinePropertiesBtn.ImageIndex = 5; + this.TimelinePropertiesBtn.ToolTipText = "Properties"; + this.TimelineViewBtn.ImageIndex = 13; + this.TimelineViewBtn.ToolTipText = "View"; + this.NotePage.Controls.AddRange(new Control[2] + { + (Control) this.NoteList, + (Control) this.NoteToolbar + }); + this.NotePage.ImageIndex = 25; + this.NotePage.Name = "NotePage"; + this.NotePage.Selected = false; + this.NotePage.Size = new Size(208, 329); + this.NotePage.TabIndex = 3; + this.NotePage.Title = "Notes"; + this.NoteList.Columns.AddRange(new ColumnHeader[1] + { + this.NoteNameHdr + }); + this.NoteList.ContextMenu = this.NoteContextMenu; + this.NoteList.Dock = DockStyle.Fill; + this.NoteList.FullRowSelect = true; + this.NoteList.LargeImageList = this.ElementImages; + this.NoteList.Location = new Point(0, 39); + this.NoteList.Name = "NoteList"; + this.NoteList.Size = new Size(208, 290); + this.NoteList.SmallImageList = this.ElementImages; + this.NoteList.Sorting = SortOrder.Ascending; + this.NoteList.TabIndex = 3; + this.NoteList.View = View.Details; + this.NoteList.MouseDown += new MouseEventHandler(this.NoteList_MouseDown); + this.NoteList.DoubleClick += new EventHandler(this.NoteList_DoubleClick); + this.NoteList.ColumnClick += new ColumnClickEventHandler(this.NoteList_ColumnClick); + this.NoteList.ItemDrag += new ItemDragEventHandler(this.NoteList_ItemDrag); + this.NoteNameHdr.Text = "Name"; + this.NoteNameHdr.Width = 120; + this.NoteContextMenu.MenuItems.AddRange(new MenuItem[4] + { + this.NoteNew, + this.NoteDelete, + this.NoteProperties, + this.NoteView + }); + this.NoteNew.Index = 0; + this.NoteNew.Shortcut = Shortcut.F2; + this.NoteNew.Text = "New Note..."; + this.NoteNew.Click += new EventHandler(this.EditNotesNew_Click); + this.NoteDelete.Index = 1; + this.NoteDelete.Text = "Delete Note"; + this.NoteDelete.Click += new EventHandler(this.EditNotesDelete_Click); + this.NoteProperties.Index = 2; + this.NoteProperties.Shortcut = Shortcut.F4; + this.NoteProperties.Text = "Note Properties"; + this.NoteProperties.Click += new EventHandler(this.EditNotesProperties_Click); + this.NoteView.Index = 3; + this.NoteView.Shortcut = Shortcut.F10; + this.NoteView.Text = "Open Note"; + this.NoteView.Click += new EventHandler(this.EditNotesView_Click); + this.NoteToolbar.Appearance = ToolBarAppearance.Flat; + this.NoteToolbar.Buttons.AddRange(new ToolBarButton[4] + { + this.NoteNewBtn, + this.NoteDeleteBtn, + this.NotePropertiesBtn, + this.NoteViewBtn + }); + this.NoteToolbar.DropDownArrows = true; + this.NoteToolbar.ImageList = this.Images; + this.NoteToolbar.Name = "NoteToolbar"; + this.NoteToolbar.ShowToolTips = true; + this.NoteToolbar.Size = new Size(208, 39); + this.NoteToolbar.TabIndex = 2; + this.NoteToolbar.ButtonClick += new ToolBarButtonClickEventHandler(this.NoteToolbar_ButtonClick); + this.NoteNewBtn.ImageIndex = 10; + this.NoteNewBtn.ToolTipText = "New"; + this.NoteDeleteBtn.ImageIndex = 4; + this.NoteDeleteBtn.ToolTipText = "Delete"; + this.NotePropertiesBtn.ImageIndex = 5; + this.NotePropertiesBtn.ToolTipText = "Properties"; + this.NoteViewBtn.ImageIndex = 14; + this.NoteViewBtn.ToolTipText = "View"; + this.ExplorerSplitter.Location = new Point(208, 25); + this.ExplorerSplitter.Name = "ExplorerSplitter"; + this.ExplorerSplitter.Size = new Size(3, 354); + this.ExplorerSplitter.TabIndex = 3; + this.ExplorerSplitter.TabStop = false; + this.Pages.Dock = DockStyle.Fill; + this.Pages.HideTabsMode = Crownwood.Magic.Controls.TabControl.HideTabsModes.ShowAlways; + this.Pages.ImageList = this.ElementImages; + this.Pages.Location = new Point(211, 25); + this.Pages.Name = "Pages"; + this.Pages.Size = new Size(501, 354); + this.Pages.TabIndex = 2; + this.Pages.ClosePressed += new EventHandler(this.Pages_ClosePressed); + this.Sep8.Index = 6; + this.Sep8.Text = "-"; + this.AutoScaleBaseSize = new Size(5, 14); + this.ClientSize = new Size(712, 401); + this.Controls.AddRange(new Control[5] + { + (Control) this.Pages, + (Control) this.ExplorerSplitter, + (Control) this.Explorer, + (Control) this.StatusBar, + (Control) this.MainToolBar + }); + this.Font = new Font("Tahoma", 11f, FontStyle.Regular, GraphicsUnit.World, (byte)0); + this.Icon = (Icon)resourceManager.GetObject("$this.Icon"); + this.Menu = this.MainMenu; + this.Name = nameof(MainForm); + this.Text = "Labyrinth"; + this.Closing += new CancelEventHandler(this.MainForm_Closing); + this.NameStatusPanel.EndInit(); + this.ElementStatusPanel.EndInit(); + this.StructureStatusPanel.EndInit(); + this.TimelineStatusPanel.EndInit(); + this.NoteStatusPanel.EndInit(); + this.ElementPage.ResumeLayout(false); + this.StructurePage.ResumeLayout(false); + this.TimelinePage.ResumeLayout(false); + this.NotePage.ResumeLayout(false); + this.ResumeLayout(false); + } + + public Element SelectedElement + { + get + { + if (this.ElementList.SelectedItems.Count != 0) + return this.ElementList.SelectedItems[0].Tag as Element; + return (Element)null; + } + } + + public Structure SelectedStructure + { + get + { + if (this.StructureList.SelectedItems.Count != 0) + return this.StructureList.SelectedItems[0].Tag as Structure; + return (Structure)null; + } + } + + public Timeline SelectedTimeline + { + get + { + if (this.TimelineList.SelectedItems.Count != 0) + return this.TimelineList.SelectedItems[0].Tag as Timeline; + return (Timeline)null; + } + } + + public Note SelectedNote + { + get + { + if (this.NoteList.SelectedItems.Count != 0) + return this.NoteList.SelectedItems[0].Tag as Note; + return (Note)null; + } + } + + private void FileNew_Click(object sender, EventArgs e) + { + try + { + if (!this.ask_for_save()) + return; + this.NewProject(); + } + catch (Exception ex) + { + LabyrinthData.Log((object)ex); + } + } + + private void FileOpen_Click(object sender, EventArgs e) + { + try + { + if (!this.ask_for_save()) + return; + OpenFileDialog openFileDialog = new OpenFileDialog(); + openFileDialog.Filter = "Plot Files|*.plt|All Files|*.*"; + if (openFileDialog.ShowDialog() != DialogResult.OK) + return; + this.OpenProject(openFileDialog.FileName); + } + catch (Exception ex) + { + LabyrinthData.Log((object)ex); + } + } + + private void FileSave_Click(object sender, EventArgs e) + { + try + { + if (LabyrinthData.FileName == "") + { + this.FileSaveAs_Click(sender, e); + } + else + { + this.SaveProject(LabyrinthData.FileName); + this.update_ui(); + } + } + catch (Exception ex) + { + LabyrinthData.Log((object)ex); + } + } + + private void FileSaveAs_Click(object sender, EventArgs e) + { + try + { + this.save_project_as(); + this.update_ui(); + } + catch (Exception ex) + { + LabyrinthData.Log((object)ex); + } + } + + private void FileImport_Click(object sender, EventArgs e) + { + try + { + OpenFileDialog openFileDialog = new OpenFileDialog(); + openFileDialog.Title = "Import"; + openFileDialog.Filter = "Plot Files|*.plt|All Files|*.*"; + if (openFileDialog.ShowDialog() != DialogResult.OK) + return; + XmlTextReader xmlTextReader = new XmlTextReader(openFileDialog.FileName); + Project project = new XmlSerializer(typeof(Project)).Deserialize((XmlReader)xmlTextReader) as Project; + xmlTextReader.Close(); + LabyrinthData.Project.Elements.AddRange(project.Elements); + LabyrinthData.Project.Structures.AddRange(project.Structures); + LabyrinthData.Project.Timelines.AddRange(project.Timelines); + this.update_ui(); + } + catch (Exception ex) + { + LabyrinthData.Log((object)ex); + } + } + + private void FilePageSetup_Click(object sender, EventArgs e) + { + try + { + int num = (int)new PageSetupDialog() + { + PageSettings = LabyrinthData.PageSettings, + PrinterSettings = LabyrinthData.PrinterSettings + }.ShowDialog(); + } + catch (Exception ex) + { + LabyrinthData.Log((object)ex); + } + } + + private void FileExit_Click(object sender, EventArgs e) + { + try + { + if (!this.ask_for_save()) + return; + this.Close(); + } + catch (Exception ex) + { + LabyrinthData.Log((object)ex); + } + } + + private void EditElementsNew_Click(object sender, EventArgs e) + { + try + { + string str = "New Element"; + string name = str; + int num = 1; + for (; LabyrinthData.Project.Elements.IndexOf(name) != -1; name = str + " " + (object)num) + ++num; + Element e1 = new Element(); + e1.Name = name; + if (new ElementDlg(e1).ShowDialog() != DialogResult.OK) + return; + LabyrinthData.Project.Elements.Add(e1); + this.update_ui(); + this.view_element(e1); + this.OnElementAdded(new ElementEventArgs(e1)); + } + catch (Exception ex) + { + LabyrinthData.Log((object)ex); + } + } + + private void EditElementsDelete_Click(object sender, EventArgs e) + { + try + { + if (this.SelectedElement == null) + return; + Element selectedElement = this.SelectedElement; + if (MessageBox.Show("Delete element '" + selectedElement.Name + "': are you sure?", "Labyrinth", MessageBoxButtons.YesNo, MessageBoxIcon.Question) != DialogResult.Yes) + return; + LabyrinthData.Project.RemoveElement(selectedElement); + this.update_ui(); + this.OnElementDeleted(new ElementEventArgs(selectedElement)); + } + catch (Exception ex) + { + LabyrinthData.Log((object)ex); + } + } + + private void EditElementsProperties_Click(object sender, EventArgs e) + { + try + { + if (this.SelectedElement == null) + return; + Element selectedElement = this.SelectedElement; + if (new ElementDlg(selectedElement).ShowDialog() != DialogResult.OK) + return; + this.update_ui(); + this.OnElementModified(new ElementEventArgs(selectedElement)); + } + catch (Exception ex) + { + LabyrinthData.Log((object)ex); + } + } + + private void EditElementsView_Click(object sender, EventArgs e) + { + try + { + if (this.SelectedElement == null) + return; + this.view_element(this.SelectedElement); + } + catch (Exception ex) + { + LabyrinthData.Log((object)ex); + } + } + + private void EditStructuresNew_Click(object sender, EventArgs e) + { + try + { + string str = "New Structure"; + string name = str; + int num = 1; + for (; LabyrinthData.Project.Structures.IndexOf(name) != -1; name = str + " " + (object)num) + ++num; + Structure s = new Structure(); + s.Name = name; + if (new StructureDlg(s).ShowDialog() != DialogResult.OK) + return; + LabyrinthData.Project.Structures.Add(s); + this.update_ui(); + this.view_structure(s); + this.OnStructureAdded(new StructureEventArgs(s)); + } + catch (Exception ex) + { + LabyrinthData.Log((object)ex); + } + } + + private void EditStructuresDelete_Click(object sender, EventArgs e) + { + try + { + if (this.SelectedStructure == null) + return; + Structure selectedStructure = this.SelectedStructure; + if (MessageBox.Show("Delete structure '" + selectedStructure.Name + "': are you sure?", "Labyrinth", MessageBoxButtons.YesNo, MessageBoxIcon.Question) != DialogResult.Yes) + return; + LabyrinthData.Project.Structures.Remove(selectedStructure); + this.update_ui(); + this.OnStructureDeleted(new StructureEventArgs(selectedStructure)); + } + catch (Exception ex) + { + LabyrinthData.Log((object)ex); + } + } + + private void EditStructuresProperties_Click(object sender, EventArgs e) + { + try + { + if (this.SelectedStructure == null) + return; + Structure selectedStructure = this.SelectedStructure; + if (new StructureDlg(selectedStructure).ShowDialog() != DialogResult.OK) + return; + this.update_ui(); + this.OnStructureModified(new StructureEventArgs(selectedStructure)); + } + catch (Exception ex) + { + LabyrinthData.Log((object)ex); + } + } + + private void EditStructuresView_Click(object sender, EventArgs e) + { + try + { + if (this.SelectedStructure == null) + return; + this.view_structure(this.SelectedStructure); + } + catch (Exception ex) + { + LabyrinthData.Log((object)ex); + } + } + + private void EditTimelinesNew_Click(object sender, EventArgs e) + { + try + { + string str = "New Timeline"; + string name = str; + int num = 1; + for (; LabyrinthData.Project.Timelines.IndexOf(name) != -1; name = str + " " + (object)num) + ++num; + Timeline tl = new Timeline(); + tl.Name = name; + if (new TimelineDlg(tl).ShowDialog() != DialogResult.OK) + return; + LabyrinthData.Project.Timelines.Add(tl); + this.update_ui(); + this.view_timeline(tl); + this.OnTimelineAdded(new TimelineEventArgs(tl)); + } + catch (Exception ex) + { + LabyrinthData.Log((object)ex); + } + } + + private void EditTimelinesDelete_Click(object sender, EventArgs e) + { + try + { + if (this.SelectedTimeline == null) + return; + Timeline selectedTimeline = this.SelectedTimeline; + if (MessageBox.Show("Delete timeline '" + selectedTimeline.Name + "': are you sure?", "Labyrinth", MessageBoxButtons.YesNo, MessageBoxIcon.Question) != DialogResult.Yes) + return; + LabyrinthData.Project.Timelines.Remove(selectedTimeline); + this.update_ui(); + this.OnTimelineDeleted(new TimelineEventArgs(selectedTimeline)); + } + catch (Exception ex) + { + LabyrinthData.Log((object)ex); + } + } + + private void EditTimelinesProperties_Click(object sender, EventArgs e) + { + try + { + if (this.SelectedTimeline == null) + return; + Timeline selectedTimeline = this.SelectedTimeline; + if (new TimelineDlg(selectedTimeline).ShowDialog() != DialogResult.OK) + return; + this.update_ui(); + this.OnTimelineModified(new TimelineEventArgs(selectedTimeline)); + } + catch (Exception ex) + { + LabyrinthData.Log((object)ex); + } + } + + private void EditTimelinesView_Click(object sender, EventArgs e) + { + try + { + if (this.SelectedTimeline == null) + return; + this.view_timeline(this.SelectedTimeline); + } + catch (Exception ex) + { + LabyrinthData.Log((object)ex); + } + } + + private void EditNotesNew_Click(object sender, EventArgs e) + { + try + { + string str = "New Note"; + string title = str; + int num = 1; + for (; LabyrinthData.Project.Notes.IndexOf(title) != -1; title = str + " " + (object)num) + ++num; + Note n = new Note(); + n.Title = title; + if (new NoteDlg(n).ShowDialog() != DialogResult.OK) + return; + LabyrinthData.Project.Notes.Add(n); + this.update_ui(); + this.view_note(n); + this.OnNoteAdded(new NoteEventArgs(n)); + } + catch (Exception ex) + { + LabyrinthData.Log((object)ex); + } + } + + private void EditNotesDelete_Click(object sender, EventArgs e) + { + try + { + if (this.SelectedNote == null) + return; + Note selectedNote = this.SelectedNote; + if (MessageBox.Show("Delete note '" + selectedNote.Title + "': are you sure?", "Labyrinth", MessageBoxButtons.YesNo, MessageBoxIcon.Question) != DialogResult.Yes) + return; + LabyrinthData.Project.Notes.Remove(selectedNote); + this.update_ui(); + this.OnNoteDeleted(new NoteEventArgs(selectedNote)); + } + catch (Exception ex) + { + LabyrinthData.Log((object)ex); + } + } + + private void EditNotesProperties_Click(object sender, EventArgs e) + { + try + { + if (this.SelectedNote == null) + return; + Note selectedNote = this.SelectedNote; + if (new NoteDlg(selectedNote).ShowDialog() != DialogResult.OK) + return; + this.update_ui(); + this.OnNoteModified(new NoteEventArgs(selectedNote)); + } + catch (Exception ex) + { + LabyrinthData.Log((object)ex); + } + } + + private void EditNotesView_Click(object sender, EventArgs e) + { + try + { + if (this.SelectedNote == null) + return; + this.view_note(this.SelectedNote); + } + catch (Exception ex) + { + LabyrinthData.Log((object)ex); + } + } + + private void EditProjectProperties_Click(object sender, EventArgs e) + { + try + { + if (new ProjectDlg(LabyrinthData.Project).ShowDialog() != DialogResult.OK) + return; + this.update_ui(); + } + catch (Exception ex) + { + LabyrinthData.Log((object)ex); + } + } + + private void ViewExplorer_Click(object sender, EventArgs e) + { + try + { + bool flag = !this.Explorer.Visible; + this.Explorer.Visible = flag; + this.ExplorerSplitter.Visible = flag; + } + catch (Exception ex) + { + LabyrinthData.Log((object)ex); + } + } + + private void ViewToolbar_Click(object sender, EventArgs e) + { + try + { + this.MainToolBar.Visible = !this.MainToolBar.Visible; + } + catch (Exception ex) + { + LabyrinthData.Log((object)ex); + } + } + + private void ViewStatusbar_Click(object sender, EventArgs e) + { + try + { + this.StatusBar.Visible = !this.StatusBar.Visible; + } + catch (Exception ex) + { + LabyrinthData.Log((object)ex); + } + } + + private void ViewPageTabs_Click(object sender, EventArgs e) + { + try + { + this.Pages.HideTabsMode = this.Pages.HideTabsMode == Crownwood.Magic.Controls.TabControl.HideTabsModes.HideAlways ? Crownwood.Magic.Controls.TabControl.HideTabsModes.ShowAlways : Crownwood.Magic.Controls.TabControl.HideTabsModes.HideAlways; + } + catch (Exception ex) + { + LabyrinthData.Log((object)ex); + } + } + + private void ToolsSearch_Click(object sender, EventArgs e) + { + try + { + if (this.ActivePage is SearchPage) + this.Pages_ClosePressed(sender, e); + else + this.view_search(); + } + catch (Exception ex) + { + LabyrinthData.Log((object)ex); + } + } + + private void ToolsTaskList_Click(object sender, EventArgs e) + { + try + { + if (this.ActivePage is TaskPage) + this.Pages_ClosePressed(sender, e); + else + this.view_tasks(); + } + catch (Exception ex) + { + LabyrinthData.Log((object)ex); + } + } + + private void ToolsAnnotations_Click(object sender, EventArgs e) + { + try + { + if (this.ActivePage is AnnotationPage) + this.Pages_ClosePressed(sender, e); + else + this.view_annotations(); + } + catch (Exception ex) + { + LabyrinthData.Log((object)ex); + } + } + + private void ToolsCalendar_Click(object sender, EventArgs e) + { + try + { + if (this.ActivePage is CalendarPage) + this.Pages_ClosePressed(sender, e); + else + this.view_calendar(); + } + catch (Exception ex) + { + LabyrinthData.Log((object)ex); + } + } + + private void ToolsAddIns_Popup(object sender, EventArgs e) + { + try + { + if (this.fAddInMgr.AddIns.Count == 0) + return; + this.ToolsAddIns.MenuItems.Clear(); + foreach (IAddIn addIn in this.fAddInMgr.AddIns) + { + MenuItem menuItem1 = this.ToolsAddIns.MenuItems.Add(addIn.Name); + foreach (IAddInComponent component in addIn.Components) + { + ICommand command = component as ICommand; + if (command != null) + { + MenuItem menuItem2 = menuItem1.MenuItems.Add(command.Name, new EventHandler(command.Execute)); + menuItem2.Enabled = command.Available; + menuItem2.Checked = command.Active; + } + } + if (menuItem1.MenuItems.Count == 0) + menuItem1.MenuItems.Add("(no commands)").Enabled = false; + } + this.ToolsAddIns.MenuItems.Add("-"); + this.ToolsAddIns.MenuItems.Add("Add-In Manager", new EventHandler(this.ToolsAddInManager_Click)); + } + catch (Exception ex) + { + LabyrinthData.Log((object)ex); + } + } + + private void ToolsAddInManager_Click(object sender, EventArgs e) + { + int num = (int)new AddInDlg(this.fAddInMgr).ShowDialog(); + } + + private void ToolsMergeElements_Click(object sender, EventArgs e) + { + if (new MergeElementsDlg().ShowDialog() != DialogResult.OK) + return; + this.update_ui(); + } + + private void WindowMenu_Popup(object sender, EventArgs e) + { + this.WindowPages.MenuItems.Clear(); + foreach (Crownwood.Magic.Controls.TabPage tabPage in (CollectionBase)this.Pages.TabPages) + this.WindowPages.MenuItems.Add(tabPage.Title, new EventHandler(this.PageActivate)).Checked = this.Pages.SelectedTab == tabPage; + if (this.WindowPages.MenuItems.Count != 0) + return; + this.WindowPages.MenuItems.Add("None").Enabled = false; + } + + private void WindowClose_Click(object sender, EventArgs e) + { + if (this.Pages.SelectedTab == null) + return; + this.Pages.TabPages.Remove(this.Pages.SelectedTab); + } + + private void WindowCloseAll_Click(object sender, EventArgs e) + { + this.Pages.TabPages.Clear(); + } + + private void WindowCloseAllExcept_Click(object sender, EventArgs e) + { + Crownwood.Magic.Controls.TabPage selectedTab = this.Pages.SelectedTab; + this.Pages.TabPages.Clear(); + if (selectedTab == null) + return; + this.Pages.TabPages.Add(selectedTab); + } + + private void PageActivate(object sender, EventArgs e) + { + this.Pages.SelectedIndex = this.WindowPages.MenuItems.IndexOf(sender as MenuItem); + } + + private void HelpContents_Click(object sender, EventArgs e) + { + try + { + string location = Assembly.GetEntryAssembly().Location; + int length = location.LastIndexOf("."); + string str = location.Substring(0, length) + ".chm"; + if (File.Exists(str)) + { + Help.ShowHelp((Control)this, str); + } + else + { + int num = (int)MessageBox.Show("The help file '" + str + "' was not found.", "Labyrinth", MessageBoxButtons.OK, MessageBoxIcon.Exclamation); + } + } + catch (Exception ex) + { + LabyrinthData.Log((object)ex); + } + } + + private void HelpAbout_Click(object sender, EventArgs e) + { + try + { + int num = (int)new AboutDlg().ShowDialog(); + } + catch (Exception ex) + { + LabyrinthData.Log((object)ex); + } + } + + private void MainToolBar_ButtonClick(object sender, ToolBarButtonClickEventArgs e) + { + try + { + if (e.Button == this.MainNewBtn) + this.FileNew_Click(sender, (EventArgs)e); + else if (e.Button == this.MainOpenBtn) + this.FileOpen_Click(sender, (EventArgs)e); + else if (e.Button == this.MainSaveBtn) + this.FileSave_Click(sender, (EventArgs)e); + else if (e.Button == this.MainPropertiesBtn) + this.EditProjectProperties_Click(sender, (EventArgs)e); + else if (e.Button == this.MainSearchBtn) + this.ToolsSearch_Click(sender, (EventArgs)e); + else if (e.Button == this.MainTasksBtn) + this.ToolsTaskList_Click(sender, (EventArgs)e); + else if (e.Button == this.MainAnnotationsBtn) + { + this.ToolsAnnotations_Click(sender, (EventArgs)e); + } + else + { + if (e.Button != this.MainCalendarBtn) + return; + this.ToolsCalendar_Click(sender, (EventArgs)e); + } + } + catch (Exception ex) + { + LabyrinthData.Log((object)ex); + } + } + + private void ElementToolbar_ButtonClick(object sender, ToolBarButtonClickEventArgs e) + { + try + { + if (e.Button == this.ElementNewBtn) + this.EditElementsNew_Click(sender, (EventArgs)e); + else if (e.Button == this.ElementDeleteBtn) + this.EditElementsDelete_Click(sender, (EventArgs)e); + else if (e.Button == this.ElementPropertiesBtn) + { + this.EditElementsProperties_Click(sender, (EventArgs)e); + } + else + { + if (e.Button != this.ElementViewBtn) + return; + this.EditElementsView_Click(sender, (EventArgs)e); + } + } + catch (Exception ex) + { + LabyrinthData.Log((object)ex); + } + } + + private void StructureToolbar_ButtonClick(object sender, ToolBarButtonClickEventArgs e) + { + try + { + if (e.Button == this.StructureNewBtn) + this.EditStructuresNew_Click(sender, (EventArgs)e); + else if (e.Button == this.StructureDeleteBtn) + this.EditStructuresDelete_Click(sender, (EventArgs)e); + else if (e.Button == this.StructurePropertiesBtn) + { + this.EditStructuresProperties_Click(sender, (EventArgs)e); + } + else + { + if (e.Button != this.StructureViewBtn) + return; + this.EditStructuresView_Click(sender, (EventArgs)e); + } + } + catch (Exception ex) + { + LabyrinthData.Log((object)ex); + } + } + + private void TimelineToolbar_ButtonClick(object sender, ToolBarButtonClickEventArgs e) + { + try + { + if (e.Button == this.TimelineNewBtn) + this.EditTimelinesNew_Click(sender, (EventArgs)e); + else if (e.Button == this.TimelineDeleteBtn) + this.EditTimelinesDelete_Click(sender, (EventArgs)e); + else if (e.Button == this.TimelinePropertiesBtn) + { + this.EditTimelinesProperties_Click(sender, (EventArgs)e); + } + else + { + if (e.Button != this.TimelineViewBtn) + return; + this.EditTimelinesView_Click(sender, (EventArgs)e); + } + } + catch (Exception ex) + { + LabyrinthData.Log((object)ex); + } + } + + private void NoteToolbar_ButtonClick(object sender, ToolBarButtonClickEventArgs e) + { + try + { + if (e.Button == this.NoteNewBtn) + this.EditNotesNew_Click(sender, (EventArgs)e); + else if (e.Button == this.NoteDeleteBtn) + this.EditNotesDelete_Click(sender, (EventArgs)e); + else if (e.Button == this.NotePropertiesBtn) + { + this.EditNotesProperties_Click(sender, (EventArgs)e); + } + else + { + if (e.Button != this.NoteViewBtn) + return; + this.EditNotesView_Click(sender, (EventArgs)e); + } + } + catch (Exception ex) + { + LabyrinthData.Log((object)ex); + } + } + + private void new_project() + { + this.OnProjectClosing(new EventArgs()); + LabyrinthData.Project = new Project(); + LabyrinthData.Project.Name = "Untitled Project"; + LabyrinthData.FileName = ""; + LabyrinthData.MostRecent = this.get_project_string(); + this.OnProjectCreated(new EventArgs()); + } + + private bool open_project(string filename) + { + this.Cursor = Cursors.WaitCursor; + bool flag; + try + { + StreamReader streamReader = new StreamReader(filename, Encoding.UTF8); + string end = streamReader.ReadToEnd(); + streamReader.Close(); + FileConversion.Convert(ref end); + XmlTextReader xmlTextReader = new XmlTextReader((TextReader)new StringReader(end)); + Project project = new XmlSerializer(typeof(Project)).Deserialize((XmlReader)xmlTextReader) as Project; + xmlTextReader.Close(); + this.OnProjectClosing(new EventArgs()); + LabyrinthData.Project = project; + LabyrinthData.FileName = filename; + LabyrinthData.MostRecent = this.get_project_string(); + flag = true; + this.OnProjectOpened(new EventArgs()); + } + catch (Exception ex) + { + LabyrinthData.Log((object)ex); + int num = (int)MessageBox.Show("There was an error opening this project." + "\nIt may have been created with a newer version of Labyrinth.", "Labyrinth", MessageBoxButtons.OK, MessageBoxIcon.Hand); + flag = false; + } + this.Cursor = Cursors.Default; + return flag; + } + + private bool save_project(string filename) + { + this.Cursor = Cursors.WaitCursor; + bool flag; + try + { + XmlTextWriter xmlTextWriter = new XmlTextWriter(filename, Encoding.UTF8); + xmlTextWriter.Formatting = Formatting.Indented; + new XmlSerializer(typeof(Project)).Serialize((XmlWriter)xmlTextWriter, (object)LabyrinthData.Project); + xmlTextWriter.Close(); + LabyrinthData.FileName = filename; + LabyrinthData.MostRecent = this.get_project_string(); + flag = true; + this.OnProjectSaved(new EventArgs()); + } + catch (Exception ex) + { + LabyrinthData.Log((object)ex); + int num = (int)MessageBox.Show("There was an error saving this project.", "Labyrinth", MessageBoxButtons.OK, MessageBoxIcon.Hand); + flag = false; + } + this.Cursor = Cursors.Default; + return flag; + } + + private bool save_project_as() + { + SaveFileDialog saveFileDialog = new SaveFileDialog(); + saveFileDialog.FileName = LabyrinthData.FileName != "" ? LabyrinthData.FileName : LabyrinthData.Project.Name; + saveFileDialog.Filter = "Plot Files|*.plt|All Files|*.*"; + if (saveFileDialog.ShowDialog() == DialogResult.OK) + return this.save_project(saveFileDialog.FileName); + return false; + } + + private bool ask_for_save() + { + if (LabyrinthData.MostRecent != this.get_project_string()) + { + switch (MessageBox.Show("This project has been modified. Would you like to save it?", "Labyrinth", MessageBoxButtons.YesNoCancel, MessageBoxIcon.Question)) + { + case DialogResult.Cancel: + return false; + + case DialogResult.Yes: + if (LabyrinthData.FileName != "") + return this.save_project(LabyrinthData.FileName); + return this.save_project_as(); + + case DialogResult.No: + return true; + } + } + return true; + } + + private string get_project_string() + { + try + { + StringWriter stringWriter = new StringWriter(); + new XmlSerializer(typeof(Project)).Serialize((TextWriter)stringWriter, (object)LabyrinthData.Project); + stringWriter.Close(); + return stringWriter.ToString(); + } + catch (Exception ex) + { + LabyrinthData.Log((object)ex); + } + return ""; + } + + private void OnIdle(object sender, EventArgs e) + { + this.FileNew.Enabled = true; + this.FileOpen.Enabled = true; + this.FileSave.Enabled = true; + this.FileSaveAs.Enabled = true; + this.FileExit.Enabled = true; + this.EditElementsNew.Enabled = true; + this.EditElementsDelete.Enabled = this.SelectedElement != null; + this.EditElementsProperties.Enabled = this.SelectedElement != null; + this.EditElementsView.Enabled = this.SelectedElement != null; + this.EditStructuresNew.Enabled = true; + this.EditStructuresDelete.Enabled = this.SelectedStructure != null; + this.EditStructuresProperties.Enabled = this.SelectedStructure != null; + this.EditStructuresView.Enabled = this.SelectedStructure != null; + this.EditTimelinesNew.Enabled = true; + this.EditTimelinesDelete.Enabled = this.SelectedTimeline != null; + this.EditTimelinesProperties.Enabled = this.SelectedTimeline != null; + this.EditTimelinesView.Enabled = this.SelectedTimeline != null; + this.EditNotesNew.Enabled = true; + this.EditNotesDelete.Enabled = this.SelectedNote != null; + this.EditNotesProperties.Enabled = this.SelectedNote != null; + this.EditNotesView.Enabled = this.SelectedNote != null; + this.EditProjectProperties.Enabled = true; + this.ViewExplorer.Enabled = true; + this.ViewExplorer.Checked = this.Explorer.Visible; + this.ViewToolbar.Enabled = true; + this.ViewToolbar.Checked = this.MainToolBar.Visible; + this.ViewStatusbar.Enabled = true; + this.ViewStatusbar.Checked = this.StatusBar.Visible; + this.ViewPageTabs.Enabled = true; + this.ViewPageTabs.Checked = this.Pages.HideTabsMode == Crownwood.Magic.Controls.TabControl.HideTabsModes.ShowAlways; + this.ToolsSearch.Enabled = true; + this.ToolsSearch.Checked = this.ActivePage is SearchPage; + this.ToolsTaskList.Enabled = true; + this.ToolsTaskList.Checked = this.ActivePage is TaskPage; + this.ToolsAnnotations.Enabled = true; + this.ToolsAnnotations.Checked = this.ActivePage is AnnotationPage; + this.ToolsCalendar.Enabled = true; + this.ToolsCalendar.Checked = this.ActivePage is CalendarPage; + this.HelpAbout.Enabled = true; + this.ElementNew.Enabled = this.EditElementsNew.Enabled; + this.ElementDelete.Enabled = this.EditElementsDelete.Enabled; + this.ElementProperties.Enabled = this.EditElementsProperties.Enabled; + this.ElementView.Enabled = this.EditElementsView.Enabled; + this.StructureNew.Enabled = this.EditStructuresNew.Enabled; + this.StructureDelete.Enabled = this.EditStructuresDelete.Enabled; + this.StructureProperties.Enabled = this.EditStructuresProperties.Enabled; + this.StructureView.Enabled = this.EditStructuresView.Enabled; + this.TimelineNew.Enabled = this.EditTimelinesNew.Enabled; + this.TimelineDelete.Enabled = this.EditTimelinesDelete.Enabled; + this.TimelineProperties.Enabled = this.EditTimelinesProperties.Enabled; + this.TimelineView.Enabled = this.EditTimelinesView.Enabled; + this.NoteNew.Enabled = this.EditNotesNew.Enabled; + this.NoteDelete.Enabled = this.EditNotesDelete.Enabled; + this.NoteProperties.Enabled = this.EditNotesProperties.Enabled; + this.NoteView.Enabled = this.EditNotesView.Enabled; + this.MainNewBtn.Enabled = this.FileNew.Enabled; + this.MainOpenBtn.Enabled = this.FileOpen.Enabled; + this.MainSaveBtn.Enabled = this.FileSave.Enabled; + this.MainPropertiesBtn.Enabled = this.EditProjectProperties.Enabled; + this.MainSearchBtn.Enabled = this.ToolsSearch.Enabled; + this.MainSearchBtn.Pushed = this.ToolsSearch.Checked; + this.MainTasksBtn.Enabled = this.ToolsTaskList.Enabled; + this.MainTasksBtn.Pushed = this.ToolsTaskList.Checked; + this.MainAnnotationsBtn.Enabled = this.ToolsAnnotations.Enabled; + this.MainAnnotationsBtn.Pushed = this.ToolsAnnotations.Checked; + this.MainCalendarBtn.Enabled = this.ToolsCalendar.Enabled; + this.MainCalendarBtn.Pushed = this.ToolsCalendar.Checked; + this.ElementNewBtn.Enabled = this.EditElementsNew.Enabled; + this.ElementDeleteBtn.Enabled = this.EditElementsDelete.Enabled; + this.ElementPropertiesBtn.Enabled = this.EditElementsProperties.Enabled; + this.ElementViewBtn.Enabled = this.EditElementsView.Enabled; + this.StructureNewBtn.Enabled = this.EditStructuresNew.Enabled; + this.StructureDeleteBtn.Enabled = this.EditStructuresDelete.Enabled; + this.StructurePropertiesBtn.Enabled = this.EditStructuresProperties.Enabled; + this.StructureViewBtn.Enabled = this.EditStructuresView.Enabled; + this.TimelineNewBtn.Enabled = this.EditTimelinesNew.Enabled; + this.TimelineDeleteBtn.Enabled = this.EditTimelinesDelete.Enabled; + this.TimelinePropertiesBtn.Enabled = this.EditTimelinesProperties.Enabled; + this.TimelineViewBtn.Enabled = this.EditTimelinesView.Enabled; + this.NoteNewBtn.Enabled = this.EditNotesNew.Enabled; + this.NoteDeleteBtn.Enabled = this.EditNotesDelete.Enabled; + this.NotePropertiesBtn.Enabled = this.EditNotesProperties.Enabled; + this.NoteViewBtn.Enabled = this.EditNotesView.Enabled; + foreach (Crownwood.Magic.Controls.TabPage tabPage in (CollectionBase)this.Pages.TabPages) + (tabPage.Control as IPage)?.UpdateUI(); + } + + private void ElementList_MouseDown(object sender, MouseEventArgs e) + { + this.ElementList.SelectedItems.Clear(); + ListViewItem itemAt = this.ElementList.GetItemAt(e.X, e.Y); + if (itemAt != null) + itemAt.Selected = true; + this.OnIdle(sender, (EventArgs)e); + } + + private void StructureList_MouseDown(object sender, MouseEventArgs e) + { + this.StructureList.SelectedItems.Clear(); + ListViewItem itemAt = this.StructureList.GetItemAt(e.X, e.Y); + if (itemAt != null) + itemAt.Selected = true; + this.OnIdle(sender, (EventArgs)e); + } + + private void TimelineList_MouseDown(object sender, MouseEventArgs e) + { + this.TimelineList.SelectedItems.Clear(); + ListViewItem itemAt = this.TimelineList.GetItemAt(e.X, e.Y); + if (itemAt != null) + itemAt.Selected = true; + this.OnIdle(sender, (EventArgs)e); + } + + private void NoteList_MouseDown(object sender, MouseEventArgs e) + { + this.NoteList.SelectedItems.Clear(); + ListViewItem itemAt = this.NoteList.GetItemAt(e.X, e.Y); + if (itemAt != null) + itemAt.Selected = true; + this.OnIdle(sender, (EventArgs)e); + } + + private void Pages_ClosePressed(object sender, EventArgs e) + { + this.WindowClose_Click(sender, e); + } + + private void ElementList_ItemDrag(object sender, ItemDragEventArgs e) + { + if (this.SelectedElement == null) + return; + int num = (int)this.DoDragDrop((object)this.SelectedElement, DragDropEffects.All); + } + + private void StructureList_ItemDrag(object sender, ItemDragEventArgs e) + { + if (this.SelectedStructure == null) + return; + int num = (int)this.DoDragDrop((object)this.SelectedStructure, DragDropEffects.All); + } + + private void TimelineList_ItemDrag(object sender, ItemDragEventArgs e) + { + if (this.SelectedTimeline == null) + return; + int num = (int)this.DoDragDrop((object)this.SelectedTimeline, DragDropEffects.All); + } + + private void NoteList_ItemDrag(object sender, ItemDragEventArgs e) + { + if (this.SelectedNote == null) + return; + int num = (int)this.DoDragDrop((object)this.SelectedNote, DragDropEffects.All); + } + + private void ElementList_DoubleClick(object sender, EventArgs e) + { + if (this.SelectedElement != null) + this.EditElementsView_Click(sender, e); + else + this.EditElementsNew_Click(sender, e); + } + + private void StructureList_DoubleClick(object sender, EventArgs e) + { + if (this.SelectedStructure != null) + this.EditStructuresView_Click(sender, e); + else + this.EditStructuresNew_Click(sender, e); + } + + private void TimelineList_DoubleClick(object sender, EventArgs e) + { + if (this.SelectedTimeline != null) + this.EditTimelinesView_Click(sender, e); + else + this.EditTimelinesNew_Click(sender, e); + } + + private void NoteList_DoubleClick(object sender, EventArgs e) + { + if (this.SelectedNote != null) + this.EditNotesView_Click(sender, e); + else + this.EditNotesNew_Click(sender, e); + } + + private void update_ui() + { + this.update_statusbar(); + this.update_explorer(); + this.update_pages(); + this.update_addins(); + } + + private void update_statusbar() + { + this.NameStatusPanel.Text = "Project: " + LabyrinthData.Project.Name; + if (LabyrinthData.FileName != "") + { + FileInfo fileInfo = new FileInfo(LabyrinthData.FileName); + if ((fileInfo.Attributes & FileAttributes.ReadOnly) == FileAttributes.ReadOnly) + this.NameStatusPanel.Text += " (read-only)"; + if (fileInfo.Length < 1024L) + { + StatusBarPanel nameStatusPanel = this.NameStatusPanel; + nameStatusPanel.Text = nameStatusPanel.Text + "; " + (object)fileInfo.Length + " bytes"; + } + else if (fileInfo.Length < 1048576L) + { + float num = (float)fileInfo.Length / 1024f; + StatusBarPanel nameStatusPanel = this.NameStatusPanel; + nameStatusPanel.Text = nameStatusPanel.Text + "; " + num.ToString("F1") + " kb"; + } + else if (fileInfo.Length < 1073741824L) + { + float num = (float)fileInfo.Length / 1048576f; + StatusBarPanel nameStatusPanel = this.NameStatusPanel; + nameStatusPanel.Text = nameStatusPanel.Text + "; " + num.ToString("F1") + " Mb"; + } + else + { + float num = (float)fileInfo.Length / 1.073742E+09f; + StatusBarPanel nameStatusPanel = this.NameStatusPanel; + nameStatusPanel.Text = nameStatusPanel.Text + "; " + num.ToString("F1") + " Gb"; + } + } + this.ElementStatusPanel.Text = "Elements: " + (object)LabyrinthData.Project.Elements.Count; + this.StructureStatusPanel.Text = "Structures: " + (object)LabyrinthData.Project.Structures.Count; + this.TimelineStatusPanel.Text = "Timelines: " + (object)LabyrinthData.Project.Timelines.Count; + this.NoteStatusPanel.Text = "Notes: " + (object)LabyrinthData.Project.Notes.Count; + } + + private void update_explorer() + { + this.update_elements(); + this.update_structures(); + this.update_timelines(); + this.update_notes(); + } + + private void update_elements() + { + this.ElementList.BeginUpdate(); + this.ElementList.Items.Clear(); + if (LabyrinthData.Project.Elements.Count != 0) + { + ArrayList arrayList = new ArrayList(); + foreach (Element element in LabyrinthData.Project.Elements) + arrayList.Add((object)new ListViewItem(element.Name) + { + ImageIndex = LabyrinthData.GetImageIndex(element.Type), + Tag = (object)element + }); + this.ElementList.Items.AddRange((ListViewItem[])arrayList.ToArray(typeof(ListViewItem))); + } + else + { + ListViewItem listViewItem = this.ElementList.Items.Add("No elements"); + listViewItem.ImageIndex = -1; + listViewItem.ForeColor = SystemColors.GrayText; + } + this.ElementList.EndUpdate(); + } + + private void update_structures() + { + this.StructureList.BeginUpdate(); + this.StructureList.Items.Clear(); + if (LabyrinthData.Project.Structures.Count != 0) + { + ArrayList arrayList = new ArrayList(); + foreach (Structure structure in LabyrinthData.Project.Structures) + arrayList.Add((object)new ListViewItem(structure.Name) + { + ImageIndex = LabyrinthData.GetImageIndex((object)structure), + Tag = (object)structure + }); + this.StructureList.Items.AddRange((ListViewItem[])arrayList.ToArray(typeof(ListViewItem))); + } + else + { + ListViewItem listViewItem = this.StructureList.Items.Add("No structures"); + listViewItem.ImageIndex = -1; + listViewItem.ForeColor = SystemColors.GrayText; + } + this.StructureList.EndUpdate(); + } + + private void update_timelines() + { + this.TimelineList.BeginUpdate(); + this.TimelineList.Items.Clear(); + if (LabyrinthData.Project.Timelines.Count != 0) + { + ArrayList arrayList = new ArrayList(); + foreach (Timeline timeline in LabyrinthData.Project.Timelines) + arrayList.Add((object)new ListViewItem(timeline.Name) + { + ImageIndex = LabyrinthData.GetImageIndex((object)timeline), + Tag = (object)timeline + }); + this.TimelineList.Items.AddRange((ListViewItem[])arrayList.ToArray(typeof(ListViewItem))); + } + else + { + ListViewItem listViewItem = this.TimelineList.Items.Add("No timelines"); + listViewItem.ImageIndex = -1; + listViewItem.ForeColor = SystemColors.GrayText; + } + this.TimelineList.EndUpdate(); + } + + private void update_notes() + { + this.NoteList.BeginUpdate(); + this.NoteList.Items.Clear(); + if (LabyrinthData.Project.Notes.Count != 0) + { + ArrayList arrayList = new ArrayList(); + foreach (Note note in LabyrinthData.Project.Notes) + arrayList.Add((object)new ListViewItem(note.Title) + { + ImageIndex = LabyrinthData.GetImageIndex((object)note), + Tag = (object)note + }); + this.NoteList.Items.AddRange((ListViewItem[])arrayList.ToArray(typeof(ListViewItem))); + } + else + { + ListViewItem listViewItem = this.NoteList.Items.Add("No notes"); + listViewItem.ImageIndex = -1; + listViewItem.ForeColor = SystemColors.GrayText; + } + this.NoteList.EndUpdate(); + } + + private void update_pages() + { + ArrayList arrayList = new ArrayList(); + foreach (Crownwood.Magic.Controls.TabPage tabPage in (CollectionBase)this.Pages.TabPages) + { + IPage control = tabPage.Control as IPage; + if (control != null && control.IsObsolete) + arrayList.Add((object)tabPage); + } + foreach (Crownwood.Magic.Controls.TabPage tabPage in arrayList) + this.Pages.TabPages.Remove(tabPage); + foreach (Crownwood.Magic.Controls.TabPage tabPage in (CollectionBase)this.Pages.TabPages) + { + IPage control = tabPage.Control as IPage; + if (control != null) + { + tabPage.Title = control.Title; + tabPage.ImageIndex = LabyrinthData.GetImageIndex((object)control); + control.UpdateData(); + } + } + } + + private void update_addins() + { + foreach (IAddIn addIn in this.fAddInMgr.AddIns) + { + foreach (IAddInComponent component in addIn.Components) + component.UpdateData(); + } + } + + private void view_element(Element e) + { + foreach (Crownwood.Magic.Controls.TabPage tabPage in (CollectionBase)this.Pages.TabPages) + { + Labyrinth.Pages.ElementPage control = tabPage.Control as Labyrinth.Pages.ElementPage; + if (control != null && control.Element == e) + { + tabPage.Selected = true; + return; + } + } + Labyrinth.Pages.ElementPage elementPage = new Labyrinth.Pages.ElementPage(e); + elementPage.ElementActivated += new ElementEventHandler(this.Page_ElementActivated); + elementPage.ElementModified += new ElementEventHandler(this.Page_ElementModified); + elementPage.TimelineModified += new TimelineEventHandler(this.Page_TimelineModified); + elementPage.TimelineActivated += new TimelineEventHandler(this.Page_TimelineActivated); + elementPage.StructureActivated += new StructureEventHandler(this.Page_StructureActivated); + elementPage.StructureModified += new StructureEventHandler(this.Page_StructureModified); + int imageIndex = LabyrinthData.GetImageIndex((object)elementPage); + Crownwood.Magic.Controls.TabPage tabPage1 = new Crownwood.Magic.Controls.TabPage(elementPage.Title, (Control)elementPage, imageIndex); + this.Pages.TabPages.Add(tabPage1); + tabPage1.Selected = true; + } + + private void view_structure(Structure s) + { + foreach (Crownwood.Magic.Controls.TabPage tabPage in (CollectionBase)this.Pages.TabPages) + { + Labyrinth.Pages.StructurePage control = tabPage.Control as Labyrinth.Pages.StructurePage; + if (control != null && control.Structure == s) + { + tabPage.Selected = true; + return; + } + } + Labyrinth.Pages.StructurePage structurePage = new Labyrinth.Pages.StructurePage(s); + structurePage.StructureModified += new StructureEventHandler(this.Page_StructureModified); + structurePage.ElementActivated += new ElementEventHandler(this.Page_ElementActivated); + structurePage.ElementModified += new ElementEventHandler(this.Page_ElementModified); + int imageIndex = LabyrinthData.GetImageIndex((object)structurePage); + Crownwood.Magic.Controls.TabPage tabPage1 = new Crownwood.Magic.Controls.TabPage(structurePage.Title, (Control)structurePage, imageIndex); + this.Pages.TabPages.Add(tabPage1); + tabPage1.Selected = true; + } + + private void view_timeline(Timeline tl) + { + foreach (Crownwood.Magic.Controls.TabPage tabPage in (CollectionBase)this.Pages.TabPages) + { + Labyrinth.Pages.TimelinePage control = tabPage.Control as Labyrinth.Pages.TimelinePage; + if (control != null && control.Timeline == tl) + { + tabPage.Selected = true; + return; + } + } + Labyrinth.Pages.TimelinePage timelinePage = new Labyrinth.Pages.TimelinePage(tl); + timelinePage.TimelineModified += new TimelineEventHandler(this.Page_TimelineModified); + timelinePage.ElementActivated += new ElementEventHandler(this.Page_ElementActivated); + timelinePage.ElementModified += new ElementEventHandler(this.Page_ElementModified); + int imageIndex = LabyrinthData.GetImageIndex((object)timelinePage); + Crownwood.Magic.Controls.TabPage tabPage1 = new Crownwood.Magic.Controls.TabPage(timelinePage.Title, (Control)timelinePage, imageIndex); + this.Pages.TabPages.Add(tabPage1); + tabPage1.Selected = true; + } + + private void view_note(Note n) + { + foreach (Crownwood.Magic.Controls.TabPage tabPage in (CollectionBase)this.Pages.TabPages) + { + Labyrinth.Pages.NotePage control = tabPage.Control as Labyrinth.Pages.NotePage; + if (control != null && control.Note == n) + { + tabPage.Selected = true; + return; + } + } + Labyrinth.Pages.NotePage notePage = new Labyrinth.Pages.NotePage(n); + notePage.NoteModified += new NoteEventHandler(this.Page_NoteModified); + int imageIndex = LabyrinthData.GetImageIndex((object)notePage); + Crownwood.Magic.Controls.TabPage tabPage1 = new Crownwood.Magic.Controls.TabPage(notePage.Title, (Control)notePage, imageIndex); + this.Pages.TabPages.Add(tabPage1); + tabPage1.Selected = true; + } + + private void view_search() + { + foreach (Crownwood.Magic.Controls.TabPage tabPage in (CollectionBase)this.Pages.TabPages) + { + if (tabPage.Control is SearchPage) + { + tabPage.Selected = true; + return; + } + } + SearchPage searchPage = new SearchPage(); + searchPage.AddCustomSearches((ICustomSearch[])this.fCustomSearches.ToArray(typeof(ICustomSearch))); + searchPage.ElementActivated += new ElementEventHandler(this.Page_ElementActivated); + searchPage.ElementModified += new ElementEventHandler(this.Page_ElementModified); + searchPage.TimelineModified += new TimelineEventHandler(this.Page_TimelineModified); + searchPage.TimelineActivated += new TimelineEventHandler(this.Page_TimelineActivated); + searchPage.StructureActivated += new StructureEventHandler(this.Page_StructureActivated); + searchPage.StructureModified += new StructureEventHandler(this.Page_StructureModified); + int imageIndex = LabyrinthData.GetImageIndex((object)searchPage); + Crownwood.Magic.Controls.TabPage tabPage1 = new Crownwood.Magic.Controls.TabPage(searchPage.Title, (Control)searchPage, imageIndex); + this.Pages.TabPages.Add(tabPage1); + tabPage1.Selected = true; + } + + private void view_tasks() + { + foreach (Crownwood.Magic.Controls.TabPage tabPage in (CollectionBase)this.Pages.TabPages) + { + if (tabPage.Control is TaskPage) + { + tabPage.Selected = true; + return; + } + } + TaskPage taskPage = new TaskPage(); + int imageIndex = LabyrinthData.GetImageIndex((object)taskPage); + Crownwood.Magic.Controls.TabPage tabPage1 = new Crownwood.Magic.Controls.TabPage(taskPage.Title, (Control)taskPage, imageIndex); + this.Pages.TabPages.Add(tabPage1); + tabPage1.Selected = true; + } + + private void view_annotations() + { + foreach (Crownwood.Magic.Controls.TabPage tabPage in (CollectionBase)this.Pages.TabPages) + { + if (tabPage.Control is AnnotationPage) + { + tabPage.Selected = true; + return; + } + } + AnnotationPage annotationPage = new AnnotationPage(); + annotationPage.ElementActivated += new ElementEventHandler(this.Page_ElementActivated); + annotationPage.ElementModified += new ElementEventHandler(this.Page_ElementModified); + annotationPage.TimelineModified += new TimelineEventHandler(this.Page_TimelineModified); + annotationPage.TimelineActivated += new TimelineEventHandler(this.Page_TimelineActivated); + int imageIndex = LabyrinthData.GetImageIndex((object)annotationPage); + Crownwood.Magic.Controls.TabPage tabPage1 = new Crownwood.Magic.Controls.TabPage(annotationPage.Title, (Control)annotationPage, imageIndex); + this.Pages.TabPages.Add(tabPage1); + tabPage1.Selected = true; + } + + private void view_calendar() + { + foreach (Crownwood.Magic.Controls.TabPage tabPage in (CollectionBase)this.Pages.TabPages) + { + if (tabPage.Control is CalendarPage) + { + tabPage.Selected = true; + return; + } + } + CalendarPage calendarPage = new CalendarPage(); + calendarPage.ElementActivated += new ElementEventHandler(this.Page_ElementActivated); + calendarPage.ElementModified += new ElementEventHandler(this.Page_ElementModified); + calendarPage.TimelineActivated += new TimelineEventHandler(this.Page_TimelineActivated); + calendarPage.TimelineModified += new TimelineEventHandler(this.Page_TimelineModified); + int imageIndex = LabyrinthData.GetImageIndex((object)calendarPage); + Crownwood.Magic.Controls.TabPage tabPage1 = new Crownwood.Magic.Controls.TabPage(calendarPage.Title, (Control)calendarPage, imageIndex); + this.Pages.TabPages.Add(tabPage1); + tabPage1.Selected = true; + } + + private void Page_ElementModified(object sender, ElementEventArgs e) + { + this.update_ui(); + this.OnElementModified(e); + } + + private void Page_StructureModified(object sender, StructureEventArgs e) + { + this.update_ui(); + this.OnStructureModified(e); + } + + private void Page_TimelineModified(object sender, TimelineEventArgs e) + { + this.update_ui(); + this.OnTimelineModified(e); + } + + private void Page_NoteModified(object sender, NoteEventArgs e) + { + this.update_ui(); + this.OnNoteModified(e); + } + + private void Page_ElementActivated(object sender, ElementEventArgs e) + { + this.view_element(e.Element); + } + + private void Page_StructureActivated(object sender, StructureEventArgs e) + { + this.view_structure(e.Structure); + } + + private void Page_TimelineActivated(object sender, TimelineEventArgs e) + { + this.view_timeline(e.Timeline); + } + + private void ElementList_ColumnClick(object sender, ColumnClickEventArgs e) + { + ListViewSorter.Sort(this.ElementList, e.Column); + } + + private void StructureList_ColumnClick(object sender, ColumnClickEventArgs e) + { + ListViewSorter.Sort(this.StructureList, e.Column); + } + + private void TimelineList_ColumnClick(object sender, ColumnClickEventArgs e) + { + ListViewSorter.Sort(this.TimelineList, e.Column); + } + + private void NoteList_ColumnClick(object sender, ColumnClickEventArgs e) + { + ListViewSorter.Sort(this.NoteList, e.Column); + } + + private void StatusBar_PanelClick(object sender, StatusBarPanelClickEventArgs e) + { + if (e.Button != MouseButtons.Left || e.Clicks != 2) + return; + int num = this.StatusBar.Panels.IndexOf(e.StatusBarPanel); + if (num == 0) + { + this.EditProjectProperties_Click(sender, (EventArgs)e); + } + else + { + if (num <= 0) + return; + this.Explorer.TabPages[num - 1].Selected = true; + } + } + } +} \ No newline at end of file diff --git a/Labyrinth3/IDE/MainForm.resx b/Labyrinth3/IDE/MainForm.resx new file mode 100644 index 0000000..5d88a93 --- /dev/null +++ b/Labyrinth3/IDE/MainForm.resx @@ -0,0 +1,390 @@ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + text/microsoft-resx + + + 2.0 + + + System.Resources.ResXResourceReader, System.Windows.Forms, Version=4.0.0.0, Culture=neutral, PublicKeyToken=b77a5c561934e089 + + + System.Resources.ResXResourceWriter, System.Windows.Forms, Version=4.0.0.0, Culture=neutral, PublicKeyToken=b77a5c561934e089 + + + + + AAABAAMAICAQAAAAAADoAgAANgAAABAQEAAAAAAAKAEAAB4DAAAwMBAAAAAAAGgGAABGBAAAKAAAACAA + AABAAAAAAQAEAAAAAAAAAgAAAAAAAAAAAAAQAAAAEAAAAAAAAAAAAIAAAIAAAACAgACAAAAAgACAAICA + AACAgIAAwMDAAAAA/wAA/wAAAP//AP8AAAD/AP8A//8AAP///wAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA + AAAAAAAAAAAAAABERERERERERERERERERAAAREREREREREREREREREQAAEREREREREREREREREREAABE + T//////////////0RAAARE//////////////9EQAAERP//////////////REAABET///RI////9Ej//0 + RAAARE///0SP///0RI//9EQAAERP//9ESP//REj///REAABET///9Ej//0SP///0RAAARE////REj/RE + j///9EQAAERP////REj0SP////REAABET/////REREj////0RAAARE//////RESP////9EQAAERP//// + //REj/////REAABET//////0SP/////0RAAARE//////9Ej/////9EQAAERP/////0RI//////REAABE + T/////9Ej//////0RAAARE/////0RI//////9EQAAERP//9EREj///////REAABET///9ESP///////0 + RAAARE//////////////9EQAAERP//////////////REAABET//////////////0RAAARERERERERERE + REREREQAAEREREREREREREREREREAABERERERERERERERERERAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA + AAAAAAAAAAAAAP//////////wAAAA8AAAAPAAAADwAAAA8AAAAPAAAADwAAAA8AAAAPAAAADwAAAA8AA + AAPAAAADwAAAA8AAAAPAAAADwAAAA8AAAAPAAAADwAAAA8AAAAPAAAADwAAAA8AAAAPAAAADwAAAA8AA + AAPAAAADwAAAA///////////KAAAABAAAAAgAAAAAQAEAAAAAACAAAAAAAAAAAAAAAAQAAAAEAAAAAAA + AAAAAIAAAIAAAACAgACAAAAAgACAAICAAACAgIAAwMDAAAAA/wAA/wAAAP//AP8AAAD/AP8A//8AAP// + /wD///////////RERERERERP9ERERERERE/0T//////0T/RP9I//SPRP9E/0SPRI9E/0T/9EhI/0T/RP + //REj/RP9E///0j/9E/0T//0SP/0T/RP9ESP//RP9E//SP//9E/0T//////0T/RERERERERP9ERERERE + RE///////////wAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA + AAAAAAAAAAAAAAAAAAAoAAAAMAAAAGAAAAABAAQAAAAAAIAEAAAAAAAAAAAAABAAAAAQAAAAAAAAAAAA + gAAAgAAAAICAAIAAAACAAIAAgIAAAMDAwACAgIAAAAD/AAD/AAAA//8A/wAAAP8A/wD//wAA////AAAA + AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA + AAAAAAAAAAAAAAAERERERERERERERERERERERERERERAAAAERERERERERERERERERERERERERERAAAAE + RERERERERERERERERERERERERERAAAAERERERERERERERERERERERERERERAAAAERERERERERERERERE + RERERERERERAAAAERE//////////////////////RERAAAAERE//////////////////////RERAAAAE + RE//////////////////////RERAAAAERE//////////////////////RERAAAAERE/////0RH////// + /0RH////RERAAAAERE/////0RH//////9ERH////RERAAAAERE/////0RH//////RER/////RERAAAAE + RE//////REf////0REf/////RERAAAAERE//////REf////0RH//////RERAAAAERE//////9ER///9E + RH//////RERAAAAERE//////9ERH//9ER///////RERAAAAERE///////0RH//9ER///////RERAAAAE + RE///////0REf/REf///////RERAAAAERE////////RER/REf///////RERAAAAERE////////9ERERH + ////////RERAAAAERE/////////0RERH////////RERAAAAERE//////////9ERH////////RERAAAAE + RE//////////9ER/////////RERAAAAERE//////////RER/////////RERAAAAERE//////////REf/ + ////////RERAAAAERE//////////REf/////////RERAAAAERE/////////0REf/////////RERAAAAE + RE/////////0RH//////////RERAAAAERE////////9ERH//////////RERAAAAERE////////RER/// + ////////RERAAAAERE/////0REREf///////////RERAAAAERE/////0RERH////////////RERAAAAE + RE//////REf/////////////RERAAAAERE//////////////////////RERAAAAERE////////////// + ////////RERAAAAERE//////////////////////RERAAAAERE//////////////////////RERAAAAE + RE//////////////////////RERAAAAERERERERERERERERERERERERERERAAAAERERERERERERERERE + RERERERERERAAAAERERERERERERERERERERERERERERAAAAERERERERERERERERERERERERERERAAAAA + AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA + AAAAAAAAAAAAAP///////wAA////////AAD///////8AAOAAAAAABwAA4AAAAAAHAADgAAAAAAcAAOAA + AAAABwAA4AAAAAAHAADgAAAAAAcAAOAAAAAABwAA4AAAAAAHAADgAAAAAAcAAOAAAAAABwAA4AAAAAAH + AADgAAAAAAcAAOAAAAAABwAA4AAAAAAHAADgAAAAAAcAAOAAAAAABwAA4AAAAAAHAADgAAAAAAcAAOAA + AAAABwAA4AAAAAAHAADgAAAAAAcAAOAAAAAABwAA4AAAAAAHAADgAAAAAAcAAOAAAAAABwAA4AAAAAAH + AADgAAAAAAcAAOAAAAAABwAA4AAAAAAHAADgAAAAAAcAAOAAAAAABwAA4AAAAAAHAADgAAAAAAcAAOAA + AAAABwAA4AAAAAAHAADgAAAAAAcAAOAAAAAABwAA4AAAAAAHAADgAAAAAAcAAOAAAAAABwAA4AAAAAAH + AADgAAAAAAcAAP///////wAA////////AAD///////8AAA== + + + + MainForm + + + 17, 17 + + + + True + + + + AAEAAAD/////AQAAAAAAAAAMAgAAAFdTeXN0ZW0uV2luZG93cy5Gb3JtcywgVmVyc2lvbj00LjAuMC4w + LCBDdWx0dXJlPW5ldXRyYWwsIFB1YmxpY0tleVRva2VuPWI3N2E1YzU2MTkzNGUwODkFAQAAACZTeXN0 + ZW0uV2luZG93cy5Gb3Jtcy5JbWFnZUxpc3RTdHJlYW1lcgEAAAAERGF0YQcCAgAAAAkDAAAADwMAAABI + FQAAAk1TRnQBSQFMAgEBGwEAAR0BAAEIAQABEAEAARABAAT/AQkBEAj/AUIBTQE2AQQGAAE2AQQCAAEo + AwABQAMAAXADAAEBAQABCAYAARwYAAGAAgABgAMAAoABAAGAAwABgAEAAYABAAKAAgADwAEAAcAB3AHA + AQAB8AHKAaYBAAEzBQABMwEAATMBAAEzAQACMwIAAxYBAAMcAQADIgEAAykBAANVAQADTQEAA0IBAAM5 + AQABgAF8Af8BAAJQAf8BAAGTAQAB1gEAAf8B7AHMAQABxgHWAe8BAAHWAucBAAGQAakBrQIAAf8BMwMA + AWYDAAGZAwABzAIAATMDAAIzAgABMwFmAgABMwGZAgABMwHMAgABMwH/AgABZgMAAWYBMwIAAmYCAAFm + AZkCAAFmAcwCAAFmAf8CAAGZAwABmQEzAgABmQFmAgACmQIAAZkBzAIAAZkB/wIAAcwDAAHMATMCAAHM + AWYCAAHMAZkCAALMAgABzAH/AgAB/wFmAgAB/wGZAgAB/wHMAQABMwH/AgAB/wEAATMBAAEzAQABZgEA + ATMBAAGZAQABMwEAAcwBAAEzAQAB/wEAAf8BMwIAAzMBAAIzAWYBAAIzAZkBAAIzAcwBAAIzAf8BAAEz + AWYCAAEzAWYBMwEAATMCZgEAATMBZgGZAQABMwFmAcwBAAEzAWYB/wEAATMBmQIAATMBmQEzAQABMwGZ + AWYBAAEzApkBAAEzAZkBzAEAATMBmQH/AQABMwHMAgABMwHMATMBAAEzAcwBZgEAATMBzAGZAQABMwLM + AQABMwHMAf8BAAEzAf8BMwEAATMB/wFmAQABMwH/AZkBAAEzAf8BzAEAATMC/wEAAWYDAAFmAQABMwEA + AWYBAAFmAQABZgEAAZkBAAFmAQABzAEAAWYBAAH/AQABZgEzAgABZgIzAQABZgEzAWYBAAFmATMBmQEA + AWYBMwHMAQABZgEzAf8BAAJmAgACZgEzAQADZgEAAmYBmQEAAmYBzAEAAWYBmQIAAWYBmQEzAQABZgGZ + AWYBAAFmApkBAAFmAZkBzAEAAWYBmQH/AQABZgHMAgABZgHMATMBAAFmAcwBmQEAAWYCzAEAAWYBzAH/ + AQABZgH/AgABZgH/ATMBAAFmAf8BmQEAAWYB/wHMAQABzAEAAf8BAAH/AQABzAEAApkCAAGZATMBmQEA + AZkBAAGZAQABmQEAAcwBAAGZAwABmQIzAQABmQEAAWYBAAGZATMBzAEAAZkBAAH/AQABmQFmAgABmQFm + ATMBAAGZATMBZgEAAZkBZgGZAQABmQFmAcwBAAGZATMB/wEAApkBMwEAApkBZgEAA5kBAAKZAcwBAAKZ + Af8BAAGZAcwCAAGZAcwBMwEAAWYBzAFmAQABmQHMAZkBAAGZAswBAAGZAcwB/wEAAZkB/wIAAZkB/wEz + AQABmQHMAWYBAAGZAf8BmQEAAZkB/wHMAQABmQL/AQABzAMAAZkBAAEzAQABzAEAAWYBAAHMAQABmQEA + AcwBAAHMAQABmQEzAgABzAIzAQABzAEzAWYBAAHMATMBmQEAAcwBMwHMAQABzAEzAf8BAAHMAWYCAAHM + AWYBMwEAAZkCZgEAAcwBZgGZAQABzAFmAcwBAAGZAWYB/wEAAcwBmQIAAcwBmQEzAQABzAGZAWYBAAHM + ApkBAAHMAZkBzAEAAcwBmQH/AQACzAIAAswBMwEAAswBZgEAAswBmQEAA8wBAALMAf8BAAHMAf8CAAHM + Af8BMwEAAZkB/wFmAQABzAH/AZkBAAHMAf8BzAEAAcwC/wEAAcwBAAEzAQAB/wEAAWYBAAH/AQABmQEA + AcwBMwIAAf8CMwEAAf8BMwFmAQAB/wEzAZkBAAH/ATMBzAEAAf8BMwH/AQAB/wFmAgAB/wFmATMBAAHM + AmYBAAH/AWYBmQEAAf8BZgHMAQABzAFmAf8BAAH/AZkCAAH/AZkBMwEAAf8BmQFmAQAB/wKZAQAB/wGZ + AcwBAAH/AZkB/wEAAf8BzAIAAf8BzAEzAQAB/wHMAWYBAAH/AcwBmQEAAf8CzAEAAf8BzAH/AQAC/wEz + AQABzAH/AWYBAAL/AZkBAAL/AcwBAAJmAf8BAAFmAf8BZgEAAWYC/wEAAf8CZgEAAf8BZgH/AQAC/wFm + AQABIQEAAaUBAANfAQADdwEAA4YBAAOWAQADywEAA7IBAAPXAQAD3QEAA+MBAAPqAQAD8QEAA/gBAAHw + AfsB/wEAAaQCoAEAA4ADAAH/AgAB/wMAAv8BAAH/AwAB/wEAAf8BAAL/AgAD/xQABwcoAA3sBAACBwbs + AgcFAAgFGAAB7AL/AewC/wHsAv8B7AL/AewDAAHsAQcE/wMHAuwFAAEFBv8ZAAHsAv8B7AL/AewC/wHs + Av8B7AMAAewBBwH/AewBBwX/AewBBwQAAQUB/wIAA/8BAAH/FwAG7AT5A+wDAAHsAQcI/wHsAQcEAAEF + BP8DAAH/FwAB7AL/AewC/wH5AuwB+QL/AewDAAHsAQcB/wTsAQcC/wHsAQcEAAEFAf8CAAH/AQAF/xUA + AewC/wHsAv8B+QLsAfkC/wHsAwAB7AEHCP8B7AEHBAABBQT/AwAB/xcABuwE+QPsAwAB7AEHAf8E7AEH + Av8B7AEHBAABBQH/AgAD/wEAAf8XAAHsAv8B7AL/AewC/wHsAv8B7AMAAewBBwj/AewBBwQAAQUG/xkA + AewC/wHsAv8B7AL/AewC/wHsAwAB7AEHAf8D7AEHA/8B7AEHBAABBQH/BAAB/wEFGAAN7AMAAewBBwj/ + AewBBwQAAQUG/wEFGAAB7AL/AewC/wHsAv8B7AL/AewDAAHsAQcI/wHsAQcEAAEFAf8EAAH/AQUYAAHs + Av8B7AL/AewC/wHsAv8B7AMAAewBBwHsAf8B7AH/AewB/wHsAf8B7AEHBAABBQb/AQUYAA3sAwABBwLs + AQMBBwHsAQcB7AEHAewBBwUACAUpAAHsAfsCAwH7AewB+wLsAQc9AAEHeAAK7AYACuwGAArsFQABBwr/ + AewEAAEHCv8B7AQAAQcK/wHsAwAB/wkAAf8GAAEHA/8CBwX/AewEAAEHA/8EAwP/AewEAAEHBP8CAQT/ + AewDAAH/CQAB/wYAAQcD/wEBAgcE/wHsBAABBwL/AQMB+wH/AfsB/wEDAv8B7AQAAQcE/wIBBP8B7BQA + AQcC/wMBAgcD/wHsBAABBwH/AQMB+wH/AfsB/wH7Af8BAwH/AewEAAEHCv8B7AQAAf8GAAH/CAABBwH/ + AgEB/wIBAQcD/wHsBAABBwH/AQMB/wH7BQMB/wHsBAABBwT/AgEE/wHsBAAB/wMAAQcCAAH/CAABBwX/ + AQECBwL/AewEAAEHAf8BAwH7Af8B+wEDAfsB/wEDAf8B7AQAAQcE/wIBBP8B7AQAAf8DAAEHAgAB/wgA + AQcG/wEBAgcB/wHsBAABBwH/AQMB/wH7Af8B+wEDAfsBAwH/AewEAAEHBP8CAQT/AewUAAEHB/8BAQEH + Af8B7AQAAQcC/wEDAf8B+wH/AfsBAwL/AewEAAEHBP8CAQT/AewFAAH/BQAB/wgAAQcI/wEBAf8B7AQA + AQcD/wQDA/8B7AQAAQcE/wIBBP8B7BQAAQcK/wHsBAABBwr/AewEAAEHCv8B7BQAAQcC/wbsAv8B7AQA + AQcC/wbsAv8B7AQAAQcC/wbsAv8B7AYAAf8FAAH/CAACBwHsAf8DBwHsAgcGAAIHAewB/wMHAewCBwYA + AgcB7AH/AwcB7AIHGQAEBwwABAcMAAQHygAE/yEAA+wYAAH/AgIB/x4AA+wYAAHsAfsBAAH/AfsB+QH/ + AQAB/wHsAQAB/wH7HQAB7BUAAewB/wEAAf8B/AH5Af8BAAH7AuwBAAH/FgAB7AUAAewWAAHsAfsBAAH/ + AfwB+wH/AQAB/wHsAfsB7BcAAewEAAHsFwAB7AH/AQAB/wL8Af8BAAH7BOwWAAHsHAAB7AH7AQAE/wEA + Af8B+wH/AfsB/xUAAewFAAPsFQAB7AH/BgAB+wH/AfsB/wH7FQAB7AIAAewaAAHsAfsB/wH7Af8B+wH/ + AfsB/wH7Af8B+wH/FQAB7AEAAewbAA3sFgAB7P8AswACBWsABQIYAAHsAfsB/wH7Af8B+wH/AfsB/wHs + AQAB/wH7AwAB7AH7Af8CAAH7AgAB/wHsAQAB/wH7BgAFAgEAAfoWAAHsAf8B+wH/AfsB/wH7Af8B+wLs + AQAB/wMAAewB/wH7AgAB/wIAAfsC7AEAAf8GAAUCAQAC+gsAAgUIAAHsAfsB/wH7Af8B+wH/AfsB/wHs + AfsB7AQAAewB+wH/AgAB+wIAAf8B7AH7AewHAAUCAQAC+gsAAgUIAAHsAf8B+wH/AfsB/wH7Af8B+wTs + AwAB7AH/AfsCAAH/AgAB+wTsDAAC+gsAAgUIAAHsAfsB/wH7Af8B+wH/AfsB/wH7Af8B+wH/AwAB7AH7 + Af8B+wEAAfsB/wEAAf8B+wH/AfsB/wcABfoBAAH6CwACBQgAAewB/wH7Af8B+wH/AfsB/wH7Af8B+wH/ + AfsDAAHsAf8B+wH/AQAB/wH7AQAB+wH/AfsB/wH7CAAF+gwAAgUIAAHsAfsB/wH7Af8B+wH/AfsB/wH7 + Af8B+wH/AwAB7AH7Af8B+wH/AgAB+wH/AfsB/wH7Af8ZAAIFCAAN7AMADewZAAIF/wCeAAEFAQAB7A0A + AgMDAAIDKAACBQEAAf8BBwH/CwABAwUAAQMZAATsCgADBQEAAewB/wEHAf8BBwUAAgMCAAEDBQABAxgA + AewEAAHsCAAEBQEHAgAB7AEHAf8BBwQABgMDAAIDGgACBwkABAUBBwMFAgAB7AH/AewDAAIDAgAHAwcA + AwEPAAEHAuwBBwcABAUBBwYFAgAB7AcABwMZAAEHAuwBBwcAAwUBBwkFCAAHAxoAAgcIAAIFAQcKBQsA + AQMPAAMBCQAB7AQAAewGAAEFAQcKBQwAAQMcAATsBwABBwoFDAADAygACAUNAAMDKgAFBT0AAgX/AB4A + BfwZAAf/GQAC/BEAAv8LAAH/A+wD/xkAAfwCAAb8CQAE/woAB/8YAAH8AgAC/AEAAvwCAAH8CAAE/woA + Af8F7AH/GAAB/AIAAvwBAAL8AgAB/AkAAv8LAAf/GAAB/AIAAvwBAAL8AgAB/BYAAf8F7AH/GAAB/AIA + AvwBAAL8AgAB/BYAB/8ZAAH8AgAE/AEAAfwXAAH/A+wD/xkAAvwFAAL8FwAF/x0ABfwZAAX//wBPAAIF + WwAI7DgACOwHAAXsAQAF7CYACOwHAAXsAQAF7AkAAgUcAAbsCQAE7AEABOwKAAIFHgAC7B4AAgUeAALs + HgACBR0ABOwLAALsAwAC7AsAAgUdAATsCwAC7AMAAuwLAAIFHQAE7AsAAuwDAALsCwACBfcAAUIBTQE+ + BwABPgMAASgDAAFAAwABcAMAAQEBAAEBBQABgAEDFgAD/wEAAv8B4AE/Av8CAAHAAQEB4AEHAcABPwIA + AcABAQHAAQcBwAEPAgABwAEBAcABAwHAAQ8CAAHAAQEBwAEDAcABAwIAAcABAQHAAQMBwAEDAgABwAEB + AcABAwHAAQMCAAHAAQEBwAEDAcABDwIAAcABAQHAAQMBwAEPAgABwAEBAcABAwHAAT8CAAHAAQEBwAED + AcABPwIAAcABAQHAAQMBwAE/AgABwAEBAcABAwHAAT8CAAHAAQEBwAEHAcABPwIAAv8B4AEHAv8CAAP/ + Ad8C/wIACv8B4AEHAeABBwHgAgcBwQHAAQMBwAEDAcABAwEHAcEBwAEDAcABAwHAAQMBBwHBAcABAwHA + AQMBwAEDAgEBwAEDAcABAwHAAQMBAAEBAcABAwHAAQMBwAEDAQABAQHAAQMBwAEDAcABAwEAAQEBwAED + AcABAwHAAQMBgAEDAcABAwHAAQMBwAEDAcEBBwHAAQMBwAEDAcABAwHBAQcBwAEDAcABAwHAAQMB4wGP + AcABAwHAAQMBwAEDAeMBjwHgAQcB4AEHAeABBwHjAY8B/AE/AfwBPwH8AT8Q/wHgAX8B/wHPBP8B4AF/ + Af8BxwH/AYMC/wGAAQEB/AEDAfABcwL/AYABAQHzAccB8wHvAv8BgAEBAe8BzwH3At8B/QGAAQEB7wH/ + AfcBvwHfAf0BgAEBAfMB/wH2AX8B2wFtAYABAQH8AX8B7gEPAdsBbQGAAQEB/wGfAe0B8wHAAQEBgAEB + Af8B7wHrAfMC/wGAAQEB/wHvAccG/wGfAc8F/wHwAX8a/wH4A/8B/gF/Av8B9wF/Av8B/AE/Av8B9wF/ + AeABPwH+AX8BgAEBAYABAQHgAR8C/wGAAQEBgAEBAeABDwH+AX8BgAEBAYABAQHgAQcB/AE/AYABAQGA + AQEB4AEHAfwBPwGAAQEBgAEBAeABBwH8AT8BgAEBAYABAQHwAQcB/AE/AYABAQGAAQEB+AEHAfwBPwGA + AQEBgAEBAfwBBwH8AT8BgAEBAYABAQL/AfwBPwb/Af4BfyL/AfwBfwH4AUMB/gF/Av8B+AEfAfgBQwH+ + AX8B/AE/AfABBwHIAeMB/gF/AfABDwHgAQEBgAHjAf4BfwHwAQ8BwAEAAYABAwHwAX8B4AEHAYABAQGA + AQMB4AF/AeABBwEAAQEByAEDAfABfwHgAQcCAAH4AQMB/gEPAeABBwEAAQEB+AEDAf4BBwHwAQ8BAAED + Af8BHwH+AQ8B8AEPAQABBwH+AQ8B/gF/AfwBPwGAAQ8B/gEPBP8B4AEfAf8BHwT/AfgBPwb/Af4BfxH/ + AfcC/wHwAQ8B4AEPAf8B9wH8AR8B4AEHAeABDwH/AfcB8wH/AeABBwHgAQ8B1gHTAfYBBwHgAQcB4AEP + AdUBtQHsAZsB8AEPAeABDwHVAbUB7AGbAfABDwHgAQ8BzAGTAewBmwH8AT8B4AEPAd0BvwHsAZsB5AEn + AeABDwHdAb8B9gEXAccB4wHgAQ8B3QG/AfMB5wHAAQMB4AEPAv8B/AEfAeABBwHgAR8G/wHgAT8Y/wH+ + AX8G/wH8AT8G/wH+AX8B/AE/AeABBwT/AfMBzwHgAQcBwAEBAf4BfwH3Ae8B4AEHAcABAQH8AT8B7wH3 + AfABDwHgAQMB/AE/Ae8B9wH4AR8B8AGHAfwBPwHvAfcB/AE/AfkBzwH8AT8B7wH3AfgBHwHwAYcB/AE/ + AfcB7wH4AR8B8AGHAfwBPwHzAc8B+AEfAfABhwH8AT8B/AE/AfwBPwH5Ac8B/gF/Fv8WAAs= + + + + True + + + + AAEAAAD/////AQAAAAAAAAAMAgAAAFdTeXN0ZW0uV2luZG93cy5Gb3JtcywgVmVyc2lvbj00LjAuMC4w + LCBDdWx0dXJlPW5ldXRyYWwsIFB1YmxpY0tleVRva2VuPWI3N2E1YzU2MTkzNGUwODkFAQAAACZTeXN0 + ZW0uV2luZG93cy5Gb3Jtcy5JbWFnZUxpc3RTdHJlYW1lcgEAAAAERGF0YQcCAgAAAAkDAAAADwMAAACU + EgAAAk1TRnQBSQFMAgEBEgEAARMBAAEIAQABEAEAARABAAT/AQkBEAj/AUIBTQE2AQQGAAE2AQQCAAEo + AwABQAMAAVADAAEBAQABCAYAARQYAAGAAgABgAMAAoABAAGAAwABgAEAAYABAAKAAgADwAEAAcAB3AHA + AQAB8AHKAaYBAAEzBQABMwEAATMBAAEzAQACMwIAAxYBAAMcAQADIgEAAykBAANVAQADTQEAA0IBAAM5 + AQABgAF8Af8BAAJQAf8BAAGTAQAB1gEAAf8B7AHMAQABxgHWAe8BAAHWAucBAAGQAakBrQIAAf8BMwMA + AWYDAAGZAwABzAIAATMDAAIzAgABMwFmAgABMwGZAgABMwHMAgABMwH/AgABZgMAAWYBMwIAAmYCAAFm + AZkCAAFmAcwCAAFmAf8CAAGZAwABmQEzAgABmQFmAgACmQIAAZkBzAIAAZkB/wIAAcwDAAHMATMCAAHM + AWYCAAHMAZkCAALMAgABzAH/AgAB/wFmAgAB/wGZAgAB/wHMAQABMwH/AgAB/wEAATMBAAEzAQABZgEA + ATMBAAGZAQABMwEAAcwBAAEzAQAB/wEAAf8BMwIAAzMBAAIzAWYBAAIzAZkBAAIzAcwBAAIzAf8BAAEz + AWYCAAEzAWYBMwEAATMCZgEAATMBZgGZAQABMwFmAcwBAAEzAWYB/wEAATMBmQIAATMBmQEzAQABMwGZ + AWYBAAEzApkBAAEzAZkBzAEAATMBmQH/AQABMwHMAgABMwHMATMBAAEzAcwBZgEAATMBzAGZAQABMwLM + AQABMwHMAf8BAAEzAf8BMwEAATMB/wFmAQABMwH/AZkBAAEzAf8BzAEAATMC/wEAAWYDAAFmAQABMwEA + AWYBAAFmAQABZgEAAZkBAAFmAQABzAEAAWYBAAH/AQABZgEzAgABZgIzAQABZgEzAWYBAAFmATMBmQEA + AWYBMwHMAQABZgEzAf8BAAJmAgACZgEzAQADZgEAAmYBmQEAAmYBzAEAAWYBmQIAAWYBmQEzAQABZgGZ + AWYBAAFmApkBAAFmAZkBzAEAAWYBmQH/AQABZgHMAgABZgHMATMBAAFmAcwBmQEAAWYCzAEAAWYBzAH/ + AQABZgH/AgABZgH/ATMBAAFmAf8BmQEAAWYB/wHMAQABzAEAAf8BAAH/AQABzAEAApkCAAGZATMBmQEA + AZkBAAGZAQABmQEAAcwBAAGZAwABmQIzAQABmQEAAWYBAAGZATMBzAEAAZkBAAH/AQABmQFmAgABmQFm + ATMBAAGZATMBZgEAAZkBZgGZAQABmQFmAcwBAAGZATMB/wEAApkBMwEAApkBZgEAA5kBAAKZAcwBAAKZ + Af8BAAGZAcwCAAGZAcwBMwEAAWYBzAFmAQABmQHMAZkBAAGZAswBAAGZAcwB/wEAAZkB/wIAAZkB/wEz + AQABmQHMAWYBAAGZAf8BmQEAAZkB/wHMAQABmQL/AQABzAMAAZkBAAEzAQABzAEAAWYBAAHMAQABmQEA + AcwBAAHMAQABmQEzAgABzAIzAQABzAEzAWYBAAHMATMBmQEAAcwBMwHMAQABzAEzAf8BAAHMAWYCAAHM + AWYBMwEAAZkCZgEAAcwBZgGZAQABzAFmAcwBAAGZAWYB/wEAAcwBmQIAAcwBmQEzAQABzAGZAWYBAAHM + ApkBAAHMAZkBzAEAAcwBmQH/AQACzAIAAswBMwEAAswBZgEAAswBmQEAA8wBAALMAf8BAAHMAf8CAAHM + Af8BMwEAAZkB/wFmAQABzAH/AZkBAAHMAf8BzAEAAcwC/wEAAcwBAAEzAQAB/wEAAWYBAAH/AQABmQEA + AcwBMwIAAf8CMwEAAf8BMwFmAQAB/wEzAZkBAAH/ATMBzAEAAf8BMwH/AQAB/wFmAgAB/wFmATMBAAHM + AmYBAAH/AWYBmQEAAf8BZgHMAQABzAFmAf8BAAH/AZkCAAH/AZkBMwEAAf8BmQFmAQAB/wKZAQAB/wGZ + AcwBAAH/AZkB/wEAAf8BzAIAAf8BzAEzAQAB/wHMAWYBAAH/AcwBmQEAAf8CzAEAAf8BzAH/AQAC/wEz + AQABzAH/AWYBAAL/AZkBAAL/AcwBAAJmAf8BAAFmAf8BZgEAAWYC/wEAAf8CZgEAAf8BZgH/AQAC/wFm + AQABIQEAAaUBAANfAQADdwEAA4YBAAOWAQADywEAA7IBAAPXAQAD3QEAA+MBAAPqAQAD8QEAA/gBAAHw + AfsB/wEAAaQCoAEAA4ADAAH/AgAB/wMAAv8BAAH/AwAB/wEAAf8BAAL/AgAD/1MADewzAAHsAv8B7AL/ + AewC/wHsAv8B7DMAAewC/wHsAv8B7AL/AewC/wHsIgAB7AH7Af8B+wH/AfsB/wH7Af8B7AEAAf8B+wQA + BuwE+QPsIgAB7AH/AfsB/wH7Af8B+wH/AfsC7AEAAf8EAAHsAv8B7AL/AfkC7AH5Av8B7CIAAewB+wH/ + AfsB/wH7Af8B+wH/AewB+wHsBQAB7AL/AewC/wH5AuwB+QL/AewiAAHsAf8B+wH/AfsB/wH7Af8B+wTs + BAAG7AT5A+wiAAHsAfsB/wH7Af8B+wH/AfsB/wH7Af8B+wH/BAAB7AL/AewC/wHsAv8B7AL/AewiAAHs + Af8B+wH/AfsB/wH7Af8B+wH/AfsB/wH7BAAB7AL/AewC/wHsAv8B7AL/AewiAAHsAfsB/wH7Af8B+wH/ + AfsB/wH7Af8B+wH/BAAN7CIADewEAAHsAv8B7AL/AewC/wHsAv8B7DMAAewC/wHsAv8B7AL/AewC/wHs + MwAN7K0AAfwPAAH8BgAHBwIAAfwfAAL8DgAC/AUAAgcG7AEHAvwFAArsCgAI/AgACPwDAAHsAQcD/wj8 + AwABBwr/AewIAAHsCfwHAAn8AgAB7AEHAf8B7AEHCfwCAAEHA/8CBwX/AewJAAj8CAAI/AMAAewBBwP/ + CPwDAAEHA/8BAQIHBP8B7AYAAewFAAHsAQAC/A4AAvwEAAHsAQcB/wTsAQcC/wL8BAABBwL/AwECBwP/ + AewGAAHsBAAB7AIAAfwPAAH8BQAB7AEHCP8B/AEHBAABBwH/AgEB/wIBAQcD/wHsBgAB7B0AAewBBwH/ + BOwBBwL/AewBBwQAAQcF/wEBAgcC/wHsBQAB7AUAA+wWAAHsAQcI/wHsAQcEAAEHBv8BAQIHAf8B7AUA + AewCAAHsGwAB7AEHAf8D7AEHA/8B7AEHBAABBwf/AQEBBwH/AewFAAHsAQAB7BwAAewBBwj/AewBBwQA + AQcI/wEBAf8B7AYAAewdAAHsAQcI/wHsAQcEAAEHCv8B7CQAAewBBwHsAf8B7AH/AewB/wHsAf8B7AEH + BAABBwL/BuwC/wHsJAABBwLsAQMBBwHsAQcB7AEHAewBBwYAAgcB7AH/AwcB7AIHJgAB7AH7AgMB+wHs + AfsC7AEHCQAEBzAAAQc4AAcHEgAB/CYAAgcG7AIHDwAC/AsAA+wWAAHsAQcE/wMHAuwKAAj8BwAD7BkA + AewBBwH/AewBBwX/AewBBwkACfwLAAHsFgAB7AEHCP8B7AEHCQAI/AUAAewFAAHsFwAB7AEHAf8E7AEH + Av8B7AEHDgAC/AYAAewEAAHsGAAB7AEHCP8B7AEHDgAB/AcAAewdAAHsAQcB/wTsAQcC/wHsAQcTAAH7 + AQAC7AH7AQAB+wEAA+wFAAH7AgAB7AH7AQAB+wkAAfsB7AEHAewB+wH/AfsE/wHsAQcTAAHsAfsC7AH7 + AuwJAAHsAfsC7AH7AQAB7AkAAewB+wLsAfsC7AEHA/8B7AEHFAAD7AH7AuwKAAHsAQAB7AH7AuwKAAHs + AQcB7AH7AuwE/wHsAQcTAAXsAQAB+wkAA+wBAAHsAQAB+wkAA+wB/wHsAf8B+wT/AewBBxQAAfsB7AH7 + AQAC7AoAAfsB7AH7AQAC7AoAAfsB7AH7Af8D7AH/AewB/wHsAQcUAAHsAfsB7AH7AewB+woAAewB+wHs + AfsB7AH7CgAB7AH7AewB+wHsAfsBBwHsAQcB7AEHFAAB7AH7AQAB7AIAAewJAAHsAfsBAAHsAgAB7AkA + AewB+wLsAgMC7AH7AuwBBxQAAfsCAAHsAfsLAAH7AgAB7AH7CwAB+wIAAewB+wQAAQemAAr/NgAB/wIA + Af8FAAH/BgAB/wkAAf8lAAr/BgAB/wkAAf8lAAH/AgAB/wUAAf82AAr/BwAB/wYAAf8nAAf/AQAC/wcA + Af8DAAEHAgAB/ycAAf8CAAP/AQABBwEAAf8HAAH/AwABBwIAAf8HAAH7AgAB7AH7AQAB+xkAAf8BAAEH + AQAB/wEAAQcBAAEHBAACBBEAAewB+wEAAewB+wEAAewZAAL/AQABBwEAAQcBAAEHAQADBwEAAgQDAAH/ + BQAB/wgAAewBAAHsAfsC7B0AAQcBAAEHAQAFBwIEEQAF7AEAAfseAAEHAQAGBwIEEgAB+wHsAfsiAAYH + AQACBAQAAf8FAAH/BwAB7AH7AewB+wHsAfsmAAIEEQAB7AH7AQAB7AIAAew5AAH7AgAB7AH7rAACAwYA + AgcBAAEDFgAJ/wUACQMHAAIDBgACBwEAAQMWAAn/BAAB+wEACQMGAAIDBgACBwEAAQMJAAL/CwAJ/wQA + Af8B+wEACQMFAAIDCQABAwkAAv8LAAn/BAAB+wH/AfsBAAkDBAAMAwkAAv8LAAn/BAAB/wH7Af8B+w0A + AgMIAAIDBgAI/wgACf8EAAH7Af8B+wH/AfsB/wH7Af8B+wgAAQMBAAgHAQABAwYACP8IAAn/BAAB/wH7 + Af8B+wH/AfsB/wH7Af8IAAEDAQAIBwEAAQMJAAL/CwAJ/wQAAfsB/wH7DgABAwEACAcBAAEDCQAC/wsA + Bv8YAAEDAQAIBwEAAQMJAAL/CwAG/wEAAf8WAAEDAQAIBxgABv8YAAEDAQAIBwEAAQeSAAFCAU0BPgcA + AT4DAAEoAwABQAMAAVADAAEBAQABAQUAAYABAhYAA/8BAAT/BAAC/wHAAQEEAAL/AcABAQQAAYABAQHA + AQEEAAGAAQEBwAEBBAABgAEBAcABAQQAAYABAQHAAQEEAAGAAQEBwAEBBAABgAEBAcABAQQAAYABAQHA + AQEEAAGAAQEBwAEBBAABgAEBAcABAQQAAv8BwAEBBAAC/wHAAQEEAAT/BAAE/wQAAf8B9wH/AfcB4AE3 + A/8B8wH/AfMB4AEDAeABBwH+AQEB/gEBAcABAQHAAQMB8AEAAf4BAAHAAQABwAEDAfIBAQH+AQEBwAEB + AcABAwH3AdMB/wHzAcABAwHAAQMB9wG3Af8B9wHAAQMBwAEDAfYBfwHfAf0BwAEDAcABAwHuAQ8B3wH9 + AcABAwHAAQMB7QHzAdsBbQHAAQMBwAEDAesB8wHbAW0BwAEDAcABAwHHAf8BwAEBAcABAwHAAQMBzwP/ + AcABAwHAAQME/wHAAQcB4AEHBP8B4AEHAfwBPwX/Ad8G/wHgAT8B/wH3BP8B4AEHAf8B8wH/AYMC/wHA + AQcB/gEBAfABcwL/AcABAwH8AQAB8wHvAv8BwAEDAfIBAQH3At8B/QHAAQMB9wHjAfcBvwHfAf0BwAED + Ae8B9wH2AX8B2wFtAcABAwHvAfcBogEPAZIBbQGAAQMB7wH3AYAB8wGAAQEBgAEDAe8B9wHAAfMB0AH/ + AcABAwH3Ae8BggH/AYoB/wGAAQMB8wHPAcQB/wHEAf8BwAEDAfwBPwHAAf8BwAH/AcABBwL/AZYB/wGW + Af8BgAEHAv8BswH/AbMB/wGzAd8M/wEAAQ8E/wHvAf0BAAEPAQcBwQL/AccB/wEAAQ8BBwHBAfwBPwHD + AfsBAAEPAQcBwQHzAc8B4wH3AQABDwIBAfcB7wHxAecBAAEPAQABAQHvAfcB+AHPAQABDwEAAQEB7wH3 + AfwBHwEAAQ8BAAEBAaIB9wH+AT8BAAEEAYABAwGCAfcB/AEfAgABwQEHAdAB7wH4Ac8CAAHBAQcBggHP + AeEB5wH4AQAB4wGPAcQBPwHDAfMB/AEAAeMBjwHAAf8BxwH9Af4BBAHjAY8Blgf/AbMN/wHAAQEC/wHg + AQMBAAEfAYABAQL/AeABAwEAAQ8BgAEBAfwBPwHgAQMBAAEHAYABAQH8AT8B4AEDAQABAwGAAQEB/AE/ + AeABAwEAAQEBgAEBAeABBwHgAQMCAAGAAQEB4AEHAeABAwEAAR8BgAEBAeABBwHgAQMBAAEfAYABAQHg + AQcB4AEDAQABHwGAAQEB/AE/AeABAwGPAfEBgAEBAfwBPwHgAQcB/wH5AYABAQH8AT8B4AEPAf8BdQGA + AQEC/wHgAR8B/wGPAYABAQr/FgAL + + + + 101 + + + 17, 58 + + + 136, 59 + + + 439, 17 + + + 119, 17 + + + 598, 17 + + + 276, 17 + + \ No newline at end of file diff --git a/Labyrinth3/IDE/Pages/AnnotationPage.cs b/Labyrinth3/IDE/Pages/AnnotationPage.cs new file mode 100644 index 0000000..151b39b --- /dev/null +++ b/Labyrinth3/IDE/Pages/AnnotationPage.cs @@ -0,0 +1,496 @@ +// Decompiled with JetBrains decompiler +// Type: Labyrinth.Pages.AnnotationPage +// Assembly: Labyrinth, Version=3.6.1928.15690, Culture=neutral, PublicKeyToken=null +// MVID: 1462002E-0BD1-49D2-9B56-C22E66C903E7 +// Assembly location: C:\Dropbox\Workspace\Programs\Labyrinth\Labyrinth.exe + +using Labyrinth.Events; +using Labyrinth.Extensibility; +using Labyrinth.Plot; +using System; +using System.Collections; +using System.ComponentModel; +using System.Drawing; +using System.IO; +using System.Resources; +using System.Windows.Forms; + +namespace Labyrinth.Pages +{ + public class AnnotationPage : UserControl, IAnnotationPage, IPage + { + private bool fShowText = true; + private bool fShowLink = true; + private bool fShowSketch = true; + private ToolBar ToolBar; + private ImageList ToolbarImages; + private ToolBarButton TextBtn; + private ToolBarButton LinkBtn; + private ToolBarButton SketchBtn; + private ListView AnnotationList; + private ContextMenu AnnotationMenu; + private MenuItem OpenAnnotation; + private ColumnHeader AnnotationHdr; + private ColumnHeader SourceHdr; + private MenuItem OpenSource; + private ToolBarButton Sep1; + private ToolBarButton ExportBtn; + private IContainer components; + + public AnnotationPage() + { + this.InitializeComponent(); + this.AnnotationList.SmallImageList = LabyrinthData.ElementImages; + this.AnnotationList.ListViewItemSorter = (IComparer)new ListViewSorter(); + this.update_annotations(); + } + + protected override void Dispose(bool disposing) + { + if (disposing && this.components != null) + this.components.Dispose(); + base.Dispose(disposing); + } + + private void InitializeComponent() + { + this.components = (IContainer)new Container(); + ResourceManager resourceManager = new ResourceManager(typeof(AnnotationPage)); + this.ToolbarImages = new ImageList(this.components); + this.ToolBar = new ToolBar(); + this.TextBtn = new ToolBarButton(); + this.LinkBtn = new ToolBarButton(); + this.SketchBtn = new ToolBarButton(); + this.AnnotationList = new ListView(); + this.AnnotationHdr = new ColumnHeader(); + this.SourceHdr = new ColumnHeader(); + this.AnnotationMenu = new ContextMenu(); + this.OpenAnnotation = new MenuItem(); + this.OpenSource = new MenuItem(); + this.Sep1 = new ToolBarButton(); + this.ExportBtn = new ToolBarButton(); + this.SuspendLayout(); + this.ToolbarImages.ColorDepth = ColorDepth.Depth8Bit; + this.ToolbarImages.ImageSize = new Size(16, 16); + this.ToolbarImages.ImageStream = (ImageListStreamer)resourceManager.GetObject("ToolbarImages.ImageStream"); + this.ToolbarImages.TransparentColor = Color.Magenta; + this.ToolBar.Appearance = ToolBarAppearance.Flat; + this.ToolBar.Buttons.AddRange(new ToolBarButton[5] + { + this.TextBtn, + this.LinkBtn, + this.SketchBtn, + this.Sep1, + this.ExportBtn + }); + this.ToolBar.DropDownArrows = true; + this.ToolBar.ImageList = this.ToolbarImages; + this.ToolBar.Name = "ToolBar"; + this.ToolBar.ShowToolTips = true; + this.ToolBar.Size = new Size(552, 25); + this.ToolBar.TabIndex = 0; + this.ToolBar.ButtonClick += new ToolBarButtonClickEventHandler(this.ToolBar_ButtonClick); + this.TextBtn.ImageIndex = 0; + this.TextBtn.ToolTipText = "Show Text Annotations"; + this.LinkBtn.ImageIndex = 1; + this.LinkBtn.ToolTipText = "Show Link Annotations"; + this.SketchBtn.ImageIndex = 2; + this.SketchBtn.ToolTipText = "Show Sketch Annotations"; + this.AnnotationList.Columns.AddRange(new ColumnHeader[2] + { + this.AnnotationHdr, + this.SourceHdr + }); + this.AnnotationList.ContextMenu = this.AnnotationMenu; + this.AnnotationList.Dock = DockStyle.Fill; + this.AnnotationList.FullRowSelect = true; + this.AnnotationList.Location = new Point(0, 25); + this.AnnotationList.Name = "AnnotationList"; + this.AnnotationList.Size = new Size(552, 231); + this.AnnotationList.Sorting = SortOrder.Ascending; + this.AnnotationList.TabIndex = 1; + this.AnnotationList.View = View.Details; + this.AnnotationList.MouseDown += new MouseEventHandler(this.AnnotationList_MouseDown); + this.AnnotationList.DoubleClick += new EventHandler(this.AnnotationList_DoubleClick); + this.AnnotationList.ColumnClick += new ColumnClickEventHandler(this.AnnotationList_ColumnClick); + this.AnnotationHdr.Text = "Annotation"; + this.AnnotationHdr.Width = 250; + this.SourceHdr.Text = "Source"; + this.SourceHdr.Width = 120; + this.AnnotationMenu.MenuItems.AddRange(new MenuItem[2] + { + this.OpenAnnotation, + this.OpenSource + }); + this.OpenAnnotation.Index = 0; + this.OpenAnnotation.Text = "Open Annotation"; + this.OpenAnnotation.Click += new EventHandler(this.OpenAnnotation_Click); + this.OpenSource.Index = 1; + this.OpenSource.Text = "Open Source"; + this.OpenSource.Click += new EventHandler(this.OpenSource_Click); + this.Sep1.Style = ToolBarButtonStyle.Separator; + this.ExportBtn.ImageIndex = 3; + this.ExportBtn.ToolTipText = "Export Annotations"; + this.Controls.AddRange(new Control[2] + { + (Control) this.AnnotationList, + (Control) this.ToolBar + }); + this.Name = nameof(AnnotationPage); + this.Size = new Size(552, 256); + this.ResumeLayout(false); + } + + public string Title + { + get + { + return "Annotation List"; + } + } + + public bool IsObsolete + { + get + { + return false; + } + } + + public void UpdateUI() + { + this.OpenAnnotation.Enabled = this.SelectedAnnotation != null; + this.TextBtn.Enabled = true; + this.TextBtn.Pushed = this.fShowText; + this.LinkBtn.Enabled = true; + this.LinkBtn.Pushed = this.fShowLink; + this.SketchBtn.Enabled = true; + this.SketchBtn.Pushed = this.fShowSketch; + } + + public void UpdateData() + { + this.update_annotations(); + } + + public bool ShowTextAnnotations + { + get + { + return this.fShowText; + } + set + { + this.fShowText = value; + } + } + + public bool ShowLinkAnnotations + { + get + { + return this.fShowLink; + } + set + { + this.fShowLink = value; + } + } + + public bool ShowSketchAnnotations + { + get + { + return this.fShowSketch; + } + set + { + this.fShowSketch = value; + } + } + + public Annotation SelectedAnnotation + { + get + { + if (this.AnnotationList.SelectedItems.Count != 0) + return this.AnnotationList.SelectedItems[0].Tag as Annotation; + return (Annotation)null; + } + } + + public event ElementEventHandler ElementModified; + + public event ElementEventHandler ElementActivated; + + public event TimelineEventHandler TimelineModified; + + public event TimelineEventHandler TimelineActivated; + + protected void OnElementModified(ElementEventArgs e) + { + try + { + if (this.ElementModified == null) + return; + this.ElementModified((object)this, e); + } + catch (Exception ex) + { + LabyrinthData.Log((object)ex); + } + } + + protected void OnElementActivated(ElementEventArgs e) + { + try + { + if (this.ElementActivated == null) + return; + this.ElementActivated((object)this, e); + } + catch (Exception ex) + { + LabyrinthData.Log((object)ex); + } + } + + protected void OnTimelineModified(TimelineEventArgs e) + { + try + { + if (this.TimelineModified == null) + return; + this.TimelineModified((object)this, e); + } + catch (Exception ex) + { + LabyrinthData.Log((object)ex); + } + } + + protected void OnTimelineActivated(TimelineEventArgs e) + { + try + { + if (this.TimelineActivated == null) + return; + this.TimelineActivated((object)this, e); + } + catch (Exception ex) + { + LabyrinthData.Log((object)ex); + } + } + + private void ToolBar_ButtonClick(object sender, ToolBarButtonClickEventArgs e) + { + try + { + if (e.Button == this.TextBtn) + { + this.fShowText = !this.fShowText; + this.update_annotations(); + } + else if (e.Button == this.LinkBtn) + { + this.fShowLink = !this.fShowLink; + this.update_annotations(); + } + else if (e.Button == this.SketchBtn) + { + this.fShowSketch = !this.fShowSketch; + this.update_annotations(); + } + else + { + if (e.Button != this.ExportBtn) + return; + string str1 = "HTML Files|*.html|Text Files|*.txt"; + try + { + SaveFileDialog saveFileDialog = new SaveFileDialog(); + saveFileDialog.FileName = LabyrinthData.Project.Name + " Annotations"; + saveFileDialog.Filter = str1; + if (saveFileDialog.ShowDialog() != DialogResult.OK) + return; + string str2 = this.export_annotations(saveFileDialog.FilterIndex == 1); + StreamWriter text = File.CreateText(saveFileDialog.FileName); + text.WriteLine(str2); + text.Close(); + } + catch (Exception ex) + { + LabyrinthData.Log((object)ex); + } + } + } + catch (Exception ex) + { + LabyrinthData.Log((object)ex); + } + } + + private void AnnotationList_DoubleClick(object sender, EventArgs e) + { + if (this.SelectedAnnotation == null) + return; + this.OpenAnnotation_Click(sender, e); + } + + private void AnnotationList_MouseDown(object sender, MouseEventArgs e) + { + this.AnnotationList.SelectedItems.Clear(); + ListViewItem itemAt = this.AnnotationList.GetItemAt(e.X, e.Y); + if (itemAt != null) + itemAt.Selected = true; + this.UpdateUI(); + } + + private void AnnotationList_ColumnClick(object sender, ColumnClickEventArgs e) + { + ListViewSorter.Sort(this.AnnotationList, e.Column); + } + + public void update_annotations() + { + this.AnnotationList.BeginUpdate(); + this.AnnotationList.Items.Clear(); + ArrayList arrayList = new ArrayList(); + foreach (Element element in LabyrinthData.Project.Elements) + { + foreach (Annotation annotation1 in element.Annotations) + { + ListViewItem annotation2 = this.get_annotation(annotation1, (object)element); + if (annotation2 != null) + arrayList.Add((object)annotation2); + } + } + foreach (Timeline timeline in LabyrinthData.Project.Timelines) + { + foreach (TimelinePoint point in timeline.Points) + { + foreach (TimelineItem timelineItem in point.Items) + { + ListViewItem annotation = this.get_annotation((Annotation)timelineItem.Annotation, (object)timeline); + if (annotation != null) + arrayList.Add((object)annotation); + } + } + } + this.AnnotationList.Items.AddRange((ListViewItem[])arrayList.ToArray(typeof(ListViewItem))); + if (this.AnnotationList.Items.Count == 0) + { + ListViewItem listViewItem = this.AnnotationList.Items.Add("No annotations"); + listViewItem.ForeColor = SystemColors.GrayText; + listViewItem.ImageIndex = -1; + } + this.AnnotationList.EndUpdate(); + } + + private ListViewItem get_annotation(Annotation a, object source) + { + if (a is TextAnnotation && !this.fShowText) + return (ListViewItem)null; + if (a is LinkAnnotation && !this.fShowLink) + return (ListViewItem)null; + if (a is SketchAnnotation && !this.fShowSketch) + return (ListViewItem)null; + return new ListViewItem(a.Title) + { + SubItems = { + source.ToString() + }, + ImageIndex = LabyrinthData.GetImageIndex(a), + Tag = (object)a + }; + } + + private string export_annotations(bool markup) + { + string str1 = ""; + string title = LabyrinthData.Project.Name + " Annotations"; + if (markup) + str1 = str1 + "" + Environment.NewLine + LabyrinthData.HTMLHeader(title) + Environment.NewLine + "" + Environment.NewLine; + if (markup) + str1 += "

"; + string str2 = str1 + title; + if (markup) + str2 += "

"; + string str3 = str2 + Environment.NewLine; + foreach (ListViewItem listViewItem in this.AnnotationList.Items) + { + Annotation tag = listViewItem.Tag as Annotation; + if (tag != null) + { + str3 += Environment.NewLine; + if (markup) + str3 = str3 + "

" + Environment.NewLine; + str3 = str3 + tag.Title + Environment.NewLine; + if (markup) + str3 = str3 + "

" + Environment.NewLine; + object source = this.get_source(tag); + if (source != null) + { + if (markup) + str3 = str3 + "

" + Environment.NewLine; + str3 = str3 + source.ToString() + Environment.NewLine; + if (markup) + str3 = str3 + "

" + Environment.NewLine; + } + if (markup) + str3 = str3 + "

" + Environment.NewLine; + str3 = str3 + (markup ? tag.Content.Replace("\n", "
") : tag.Content) + Environment.NewLine; + if (markup) + str3 = str3 + "

" + Environment.NewLine; + } + } + if (markup) + str3 = str3 + "" + Environment.NewLine + "" + Environment.NewLine; + return str3; + } + + private void OpenAnnotation_Click(object sender, EventArgs e) + { + if (this.SelectedAnnotation == null || !Annotations.Open(this.SelectedAnnotation)) + return; + object source = this.get_source(this.SelectedAnnotation); + if (source is Element) + this.OnElementModified(new ElementEventArgs(source as Element)); + if (source is Timeline) + this.OnTimelineModified(new TimelineEventArgs(source as Timeline)); + this.update_annotations(); + } + + private object get_source(Annotation a) + { + foreach (Element element in LabyrinthData.Project.Elements) + { + if (element.Annotations.Contains(a)) + return (object)element; + } + foreach (Timeline timeline in LabyrinthData.Project.Timelines) + { + foreach (TimelinePoint point in timeline.Points) + { + foreach (TimelineItem timelineItem in point.Items) + { + if (timelineItem.Annotation == a) + return (object)timeline; + } + } + } + return (object)null; + } + + private void OpenSource_Click(object sender, EventArgs e) + { + object source = this.get_source(this.SelectedAnnotation); + if (source is Element) + this.OnElementActivated(new ElementEventArgs(source as Element)); + if (!(source is Timeline)) + return; + this.OnTimelineActivated(new TimelineEventArgs(source as Timeline)); + } + } +} \ No newline at end of file diff --git a/Labyrinth3/IDE/Pages/AnnotationPage.resx b/Labyrinth3/IDE/Pages/AnnotationPage.resx new file mode 100644 index 0000000..a585041 --- /dev/null +++ b/Labyrinth3/IDE/Pages/AnnotationPage.resx @@ -0,0 +1,183 @@ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + text/microsoft-resx + + + 2.0 + + + System.Resources.ResXResourceReader, System.Windows.Forms, Version=4.0.0.0, Culture=neutral, PublicKeyToken=b77a5c561934e089 + + + System.Resources.ResXResourceWriter, System.Windows.Forms, Version=4.0.0.0, Culture=neutral, PublicKeyToken=b77a5c561934e089 + + + + 143, 17 + + + AnnotationPage + + + 17, 17 + + + + AAEAAAD/////AQAAAAAAAAAMAgAAAFdTeXN0ZW0uV2luZG93cy5Gb3JtcywgVmVyc2lvbj00LjAuMC4w + LCBDdWx0dXJlPW5ldXRyYWwsIFB1YmxpY0tleVRva2VuPWI3N2E1YzU2MTkzNGUwODkFAQAAACZTeXN0 + ZW0uV2luZG93cy5Gb3Jtcy5JbWFnZUxpc3RTdHJlYW1lcgEAAAAERGF0YQcCAgAAAAkDAAAADwMAAACy + CgAAAk1TRnQBSQFMAgEBBAEAAQkBAAEIAQABEAEAARABAAT/AQkBEAj/AUIBTQE2AQQGAAE2AQQCAAEo + AwABQAMAASADAAEBAQABCAYAAQgYAAGAAgABgAMAAoABAAGAAwABgAEAAYABAAKAAgADwAEAAcAB3AHA + AQAB8AHKAaYBAAEzBQABMwEAATMBAAEzAQACMwIAAxYBAAMcAQADIgEAAykBAANVAQADTQEAA0IBAAM5 + AQABgAF8Af8BAAJQAf8BAAGTAQAB1gEAAf8B7AHMAQABxgHWAe8BAAHWAucBAAGQAakBrQIAAf8BMwMA + AWYDAAGZAwABzAIAATMDAAIzAgABMwFmAgABMwGZAgABMwHMAgABMwH/AgABZgMAAWYBMwIAAmYCAAFm + AZkCAAFmAcwCAAFmAf8CAAGZAwABmQEzAgABmQFmAgACmQIAAZkBzAIAAZkB/wIAAcwDAAHMATMCAAHM + AWYCAAHMAZkCAALMAgABzAH/AgAB/wFmAgAB/wGZAgAB/wHMAQABMwH/AgAB/wEAATMBAAEzAQABZgEA + ATMBAAGZAQABMwEAAcwBAAEzAQAB/wEAAf8BMwIAAzMBAAIzAWYBAAIzAZkBAAIzAcwBAAIzAf8BAAEz + AWYCAAEzAWYBMwEAATMCZgEAATMBZgGZAQABMwFmAcwBAAEzAWYB/wEAATMBmQIAATMBmQEzAQABMwGZ + AWYBAAEzApkBAAEzAZkBzAEAATMBmQH/AQABMwHMAgABMwHMATMBAAEzAcwBZgEAATMBzAGZAQABMwLM + AQABMwHMAf8BAAEzAf8BMwEAATMB/wFmAQABMwH/AZkBAAEzAf8BzAEAATMC/wEAAWYDAAFmAQABMwEA + AWYBAAFmAQABZgEAAZkBAAFmAQABzAEAAWYBAAH/AQABZgEzAgABZgIzAQABZgEzAWYBAAFmATMBmQEA + AWYBMwHMAQABZgEzAf8BAAJmAgACZgEzAQADZgEAAmYBmQEAAmYBzAEAAWYBmQIAAWYBmQEzAQABZgGZ + AWYBAAFmApkBAAFmAZkBzAEAAWYBmQH/AQABZgHMAgABZgHMATMBAAFmAcwBmQEAAWYCzAEAAWYBzAH/ + AQABZgH/AgABZgH/ATMBAAFmAf8BmQEAAWYB/wHMAQABzAEAAf8BAAH/AQABzAEAApkCAAGZATMBmQEA + AZkBAAGZAQABmQEAAcwBAAGZAwABmQIzAQABmQEAAWYBAAGZATMBzAEAAZkBAAH/AQABmQFmAgABmQFm + ATMBAAGZATMBZgEAAZkBZgGZAQABmQFmAcwBAAGZATMB/wEAApkBMwEAApkBZgEAA5kBAAKZAcwBAAKZ + Af8BAAGZAcwCAAGZAcwBMwEAAWYBzAFmAQABmQHMAZkBAAGZAswBAAGZAcwB/wEAAZkB/wIAAZkB/wEz + AQABmQHMAWYBAAGZAf8BmQEAAZkB/wHMAQABmQL/AQABzAMAAZkBAAEzAQABzAEAAWYBAAHMAQABmQEA + AcwBAAHMAQABmQEzAgABzAIzAQABzAEzAWYBAAHMATMBmQEAAcwBMwHMAQABzAEzAf8BAAHMAWYCAAHM + AWYBMwEAAZkCZgEAAcwBZgGZAQABzAFmAcwBAAGZAWYB/wEAAcwBmQIAAcwBmQEzAQABzAGZAWYBAAHM + ApkBAAHMAZkBzAEAAcwBmQH/AQACzAIAAswBMwEAAswBZgEAAswBmQEAA8wBAALMAf8BAAHMAf8CAAHM + Af8BMwEAAZkB/wFmAQABzAH/AZkBAAHMAf8BzAEAAcwC/wEAAcwBAAEzAQAB/wEAAWYBAAH/AQABmQEA + AcwBMwIAAf8CMwEAAf8BMwFmAQAB/wEzAZkBAAH/ATMBzAEAAf8BMwH/AQAB/wFmAgAB/wFmATMBAAHM + AmYBAAH/AWYBmQEAAf8BZgHMAQABzAFmAf8BAAH/AZkCAAH/AZkBMwEAAf8BmQFmAQAB/wKZAQAB/wGZ + AcwBAAH/AZkB/wEAAf8BzAIAAf8BzAEzAQAB/wHMAWYBAAH/AcwBmQEAAf8CzAEAAf8BzAH/AQAC/wEz + AQABzAH/AWYBAAL/AZkBAAL/AcwBAAJmAf8BAAFmAf8BZgEAAWYC/wEAAf8CZgEAAf8BZgH/AQAC/wFm + AQABIQEAAaUBAANfAQADdwEAA4YBAAOWAQADywEAA7IBAAPXAQAD3QEAA+MBAAPqAQAD8QEAA/gBAAHw + AfsB/wEAAaQCoAEAA4ADAAH/AgAB/wMAAv8BAAH/AwAB/wEAAf8BAAL/AgAD//8A/wD/AP8AQQAB/D8A + AvwmAAT/DwAI/CUAAf8CAgH/DwAJ/AEAAewB+wH/AfsB/wH7Af8B+wH/AewBAAH/AfsDAAHsAfsB/wIA + AfsCAAH/AewBAAH/AfsDAAHsAfsBAAH/AfsB+QH/AQAB/wHsAQAB/wH7CQAI/AIAAewB/wH7Af8B+wH/ + AfsB/wH7AuwBAAH/AwAB7AH/AfsCAAH/AgAB+wLsAQAB/wMAAewB/wEAAf8B/AH5Af8BAAH7AuwBAAH/ + DgAC/AMAAewB+wH/AfsB/wH7Af8B+wH/AewB+wHsBAAB7AH7Af8CAAH7AgAB/wHsAfsB7AQAAewB+wEA + Af8B/AH7Af8BAAH/AewB+wHsDwAB/AQAAewB/wH7Af8B+wH/AfsB/wH7BOwDAAHsAf8B+wIAAf8CAAH7 + BOwDAAHsAf8BAAH/AvwB/wEAAfsE7AMAAewB+wH/AfsB/wH7Af8B+wH/AewBAAH/AfsDAAHsAfsB/wH7 + Af8B+wH/AfsB/wH7Af8B+wH/AwAB7AH7Af8B+wEAAfsB/wEAAf8B+wH/AfsB/wMAAewB+wEABP8BAAH/ + AfsB/wH7Af8DAAHsAf8B+wH/AfsB/wH7Af8B+wLsAQAB/wMAAewB/wH7Af8B+wH/AfsB/wH7Af8B+wH/ + AfsDAAHsAf8B+wH/AQAB/wH7AQAB+wH/AfsB/wH7AwAB7AH/BgAB+wH/AfsB/wH7AwAB7AH7Af8B+wH/ + AfsB/wH7Af8B7AH7AewEAAHsAfsB/wH7Af8B+wH/AfsB/wH7Af8B+wH/AwAB7AH7Af8B+wH/AgAB+wH/ + AfsB/wH7Af8DAAHsAfsB/wH7Af8B+wH/AfsB/wH7Af8B+wH/AwAB7AH/AfsB/wH7Af8B+wH/AfsE7AMA + DewDAA3sAwAN7AMAAewB+wH/AfsB/wH7Af8B+wH/AfsB/wH7Af8zAAHsAf8B+wH/AfsB/wH7Af8B+wH/ + AfsB/wH7MwAB7AH7Af8B+wH/AfsB/wH7Af8B+wH/AfsB/zMADexCAAFCAU0BPgcAAT4DAAEoAwABQAMA + ASADAAEBAQABAQYAAQEWAAP/gQAC/wH4BP8B9wL/AfcBfwHgAX8B/wHzAv8B9wF/AeABfwH+AQEBgAEB + AYABAQGAAQEB/gEAAYABAQGAAQEBgAEBAf4BAQGAAQEBgAEBAYABAQH/AfMBgAEBAYABAQGAAQEBgAEB + AYABAQGAAQEBgAEBAYABAQGAAQEBgAEBAYABAQGAAQEBgAEBAYABAQGAAQEBgAEBAYABAQGAAQEBgAEB + AYABAQGAAQEBgAEBAYABAQGAAQEG/wGAAQEG/wGAAQEG/wGAAQEI/xYACw== + + + \ No newline at end of file diff --git a/Labyrinth3/IDE/Pages/CalendarPage.cs b/Labyrinth3/IDE/Pages/CalendarPage.cs new file mode 100644 index 0000000..1c88965 --- /dev/null +++ b/Labyrinth3/IDE/Pages/CalendarPage.cs @@ -0,0 +1,566 @@ +// Decompiled with JetBrains decompiler +// Type: Labyrinth.Pages.CalendarPage +// Assembly: Labyrinth, Version=3.6.1928.15690, Culture=neutral, PublicKeyToken=null +// MVID: 1462002E-0BD1-49D2-9B56-C22E66C903E7 +// Assembly location: C:\Dropbox\Workspace\Programs\Labyrinth\Labyrinth.exe + +using Labyrinth.Collections; +using Labyrinth.Events; +using Labyrinth.Extensibility; +using Labyrinth.Forms; +using Labyrinth.Plot; +using System; +using System.Collections; +using System.ComponentModel; +using System.Drawing; +using System.Windows.Forms; + +namespace Labyrinth.Pages +{ + public class CalendarPage : UserControl, ICalendarPage, IPage + { + private Container components = (Container)null; + private ContextMenu ItemContext; + private MenuItem ItemOpenAnnotation; + private MenuItem ItemPointProperties; + private MenuItem ItemTimelineProperties; + private MenuItem ItemOpenElement; + private MenuItem ItemElementProperties; + private MenuItem ItemOpenTimeline; + private ListView PointList; + private Splitter PointSplitter; + private Panel CalendarPanel; + private MonthCalendar Calendar; + private ListView ItemList; + private ColumnHeader NameHdr; + private ColumnHeader ElementHdr; + private ColumnHeader PointHdr; + private ColumnHeader TimelineHdr; + private ColumnHeader DateHdr; + + public CalendarPage() + { + this.InitializeComponent(); + this.PointList.ListViewItemSorter = (IComparer)new ListViewSorter(); + this.ItemList.ListViewItemSorter = (IComparer)new ListViewSorter(); + this.ItemList.SmallImageList = LabyrinthData.ElementImages; + this.UpdateData(); + } + + protected override void Dispose(bool disposing) + { + if (disposing && this.components != null) + this.components.Dispose(); + base.Dispose(disposing); + } + + private void InitializeComponent() + { + this.ItemContext = new ContextMenu(); + this.ItemOpenAnnotation = new MenuItem(); + this.ItemOpenElement = new MenuItem(); + this.ItemOpenTimeline = new MenuItem(); + this.ItemElementProperties = new MenuItem(); + this.ItemPointProperties = new MenuItem(); + this.ItemTimelineProperties = new MenuItem(); + this.PointList = new ListView(); + this.PointSplitter = new Splitter(); + this.CalendarPanel = new Panel(); + this.Calendar = new MonthCalendar(); + this.ItemList = new ListView(); + this.NameHdr = new ColumnHeader(); + this.ElementHdr = new ColumnHeader(); + this.PointHdr = new ColumnHeader(); + this.TimelineHdr = new ColumnHeader(); + this.DateHdr = new ColumnHeader(); + this.CalendarPanel.SuspendLayout(); + this.SuspendLayout(); + this.ItemContext.MenuItems.AddRange(new MenuItem[6] + { + this.ItemOpenAnnotation, + this.ItemOpenElement, + this.ItemOpenTimeline, + this.ItemElementProperties, + this.ItemPointProperties, + this.ItemTimelineProperties + }); + this.ItemOpenAnnotation.Index = 0; + this.ItemOpenAnnotation.Text = "Open Annotation"; + this.ItemOpenAnnotation.Click += new EventHandler(this.ItemOpenAnnotation_Click); + this.ItemOpenElement.Index = 1; + this.ItemOpenElement.Text = "Open Element"; + this.ItemOpenElement.Click += new EventHandler(this.ItemOpenElement_Click); + this.ItemOpenTimeline.Index = 2; + this.ItemOpenTimeline.Text = "Open Timeline"; + this.ItemOpenTimeline.Click += new EventHandler(this.ItemOpenTimeline_Click); + this.ItemElementProperties.Index = 3; + this.ItemElementProperties.Text = "Element Properties"; + this.ItemElementProperties.Click += new EventHandler(this.ItemElementProperties_Click); + this.ItemPointProperties.Index = 4; + this.ItemPointProperties.Text = "Timeline Point Properties"; + this.ItemPointProperties.Click += new EventHandler(this.ItemPointProperties_Click); + this.ItemTimelineProperties.Index = 5; + this.ItemTimelineProperties.Text = "Timeline Properties"; + this.ItemTimelineProperties.Click += new EventHandler(this.ItemTimelineProperties_Click); + this.PointList.Activation = ItemActivation.OneClick; + this.PointList.Columns.AddRange(new ColumnHeader[1] + { + this.DateHdr + }); + this.PointList.Dock = DockStyle.Left; + this.PointList.FullRowSelect = true; + this.PointList.Name = "PointList"; + this.PointList.Size = new Size(160, 352); + this.PointList.TabIndex = 6; + this.PointList.View = View.Details; + this.PointList.MouseDown += new MouseEventHandler(this.PointList_MouseDown); + this.PointList.ItemActivate += new EventHandler(this.PointList_ItemActivate); + this.PointList.ColumnClick += new ColumnClickEventHandler(this.PointList_ColumnClick); + this.PointSplitter.Location = new Point(160, 0); + this.PointSplitter.Name = "PointSplitter"; + this.PointSplitter.Size = new Size(3, 352); + this.PointSplitter.TabIndex = 7; + this.PointSplitter.TabStop = false; + this.CalendarPanel.AutoScroll = true; + this.CalendarPanel.BackColor = SystemColors.ControlDark; + this.CalendarPanel.Controls.AddRange(new Control[1] + { + (Control) this.Calendar + }); + this.CalendarPanel.Dock = DockStyle.Top; + this.CalendarPanel.Location = new Point(163, 0); + this.CalendarPanel.Name = "CalendarPanel"; + this.CalendarPanel.Size = new Size(453, 168); + this.CalendarPanel.TabIndex = 8; + this.CalendarPanel.Resize += new EventHandler(this.CalendarPanel_Resize); + this.CalendarPanel.Layout += new LayoutEventHandler(this.CalendarPanel_Layout); + this.Calendar.Location = new Point(8, 8); + this.Calendar.MaxSelectionCount = 1; + this.Calendar.Name = "Calendar"; + this.Calendar.ScrollChange = 1; + this.Calendar.ShowTodayCircle = false; + this.Calendar.TabIndex = 4; + this.Calendar.DateSelected += new DateRangeEventHandler(this.Calendar_DateSelected); + this.Calendar.DateChanged += new DateRangeEventHandler(this.Calendar_DateSelected); + this.ItemList.Columns.AddRange(new ColumnHeader[4] + { + this.NameHdr, + this.ElementHdr, + this.PointHdr, + this.TimelineHdr + }); + this.ItemList.ContextMenu = this.ItemContext; + this.ItemList.Dock = DockStyle.Fill; + this.ItemList.FullRowSelect = true; + this.ItemList.Location = new Point(163, 168); + this.ItemList.Name = "ItemList"; + this.ItemList.Size = new Size(453, 184); + this.ItemList.TabIndex = 9; + this.ItemList.View = View.Details; + this.ItemList.MouseDown += new MouseEventHandler(this.ItemList_MouseDown); + this.ItemList.DoubleClick += new EventHandler(this.ItemList_DoubleClick); + this.ItemList.ColumnClick += new ColumnClickEventHandler(this.ItemList_ColumnClick); + this.NameHdr.Text = "Name"; + this.NameHdr.Width = 90; + this.ElementHdr.Text = "Element"; + this.ElementHdr.Width = 90; + this.PointHdr.Text = "Point"; + this.PointHdr.Width = 90; + this.TimelineHdr.Text = "Timeline"; + this.TimelineHdr.Width = 90; + this.DateHdr.Text = "Date"; + this.DateHdr.Width = 150; + this.Controls.AddRange(new Control[4] + { + (Control) this.ItemList, + (Control) this.CalendarPanel, + (Control) this.PointSplitter, + (Control) this.PointList + }); + this.Font = new Font("Tahoma", 11f, FontStyle.Regular, GraphicsUnit.World, (byte)0); + this.Name = "ChronologyPage"; + this.Size = new Size(616, 352); + this.CalendarPanel.ResumeLayout(false); + this.ResumeLayout(false); + } + + public string Title + { + get + { + return "Calendar"; + } + } + + public bool IsObsolete + { + get + { + return false; + } + } + + public void UpdateUI() + { + bool flag = this.SelectedItem != null; + this.ItemOpenAnnotation.Enabled = flag; + this.ItemOpenElement.Enabled = flag; + this.ItemOpenTimeline.Enabled = flag; + this.ItemElementProperties.Enabled = flag; + this.ItemPointProperties.Enabled = flag; + this.ItemTimelineProperties.Enabled = flag; + } + + public void UpdateData() + { + this.update_calendar(); + this.update_items(); + } + + public DateTime SelectedDate + { + get + { + if (this.PointList.SelectedItems.Count == 0) + return DateTime.MinValue; + try + { + return (DateTime)this.PointList.SelectedItems[0].Tag; + } + catch + { + return DateTime.MinValue; + } + } + } + + public TimelineItem SelectedItem + { + get + { + if (this.ItemList.SelectedItems.Count != 0) + return this.ItemList.SelectedItems[0].Tag as TimelineItem; + return (TimelineItem)null; + } + } + + public event ElementEventHandler ElementActivated; + + public event ElementEventHandler ElementModified; + + public event TimelineEventHandler TimelineActivated; + + public event TimelineEventHandler TimelineModified; + + protected void OnElementActivated(ElementEventArgs e) + { + try + { + if (this.ElementActivated == null) + return; + this.ElementActivated((object)this, e); + } + catch (Exception ex) + { + LabyrinthData.Log((object)ex); + } + } + + protected void OnElementModified(ElementEventArgs e) + { + try + { + if (this.ElementModified == null) + return; + this.ElementModified((object)this, e); + } + catch (Exception ex) + { + LabyrinthData.Log((object)ex); + } + } + + protected void OnTimelineActivated(TimelineEventArgs e) + { + try + { + if (this.TimelineActivated == null) + return; + this.TimelineActivated((object)this, e); + } + catch (Exception ex) + { + LabyrinthData.Log((object)ex); + } + } + + protected void OnTimelineModified(TimelineEventArgs e) + { + try + { + if (this.TimelineModified == null) + return; + this.TimelineModified((object)this, e); + } + catch (Exception ex) + { + LabyrinthData.Log((object)ex); + } + } + + private void ItemOpenAnnotation_Click(object sender, EventArgs e) + { + TimelineItem selectedItem = this.SelectedItem; + if (selectedItem == null || !Annotations.Open((Annotation)selectedItem.Annotation)) + return; + this.UpdateData(); + this.OnTimelineModified(new TimelineEventArgs(this.get_parent(selectedItem))); + } + + private void ItemOpenElement_Click(object sender, EventArgs e) + { + if (this.SelectedItem == null) + return; + int index = LabyrinthData.Project.Elements.IndexOf(this.SelectedItem.ElementID); + if (index == -1) + return; + this.OnElementActivated(new ElementEventArgs(LabyrinthData.Project.Elements[index])); + } + + private void ItemOpenTimeline_Click(object sender, EventArgs e) + { + if (this.SelectedItem == null) + return; + Timeline parent = this.get_parent(this.SelectedItem); + if (parent == null) + return; + this.OnTimelineActivated(new TimelineEventArgs(parent)); + } + + private void ItemElementProperties_Click(object sender, EventArgs e) + { + if (this.SelectedItem == null) + return; + int index = LabyrinthData.Project.Elements.IndexOf(this.SelectedItem.ElementID); + if (index == -1) + return; + Element element = LabyrinthData.Project.Elements[index]; + if (new ElementDlg(element).ShowDialog() != DialogResult.OK) + return; + this.UpdateData(); + this.OnElementModified(new ElementEventArgs(element)); + } + + private void ItemPointProperties_Click(object sender, EventArgs e) + { + TimelineItem selectedItem = this.SelectedItem; + if (selectedItem == null) + return; + TimelinePoint parentPoint = this.get_parent_point(selectedItem); + if (parentPoint == null || new TimelinePointDlg(parentPoint).ShowDialog() != DialogResult.OK) + return; + this.UpdateData(); + this.OnTimelineModified(new TimelineEventArgs(this.get_parent(selectedItem))); + } + + private void ItemTimelineProperties_Click(object sender, EventArgs e) + { + if (this.SelectedItem == null) + return; + Timeline parent = this.get_parent(this.SelectedItem); + if (parent == null || new TimelineDlg(parent).ShowDialog() != DialogResult.OK) + return; + this.UpdateData(); + this.OnTimelineModified(new TimelineEventArgs(parent)); + } + + private void ItemList_MouseDown(object sender, MouseEventArgs e) + { + this.ItemList.SelectedItems.Clear(); + ListViewItem itemAt = this.ItemList.GetItemAt(e.X, e.Y); + if (itemAt != null) + itemAt.Selected = true; + this.UpdateUI(); + } + + private void PointList_MouseDown(object sender, MouseEventArgs e) + { + this.PointList.SelectedItems.Clear(); + ListViewItem itemAt = this.PointList.GetItemAt(e.X, e.Y); + if (itemAt != null) + itemAt.Selected = true; + this.UpdateUI(); + } + + private void CalendarPanel_Resize(object sender, EventArgs e) + { + this.position_calendar(); + } + + private void CalendarPanel_Layout(object sender, LayoutEventArgs e) + { + this.position_calendar(); + } + + private void Calendar_DateSelected(object sender, DateRangeEventArgs e) + { + this.update_items(); + } + + private void ItemList_ColumnClick(object sender, ColumnClickEventArgs e) + { + ListViewSorter.Sort(this.ItemList, e.Column); + } + + private void ItemList_DoubleClick(object sender, EventArgs e) + { + this.ItemOpenAnnotation_Click(sender, e); + } + + private void PointList_ColumnClick(object sender, ColumnClickEventArgs e) + { + ListViewSorter.Sort(this.PointList, e.Column); + } + + private void PointList_ItemActivate(object sender, EventArgs e) + { + if (!(this.SelectedDate != DateTime.MinValue)) + return; + this.Calendar.SelectionStart = this.SelectedDate; + } + + private void update_calendar() + { + DateTime dateTime1 = DateTime.MaxValue; + DateTime dateTime2 = DateTime.MinValue; + ArrayList arrayList1 = new ArrayList(); + foreach (Timeline timeline in LabyrinthData.Project.Timelines) + { + foreach (TimelinePoint point in timeline.Points) + { + if (point.UseSchedule != ScheduleType.None) + { + if (point.Schedule < dateTime1) + dateTime1 = point.Schedule; + if (point.Schedule > dateTime2) + dateTime2 = point.Schedule; + arrayList1.Add((object)point.Schedule); + } + } + } + this.Calendar.BoldedDates = (DateTime[])arrayList1.ToArray(typeof(DateTime)); + this.Calendar.UpdateBoldedDates(); + this.PointList.BeginUpdate(); + this.PointList.Items.Clear(); + if (this.Calendar.BoldedDates.Length != 0) + { + ArrayList arrayList2 = new ArrayList(); + foreach (DateTime boldedDate in this.Calendar.BoldedDates) + arrayList2.Add((object)new ListViewItem(boldedDate.ToLongDateString()) + { + ImageIndex = -1, + Tag = (object)boldedDate + }); + this.PointList.Items.AddRange((ListViewItem[])arrayList2.ToArray(typeof(ListViewItem))); + } + else + { + ListViewItem listViewItem = this.PointList.Items.Add("No scheduled points"); + listViewItem.ForeColor = SystemColors.GrayText; + listViewItem.ImageIndex = -1; + } + this.PointList.EndUpdate(); + if (dateTime1 == DateTime.MaxValue) + { + this.Calendar.SelectionStart = DateTime.Today; + this.Calendar.CalendarDimensions = new Size(1, 1); + } + else + { + this.Calendar.SelectionStart = dateTime1; + int num = dateTime2.Month - dateTime1.Month + 1 + (dateTime2.Year - dateTime1.Year) * 12; + this.Calendar.SetCalendarDimensions(num > 0 ? num : 1, 1); + } + this.position_calendar(); + } + + private void update_items() + { + SelectionRange selectionRange = this.Calendar.SelectionRange; + this.ItemList.BeginUpdate(); + this.ItemList.Items.Clear(); + ArrayList arrayList = new ArrayList(); + foreach (Timeline timeline in LabyrinthData.Project.Timelines) + { + foreach (TimelinePoint point in timeline.Points) + { + if (point.UseSchedule != ScheduleType.None && point.Schedule >= selectionRange.Start && point.Schedule <= selectionRange.End) + { + foreach (TimelineItem timelineItem in point.Items) + { + Element element = (Element)null; + int index = LabyrinthData.Project.Elements.IndexOf(timelineItem.ElementID); + if (index != -1) + element = LabyrinthData.Project.Elements[index]; + arrayList.Add((object)new ListViewItem(timelineItem.Annotation.Title) + { + SubItems = { + element != null ? element.Name : "", + point.Name, + timeline.Name + }, + ImageIndex = LabyrinthData.GetImageIndex((Annotation)timelineItem.Annotation), + Tag = (object)timelineItem + }); + } + } + } + } + this.ItemList.Items.AddRange((ListViewItem[])arrayList.ToArray(typeof(ListViewItem))); + if (this.ItemList.Items.Count == 0) + { + ListViewItem listViewItem = this.ItemList.Items.Add("No timeline items"); + listViewItem.ForeColor = SystemColors.GrayText; + listViewItem.ImageIndex = -1; + } + this.ItemList.EndUpdate(); + } + + private void position_calendar() + { + if (this.CalendarPanel.Width >= this.Calendar.Width) + this.Calendar.Left = (this.CalendarPanel.Width - this.Calendar.Width) / 2; + else + this.Calendar.Left = 0; + this.Calendar.Top = 0; + this.CalendarPanel.Height = this.Calendar.Height + (this.CalendarPanel.Height - this.CalendarPanel.ClientRectangle.Height); + this.CalendarPanel.Invalidate(); + } + + private Timeline get_parent(TimelineItem tli) + { + foreach (Timeline timeline in LabyrinthData.Project.Timelines) + { + foreach (TimelinePoint point in timeline.Points) + { + if (point.Items.Contains(tli)) + return timeline; + } + } + return (Timeline)null; + } + + private TimelinePoint get_parent_point(TimelineItem tli) + { + foreach (Timeline timeline in LabyrinthData.Project.Timelines) + { + foreach (TimelinePoint point in timeline.Points) + { + if (point.Items.Contains(tli)) + return point; + } + } + return null; + } + } +} \ No newline at end of file diff --git a/Labyrinth3/IDE/Pages/CalendarPage.resx b/Labyrinth3/IDE/Pages/CalendarPage.resx new file mode 100644 index 0000000..ac06624 --- /dev/null +++ b/Labyrinth3/IDE/Pages/CalendarPage.resx @@ -0,0 +1,127 @@ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + text/microsoft-resx + + + 2.0 + + + System.Resources.ResXResourceReader, System.Windows.Forms, Version=4.0.0.0, Culture=neutral, PublicKeyToken=b77a5c561934e089 + + + System.Resources.ResXResourceWriter, System.Windows.Forms, Version=4.0.0.0, Culture=neutral, PublicKeyToken=b77a5c561934e089 + + + ChronologyPage + + + + 17, 17 + + \ No newline at end of file diff --git a/Labyrinth3/IDE/Pages/ElementPage.cs b/Labyrinth3/IDE/Pages/ElementPage.cs new file mode 100644 index 0000000..3f731a0 --- /dev/null +++ b/Labyrinth3/IDE/Pages/ElementPage.cs @@ -0,0 +1,1515 @@ +// Decompiled with JetBrains decompiler +// Type: Labyrinth.Pages.ElementPage +// Assembly: Labyrinth, Version=3.6.1928.15690, Culture=neutral, PublicKeyToken=null +// MVID: 1462002E-0BD1-49D2-9B56-C22E66C903E7 +// Assembly location: C:\Dropbox\Workspace\Programs\Labyrinth\Labyrinth.exe + +using Labyrinth.Collections; +using Labyrinth.Controls; +using Labyrinth.Events; +using Labyrinth.Extensibility; +using Labyrinth.Forms; +using Labyrinth.Plot; +using System; +using System.Collections; +using System.Collections.Generic; +using System.ComponentModel; +using System.Drawing; +using System.Drawing.Printing; +using System.IO; +using System.Resources; +using System.Windows.Forms; + +namespace Labyrinth.Pages +{ + public class ElementPage : UserControl, IElementPage, IPage + { + private Element fElement = (Element)null; + private ArrayList fItemsToPrint = new ArrayList(); + private IContainer components; + private ToolBar ToolBar; + private ImageList ToolbarImages; + private Crownwood.Magic.Controls.TabControl Pages; + private Crownwood.Magic.Controls.TabPage AnnotationsPage; + private Crownwood.Magic.Controls.TabPage LinksPage; + private ListView LinkList; + private ColumnHeader ElementHdr; + private ColumnHeader LinkTextHdr; + private ColumnHeader StructureHdr; + private ToolBarButton Sep1; + private ToolBarButton Sep2; + private ContextMenu AnnotationContextMenu; + private MenuItem AnnotationNew; + private MenuItem AnnotationDelete; + private MenuItem AnnotationProperties; + private MenuItem Sep3; + private MenuItem AnnotationMoveUp; + private MenuItem AnnotationMoveDown; + private ToolBarButton AnnotationNewBtn; + private Crownwood.Magic.Controls.TabPage TimelinePage; + private ColumnHeader TimelineHdr; + private ListView TimelineList; + private Splitter TimelineSplitter; + private ContextMenu TimelineContextMenu; + private MenuItem TimelineDelete; + private MenuItem TimelineProperties; + private ContextMenu LinkContextMenu; + private MenuItem LinkOpenElement; + private ImageList ListImages; + private MenuItem LinkOpenStructure; + private MenuItem LinkLinkProperties; + private MenuItem TimelineOpenTimeline; + private ToolBarButton Sep4; + private ToolBarButton ExportBtn; + private ToolBarButton PrintBtn; + private ToolBarButton PrintPreviewBtn; + private ToolBarButton ItemDeleteBtn; + private ToolBarButton ItemPropertiesBtn; + private ToolBarButton MoveUpBtn; + private ToolBarButton MoveDownBtn; + private MenuItem LinkDeleteLink; + private MenuItem Sep5; + private AnnotationPanel AnnotationPanel; + private ToolBarButton FilterBtn; + private AnnotationPanel TimelineAnnotationPanel; + private ToolBarButton PropertiesBtn; + + public ElementPage(Element e) + { + this.InitializeComponent(); + this.LinkList.ListViewItemSorter = (IComparer)new ListViewSorter(); + this.TimelineList.ListViewItemSorter = (IComparer)new ListViewSorter(); + this.Pages.Appearance = Crownwood.Magic.Controls.TabControl.VisualAppearance.MultiBox; + if (this.TopLevelControl is MainForm) + this.LinkList.SmallImageList = LabyrinthData.ElementImages; + this.fElement = e; + this.UpdateData(); + } + + protected override void Dispose(bool disposing) + { + if (disposing && this.components != null) + this.components.Dispose(); + base.Dispose(disposing); + } + + private void InitializeComponent() + { + this.components = (IContainer)new Container(); + ResourceManager resourceManager = new ResourceManager(typeof(ElementPage)); + this.ToolBar = new ToolBar(); + this.PropertiesBtn = new ToolBarButton(); + this.Sep1 = new ToolBarButton(); + this.AnnotationNewBtn = new ToolBarButton(); + this.ItemDeleteBtn = new ToolBarButton(); + this.ItemPropertiesBtn = new ToolBarButton(); + this.Sep2 = new ToolBarButton(); + this.MoveUpBtn = new ToolBarButton(); + this.MoveDownBtn = new ToolBarButton(); + this.FilterBtn = new ToolBarButton(); + this.Sep4 = new ToolBarButton(); + this.PrintBtn = new ToolBarButton(); + this.PrintPreviewBtn = new ToolBarButton(); + this.ExportBtn = new ToolBarButton(); + this.ToolbarImages = new ImageList(this.components); + this.Pages = new Crownwood.Magic.Controls.TabControl(); + this.ListImages = new ImageList(this.components); + this.AnnotationsPage = new Crownwood.Magic.Controls.TabPage(); + this.AnnotationPanel = new AnnotationPanel(); + this.AnnotationContextMenu = new ContextMenu(); + this.AnnotationNew = new MenuItem(); + this.AnnotationProperties = new MenuItem(); + this.AnnotationDelete = new MenuItem(); + this.Sep3 = new MenuItem(); + this.AnnotationMoveUp = new MenuItem(); + this.AnnotationMoveDown = new MenuItem(); + this.LinksPage = new Crownwood.Magic.Controls.TabPage(); + this.LinkList = new ListView(); + this.ElementHdr = new ColumnHeader(); + this.LinkTextHdr = new ColumnHeader(); + this.StructureHdr = new ColumnHeader(); + this.LinkContextMenu = new ContextMenu(); + this.LinkOpenElement = new MenuItem(); + this.LinkOpenStructure = new MenuItem(); + this.Sep5 = new MenuItem(); + this.LinkDeleteLink = new MenuItem(); + this.LinkLinkProperties = new MenuItem(); + this.TimelinePage = new Crownwood.Magic.Controls.TabPage(); + this.TimelineAnnotationPanel = new AnnotationPanel(); + this.TimelineSplitter = new Splitter(); + this.TimelineList = new ListView(); + this.TimelineHdr = new ColumnHeader(); + this.TimelineContextMenu = new ContextMenu(); + this.TimelineProperties = new MenuItem(); + this.TimelineDelete = new MenuItem(); + this.TimelineOpenTimeline = new MenuItem(); + this.AnnotationsPage.SuspendLayout(); + this.LinksPage.SuspendLayout(); + this.TimelinePage.SuspendLayout(); + this.SuspendLayout(); + this.ToolBar.Appearance = ToolBarAppearance.Flat; + this.ToolBar.Buttons.AddRange(new ToolBarButton[13] + { + this.PropertiesBtn, + this.Sep1, + this.AnnotationNewBtn, + this.ItemDeleteBtn, + this.ItemPropertiesBtn, + this.Sep2, + this.MoveUpBtn, + this.MoveDownBtn, + this.FilterBtn, + this.Sep4, + this.PrintBtn, + this.PrintPreviewBtn, + this.ExportBtn + }); + this.ToolBar.DropDownArrows = true; + this.ToolBar.ImageList = this.ToolbarImages; + this.ToolBar.Name = "ToolBar"; + this.ToolBar.ShowToolTips = true; + this.ToolBar.Size = new Size(336, 25); + this.ToolBar.TabIndex = 0; + this.ToolBar.ButtonDropDown += new ToolBarButtonClickEventHandler(this.ToolBar_ButtonDropDown); + this.ToolBar.ButtonClick += new ToolBarButtonClickEventHandler(this.ToolBar_ButtonClick); + this.PropertiesBtn.ImageIndex = 0; + this.PropertiesBtn.ToolTipText = "Element Properties"; + this.Sep1.Style = ToolBarButtonStyle.Separator; + this.AnnotationNewBtn.ImageIndex = 3; + this.AnnotationNewBtn.Style = ToolBarButtonStyle.DropDownButton; + this.AnnotationNewBtn.ToolTipText = "New Annotation"; + this.ItemDeleteBtn.ImageIndex = 4; + this.ItemDeleteBtn.ToolTipText = "Delete Annotation"; + this.ItemPropertiesBtn.ImageIndex = 0; + this.ItemPropertiesBtn.ToolTipText = "Annotation Properties"; + this.Sep2.Style = ToolBarButtonStyle.Separator; + this.MoveUpBtn.ImageIndex = 5; + this.MoveUpBtn.ToolTipText = "Move Up"; + this.MoveDownBtn.ImageIndex = 6; + this.MoveDownBtn.ToolTipText = "Move Down"; + this.FilterBtn.ImageIndex = 8; + this.FilterBtn.ToolTipText = "Filter"; + this.Sep4.Style = ToolBarButtonStyle.Separator; + this.PrintBtn.ImageIndex = 1; + this.PrintBtn.ToolTipText = "Print"; + this.PrintPreviewBtn.ImageIndex = 2; + this.PrintPreviewBtn.ToolTipText = "Print Preview"; + this.ExportBtn.ImageIndex = 7; + this.ExportBtn.ToolTipText = "Export"; + this.ToolbarImages.ColorDepth = ColorDepth.Depth8Bit; + this.ToolbarImages.ImageSize = new Size(16, 16); + this.ToolbarImages.ImageStream = (ImageListStreamer)resourceManager.GetObject("ToolbarImages.ImageStream"); + this.ToolbarImages.TransparentColor = Color.Magenta; + this.Pages.Dock = DockStyle.Fill; + this.Pages.HideTabsMode = Crownwood.Magic.Controls.TabControl.HideTabsModes.ShowAlways; + this.Pages.ImageList = this.ListImages; + this.Pages.Location = new Point(0, 25); + this.Pages.Name = "Pages"; + this.Pages.SelectedIndex = 0; + this.Pages.SelectedTab = this.AnnotationsPage; + this.Pages.Size = new Size(336, 207); + this.Pages.TabIndex = 1; + this.Pages.TabPages.AddRange(new Crownwood.Magic.Controls.TabPage[3] + { + this.AnnotationsPage, + this.LinksPage, + this.TimelinePage + }); + this.ListImages.ColorDepth = ColorDepth.Depth8Bit; + this.ListImages.ImageSize = new Size(16, 16); + this.ListImages.ImageStream = (ImageListStreamer)resourceManager.GetObject("ListImages.ImageStream"); + this.ListImages.TransparentColor = Color.Magenta; + this.AnnotationsPage.Controls.AddRange(new Control[1] + { + (Control) this.AnnotationPanel + }); + this.AnnotationsPage.ImageIndex = 0; + this.AnnotationsPage.Name = "AnnotationsPage"; + this.AnnotationsPage.Size = new Size(336, 182); + this.AnnotationsPage.TabIndex = 0; + this.AnnotationsPage.Title = "Annotations"; + this.AnnotationPanel.AllowDrop = true; + this.AnnotationPanel.ContextMenu = this.AnnotationContextMenu; + this.AnnotationPanel.Dock = DockStyle.Fill; + this.AnnotationPanel.Name = "AnnotationPanel"; + this.AnnotationPanel.SelectedAnnotation = (Annotation)null; + this.AnnotationPanel.SelectedIndex = -1; + this.AnnotationPanel.ShowFilter = false; + this.AnnotationPanel.Size = new Size(336, 182); + this.AnnotationPanel.TabIndex = 4; + this.AnnotationPanel.DragDrop += new DragEventHandler(this.AnnotationList_DragDrop); + this.AnnotationPanel.DoubleClick += new EventHandler(this.AnnotationPanel_DoubleClick); + this.AnnotationPanel.DragOver += new DragEventHandler(this.AnnotationList_DragOver); + this.AnnotationContextMenu.MenuItems.AddRange(new MenuItem[6] + { + this.AnnotationNew, + this.AnnotationProperties, + this.AnnotationDelete, + this.Sep3, + this.AnnotationMoveUp, + this.AnnotationMoveDown + }); + this.AnnotationContextMenu.Popup += new EventHandler(this.AnnotationContextMenu_Popup); + this.AnnotationNew.Index = 0; + this.AnnotationNew.Text = "New Annotation"; + this.AnnotationProperties.Index = 1; + this.AnnotationProperties.Text = "Open Annotation"; + this.AnnotationProperties.Click += new EventHandler(this.AnnotationProperties_Click); + this.AnnotationDelete.Index = 2; + this.AnnotationDelete.Shortcut = Shortcut.Del; + this.AnnotationDelete.Text = "Delete Annotation"; + this.AnnotationDelete.Click += new EventHandler(this.AnnotationDelete_Click); + this.Sep3.Index = 3; + this.Sep3.Text = "-"; + this.AnnotationMoveUp.Index = 4; + this.AnnotationMoveUp.Text = "Move Up"; + this.AnnotationMoveUp.Click += new EventHandler(this.AnnotationMoveUp_Click); + this.AnnotationMoveDown.Index = 5; + this.AnnotationMoveDown.Text = "Move Down"; + this.AnnotationMoveDown.Click += new EventHandler(this.AnnotationMoveDown_Click); + this.LinksPage.Controls.AddRange(new Control[1] + { + (Control) this.LinkList + }); + this.LinksPage.ImageIndex = 2; + this.LinksPage.Name = "LinksPage"; + this.LinksPage.Selected = false; + this.LinksPage.Size = new Size(336, 182); + this.LinksPage.TabIndex = 1; + this.LinksPage.Title = "Links"; + this.LinkList.Columns.AddRange(new ColumnHeader[3] + { + this.ElementHdr, + this.LinkTextHdr, + this.StructureHdr + }); + this.LinkList.ContextMenu = this.LinkContextMenu; + this.LinkList.Dock = DockStyle.Fill; + this.LinkList.FullRowSelect = true; + this.LinkList.Name = "LinkList"; + this.LinkList.Size = new Size(336, 182); + this.LinkList.SmallImageList = this.ListImages; + this.LinkList.Sorting = SortOrder.Ascending; + this.LinkList.TabIndex = 0; + this.LinkList.View = View.Details; + this.LinkList.MouseDown += new MouseEventHandler(this.LinkList_MouseDown); + this.LinkList.DoubleClick += new EventHandler(this.LinkList_DoubleClick); + this.LinkList.ColumnClick += new ColumnClickEventHandler(this.LinkList_ColumnClick); + this.ElementHdr.Text = "Element"; + this.ElementHdr.Width = 120; + this.LinkTextHdr.Text = "Link Text"; + this.LinkTextHdr.Width = 120; + this.StructureHdr.Text = "Structure"; + this.StructureHdr.Width = 90; + this.LinkContextMenu.MenuItems.AddRange(new MenuItem[5] + { + this.LinkOpenElement, + this.LinkOpenStructure, + this.Sep5, + this.LinkDeleteLink, + this.LinkLinkProperties + }); + this.LinkOpenElement.Index = 0; + this.LinkOpenElement.Text = "Open Element"; + this.LinkOpenElement.Click += new EventHandler(this.LinkOpenElement_Click); + this.LinkOpenStructure.Index = 1; + this.LinkOpenStructure.Text = "Open Structure"; + this.LinkOpenStructure.Click += new EventHandler(this.LinkOpenStructure_Click); + this.Sep5.Index = 2; + this.Sep5.Text = "-"; + this.LinkDeleteLink.Index = 3; + this.LinkDeleteLink.Text = "Delete Link"; + this.LinkDeleteLink.Click += new EventHandler(this.LinkDeleteLink_Click); + this.LinkLinkProperties.Index = 4; + this.LinkLinkProperties.Text = "Link Properties"; + this.LinkLinkProperties.Click += new EventHandler(this.LinkLinkProperties_Click); + this.TimelinePage.Controls.AddRange(new Control[3] + { + (Control) this.TimelineAnnotationPanel, + (Control) this.TimelineSplitter, + (Control) this.TimelineList + }); + this.TimelinePage.ImageIndex = 1; + this.TimelinePage.Name = "TimelinePage"; + this.TimelinePage.Selected = false; + this.TimelinePage.Size = new Size(336, 182); + this.TimelinePage.TabIndex = 2; + this.TimelinePage.Title = "Timelines"; + this.TimelineAnnotationPanel.Dock = DockStyle.Fill; + this.TimelineAnnotationPanel.Location = new Point(115, 0); + this.TimelineAnnotationPanel.Name = "TimelineAnnotationPanel"; + this.TimelineAnnotationPanel.SelectedAnnotation = (Annotation)null; + this.TimelineAnnotationPanel.SelectedIndex = -1; + this.TimelineAnnotationPanel.ShowFilter = false; + this.TimelineAnnotationPanel.Size = new Size(221, 182); + this.TimelineAnnotationPanel.TabIndex = 4; + this.TimelineAnnotationPanel.DoubleClick += new EventHandler(this.TimelineAnnotationList_DoubleClick); + this.TimelineSplitter.Location = new Point(112, 0); + this.TimelineSplitter.Name = "TimelineSplitter"; + this.TimelineSplitter.Size = new Size(3, 182); + this.TimelineSplitter.TabIndex = 1; + this.TimelineSplitter.TabStop = false; + this.TimelineList.Columns.AddRange(new ColumnHeader[1] + { + this.TimelineHdr + }); + this.TimelineList.Dock = DockStyle.Left; + this.TimelineList.FullRowSelect = true; + this.TimelineList.Name = "TimelineList"; + this.TimelineList.Size = new Size(112, 182); + this.TimelineList.SmallImageList = this.ListImages; + this.TimelineList.Sorting = SortOrder.Ascending; + this.TimelineList.TabIndex = 0; + this.TimelineList.View = View.Details; + this.TimelineList.MouseDown += new MouseEventHandler(this.TimelineList_MouseDown); + this.TimelineList.DoubleClick += new EventHandler(this.TimelineList_DoubleClick); + this.TimelineList.ColumnClick += new ColumnClickEventHandler(this.TimelineList_ColumnClick); + this.TimelineList.SelectedIndexChanged += new EventHandler(this.TimelineList_SelectedIndexChanged); + this.TimelineHdr.Text = "Timeline"; + this.TimelineHdr.Width = 90; + this.TimelineContextMenu.MenuItems.AddRange(new MenuItem[3] + { + this.TimelineProperties, + this.TimelineDelete, + this.TimelineOpenTimeline + }); + this.TimelineProperties.Index = 0; + this.TimelineProperties.Text = "Open Annotation"; + this.TimelineProperties.Click += new EventHandler(this.TimelineProperties_Click); + this.TimelineDelete.Index = 1; + this.TimelineDelete.Text = "Delete Annotation"; + this.TimelineDelete.Click += new EventHandler(this.TimelineDelete_Click); + this.TimelineOpenTimeline.Index = 2; + this.TimelineOpenTimeline.Text = "Open Timeline"; + this.TimelineOpenTimeline.Click += new EventHandler(this.TimelineOpenTimeline_Click); + this.Controls.AddRange(new Control[2] + { + (Control) this.Pages, + (Control) this.ToolBar + }); + this.Font = new Font("Tahoma", 11f, FontStyle.Regular, GraphicsUnit.World); + this.Name = nameof(ElementPage); + this.Size = new Size(336, 232); + this.AnnotationsPage.ResumeLayout(false); + this.LinksPage.ResumeLayout(false); + this.TimelinePage.ResumeLayout(false); + this.ResumeLayout(false); + } + + public string Title + { + get + { + return this.fElement.Name; + } + } + + public bool IsObsolete + { + get + { + return LabyrinthData.Project.Elements.IndexOf(this.fElement) == -1; + } + } + + public void UpdateUI() + { + if (this.Pages.SelectedTab == this.AnnotationsPage) + { + bool flag1 = this.AnnotationPanel.SelectedAnnotation != null; + bool flag2 = this.AnnotationPanel.SelectedIndex == 0; + bool flag3 = this.AnnotationPanel.SelectedIndex == this.AnnotationPanel.Annotations.Count - 1; + this.AnnotationNew.Enabled = true; + this.AnnotationDelete.Enabled = flag1; + this.AnnotationProperties.Enabled = flag1; + this.AnnotationMoveUp.Enabled = flag1 && !flag2 && !this.AnnotationPanel.FilterApplied; + this.AnnotationMoveDown.Enabled = flag1 && !flag3 && !this.AnnotationPanel.FilterApplied; + this.PropertiesBtn.Enabled = true; + this.AnnotationNewBtn.Enabled = this.AnnotationNew.Enabled; + this.ItemDeleteBtn.Enabled = this.AnnotationDelete.Enabled; + this.ItemPropertiesBtn.Enabled = this.AnnotationProperties.Enabled; + this.MoveUpBtn.Enabled = this.AnnotationMoveUp.Enabled; + this.MoveDownBtn.Enabled = this.AnnotationMoveDown.Enabled; + this.FilterBtn.Enabled = true; + this.FilterBtn.Pushed = this.AnnotationPanel.ShowFilter; + this.ExportBtn.Enabled = true; + } + else if (this.Pages.SelectedTab == this.LinksPage) + { + this.LinkOpenElement.Enabled = this.SelectedLink != null; + this.LinkOpenStructure.Enabled = this.SelectedLink != null; + this.LinkDeleteLink.Enabled = this.SelectedLink != null; + this.LinkLinkProperties.Enabled = this.SelectedLink != null; + this.PropertiesBtn.Enabled = true; + this.AnnotationNewBtn.Enabled = false; + this.ItemDeleteBtn.Enabled = this.LinkDeleteLink.Enabled; + this.ItemPropertiesBtn.Enabled = this.LinkLinkProperties.Enabled; + this.MoveUpBtn.Enabled = false; + this.MoveDownBtn.Enabled = false; + this.FilterBtn.Enabled = false; + this.FilterBtn.Pushed = false; + this.ExportBtn.Enabled = true; + } + else + { + if (this.Pages.SelectedTab != this.TimelinePage) + return; + bool flag = this.TimelineAnnotationPanel.SelectedAnnotation != null; + this.TimelineDelete.Enabled = flag; + this.TimelineProperties.Enabled = flag; + this.TimelineOpenTimeline.Enabled = this.SelectedTimeline != null; + this.PropertiesBtn.Enabled = true; + this.AnnotationNewBtn.Enabled = false; + this.ItemDeleteBtn.Enabled = this.TimelineDelete.Enabled; + this.ItemPropertiesBtn.Enabled = this.TimelineProperties.Enabled; + this.MoveUpBtn.Enabled = false; + this.MoveDownBtn.Enabled = false; + this.FilterBtn.Enabled = true; + this.FilterBtn.Pushed = this.TimelineAnnotationPanel.ShowFilter; + this.ExportBtn.Enabled = this.SelectedTimeline != null; + } + } + + public void UpdateData() + { + this.update_annotations(); + this.update_timelines(); + this.update_links(); + } + + public Element Element + { + get + { + return this.fElement; + } + } + + public Annotation SelectedAnnotation + { + get + { + return this.AnnotationPanel.SelectedAnnotation; + } + } + + public Annotation SelectedTimelineAnnotation + { + get + { + return this.TimelineAnnotationPanel.SelectedAnnotation; + } + } + + public Timeline SelectedTimeline + { + get + { + if (this.TimelineList.SelectedItems.Count != 0) + return this.TimelineList.SelectedItems[0].Tag as Timeline; + return (Timeline)null; + } + } + + public Labyrinth.Plot.Link SelectedLink + { + get + { + if (this.LinkList.SelectedItems.Count != 0) + return this.LinkList.SelectedItems[0].Tag as Labyrinth.Plot.Link; + return (Labyrinth.Plot.Link)null; + } + } + + public event ElementEventHandler ElementModified; + + public event ElementEventHandler ElementActivated; + + public event TimelineEventHandler TimelineModified; + + public event TimelineEventHandler TimelineActivated; + + public event StructureEventHandler StructureActivated; + + public event StructureEventHandler StructureModified; + + protected void OnElementModified(ElementEventArgs e) + { + try + { + if (this.ElementModified == null) + return; + this.ElementModified((object)this, e); + } + catch (Exception ex) + { + LabyrinthData.Log((object)ex); + } + } + + protected void OnElementActivated(ElementEventArgs e) + { + try + { + if (this.ElementActivated == null) + return; + this.ElementActivated((object)this, e); + } + catch (Exception ex) + { + LabyrinthData.Log((object)ex); + } + } + + protected void OnTimelineModified(TimelineEventArgs e) + { + try + { + if (this.TimelineModified == null) + return; + this.TimelineModified((object)this, e); + } + catch (Exception ex) + { + LabyrinthData.Log((object)ex); + } + } + + protected void OnTimelineActivated(TimelineEventArgs e) + { + try + { + if (this.TimelineActivated == null) + return; + this.TimelineActivated((object)this, e); + } + catch (Exception ex) + { + LabyrinthData.Log((object)ex); + } + } + + protected void OnStructureActivated(StructureEventArgs e) + { + try + { + if (this.StructureActivated == null) + return; + this.StructureActivated((object)this, e); + } + catch (Exception ex) + { + LabyrinthData.Log((object)ex); + } + } + + protected void OnStructureModified(StructureEventArgs e) + { + try + { + if (this.StructureModified == null) + return; + this.StructureModified((object)this, e); + } + catch (Exception ex) + { + LabyrinthData.Log((object)ex); + } + } + + private void ToolBar_ButtonClick(object sender, ToolBarButtonClickEventArgs e) + { + try + { + if (e.Button == this.PropertiesBtn) + { + if (new ElementDlg(this.fElement).ShowDialog() != DialogResult.OK) + return; + this.UpdateData(); + this.OnElementModified(new ElementEventArgs(this.fElement)); + } + else if (e.Button == this.AnnotationNewBtn) + this.AnnotationNewText_Click(sender, (EventArgs)e); + else if (e.Button == this.ItemDeleteBtn) + { + if (this.Pages.SelectedTab == this.AnnotationsPage) + this.AnnotationDelete_Click(sender, (EventArgs)e); + else if (this.Pages.SelectedTab == this.LinksPage) + { + this.LinkDeleteLink_Click(sender, (EventArgs)e); + } + else + { + if (this.Pages.SelectedTab != this.TimelinePage) + return; + this.TimelineDelete_Click(sender, (EventArgs)e); + } + } + else if (e.Button == this.ItemPropertiesBtn) + { + if (this.Pages.SelectedTab == this.AnnotationsPage) + this.AnnotationProperties_Click(sender, (EventArgs)e); + else if (this.Pages.SelectedTab == this.LinksPage) + { + this.LinkLinkProperties_Click(sender, (EventArgs)e); + } + else + { + if (this.Pages.SelectedTab != this.TimelinePage) + return; + this.TimelineProperties_Click(sender, (EventArgs)e); + } + } + else if (e.Button == this.MoveUpBtn) + this.AnnotationMoveUp_Click(sender, (EventArgs)e); + else if (e.Button == this.MoveDownBtn) + this.AnnotationMoveDown_Click(sender, (EventArgs)e); + else if (e.Button == this.FilterBtn) + { + if (this.Pages.SelectedTab == this.AnnotationsPage) + { + this.AnnotationPanel.ShowFilter = !this.AnnotationPanel.ShowFilter; + } + else + { + if (this.Pages.SelectedTab == this.LinksPage || this.Pages.SelectedTab != this.TimelinePage) + return; + this.TimelineAnnotationPanel.ShowFilter = !this.TimelineAnnotationPanel.ShowFilter; + } + } + else if (e.Button == this.ExportBtn) + { + string str1 = "HTML Files|*.html|Text Files|*.txt"; + try + { + string str2 = this.fElement.Name; + if (this.Pages.SelectedTab == this.TimelinePage && this.SelectedTimeline != null) + str2 = str2 + " " + this.SelectedTimeline.Name; + SaveFileDialog saveFileDialog = new SaveFileDialog(); + saveFileDialog.FileName = str2; + saveFileDialog.Filter = str1; + if (saveFileDialog.ShowDialog() != DialogResult.OK) + return; + bool markup = saveFileDialog.FilterIndex == 1; + string str3 = ""; + if (this.Pages.SelectedTab == this.AnnotationsPage) + str3 = this.export_annotations(markup); + else if (this.Pages.SelectedTab == this.LinksPage) + str3 = this.export_links(markup); + else if (this.Pages.SelectedTab == this.TimelinePage) + str3 = this.export_timeline_annotations(markup); + StreamWriter text = File.CreateText(saveFileDialog.FileName); + text.WriteLine(str3); + text.Close(); + } + catch (Exception ex) + { + LabyrinthData.Log((object)ex); + } + } + else if (e.Button == this.PrintBtn) + { + this.print(false); + } + else + { + if (e.Button != this.PrintPreviewBtn) + return; + this.print(true); + } + } + catch (Exception ex) + { + LabyrinthData.Log((object)ex); + } + } + + private void ToolBar_ButtonDropDown(object sender, ToolBarButtonClickEventArgs e) + { + try + { + if (e.Button != this.AnnotationNewBtn) + return; + ContextMenu contextMenu = new ContextMenu(); + contextMenu.MenuItems.AddRange(this.get_annotation_submenu()); + Rectangle rectangle = this.AnnotationNewBtn.Rectangle; + int x = rectangle.X; + rectangle = this.AnnotationNewBtn.Rectangle; + int y1 = rectangle.Y; + rectangle = this.AnnotationNewBtn.Rectangle; + int height = rectangle.Height; + int y2 = y1 + height; + contextMenu.Show((Control)this.ToolBar, new Point(x, y2)); + } + catch (Exception ex) + { + LabyrinthData.Log((object)ex); + } + } + + private void TimelineList_SelectedIndexChanged(object sender, EventArgs e) + { + this.update_timeline_annotations(); + } + + private void TimelineList_DoubleClick(object sender, EventArgs e) + { + if (this.SelectedTimeline == null) + return; + this.TimelineOpenTimeline_Click(sender, e); + } + + private void AnnotationDelete_Click(object sender, EventArgs e) + { + if (this.AnnotationPanel.SelectedAnnotation == null || MessageBox.Show("Delete annotation '" + this.AnnotationPanel.SelectedAnnotation.Title + "': are you sure?", "Labyrinth", MessageBoxButtons.YesNo, MessageBoxIcon.Question) != DialogResult.Yes) + return; + this.fElement.Annotations.Remove(this.AnnotationPanel.SelectedAnnotation); + this.update_annotations(); + this.OnElementModified(new ElementEventArgs(this.fElement)); + } + + private void AnnotationProperties_Click(object sender, EventArgs e) + { + if (this.AnnotationPanel.SelectedAnnotation == null) + return; + Annotation selectedAnnotation = this.AnnotationPanel.SelectedAnnotation; + if (!Annotations.Open(selectedAnnotation)) + return; + this.update_annotations(); + this.OnElementModified(new ElementEventArgs(this.fElement)); + this.AnnotationPanel.SelectedAnnotation = selectedAnnotation; + } + + private void AnnotationMoveUp_Click(object sender, EventArgs e) + { + if (this.AnnotationPanel.SelectedAnnotation == null) + return; + Annotation selectedAnnotation = this.AnnotationPanel.SelectedAnnotation; + int index = this.fElement.Annotations.IndexOf(selectedAnnotation); + switch (index) + { + case -1: + break; + + case 0: + break; + + default: + Annotation annotation = this.fElement.Annotations[index - 1]; + this.fElement.Annotations[index - 1] = this.fElement.Annotations[index]; + this.fElement.Annotations[index] = annotation; + this.update_annotations(); + this.OnElementModified(new ElementEventArgs(this.fElement)); + this.AnnotationPanel.SelectedAnnotation = selectedAnnotation; + break; + } + } + + private void AnnotationMoveDown_Click(object sender, EventArgs e) + { + if (this.AnnotationPanel.SelectedAnnotation == null) + return; + Annotation selectedAnnotation = this.AnnotationPanel.SelectedAnnotation; + int index = this.fElement.Annotations.IndexOf(selectedAnnotation); + if (index == -1 || index == this.AnnotationPanel.Annotations.Count - 1) + return; + Annotation annotation = this.fElement.Annotations[index + 1]; + this.fElement.Annotations[index + 1] = this.fElement.Annotations[index]; + this.fElement.Annotations[index] = annotation; + this.update_annotations(); + this.OnElementModified(new ElementEventArgs(this.fElement)); + this.AnnotationPanel.SelectedAnnotation = selectedAnnotation; + } + + private void TimelineDelete_Click(object sender, EventArgs e) + { + if (this.TimelineAnnotationPanel.SelectedAnnotation == null || MessageBox.Show("Delete annotation '" + this.TimelineAnnotationPanel.SelectedAnnotation.Title + "': are you sure?", "Labyrinth", MessageBoxButtons.YesNo, MessageBoxIcon.Question) != DialogResult.Yes) + return; + Timeline tl = (Timeline)null; + TimelinePoint timelinePoint = (TimelinePoint)null; + TimelineItem timelineItem1 = (TimelineItem)null; + foreach (Timeline timeline in LabyrinthData.Project.Timelines) + { + foreach (TimelinePoint point in timeline.Points) + { + foreach (TimelineItem timelineItem2 in point.Items) + { + if (timelineItem2.Annotation.ID == this.TimelineAnnotationPanel.SelectedAnnotation.ID) + { + tl = timeline; + timelinePoint = point; + timelineItem1 = timelineItem2; + break; + } + } + } + } + if (timelineItem1 == null) + return; + timelinePoint.Items.Remove(timelineItem1); + this.update_timelines(); + this.OnTimelineModified(new TimelineEventArgs(tl)); + } + + private void TimelineProperties_Click(object sender, EventArgs e) + { + if (this.TimelineAnnotationPanel.SelectedAnnotation == null) + return; + Annotation selectedAnnotation = this.TimelineAnnotationPanel.SelectedAnnotation; + if (!Annotations.Open(selectedAnnotation)) + return; + this.update_timelines(); + this.OnTimelineModified(new TimelineEventArgs(this.SelectedTimeline)); + this.TimelineAnnotationPanel.SelectedAnnotation = selectedAnnotation; + } + + private void TimelineOpenTimeline_Click(object sender, EventArgs e) + { + if (this.SelectedTimeline == null) + return; + this.OnTimelineActivated(new TimelineEventArgs(this.SelectedTimeline)); + } + + private void LinkOpenElement_Click(object sender, EventArgs e) + { + if (this.SelectedLink == null) + return; + int index = LabyrinthData.Project.Elements.IndexOf(this.SelectedLink.LHS != this.fElement.ID ? this.SelectedLink.LHS : this.SelectedLink.RHS); + if (index == -1) + return; + this.OnElementActivated(new ElementEventArgs(LabyrinthData.Project.Elements[index])); + } + + private void LinkOpenStructure_Click(object sender, EventArgs e) + { + if (this.SelectedLink == null) + return; + Structure structureContaining = this.get_structure_containing(this.SelectedLink); + if (structureContaining == null) + return; + this.OnStructureActivated(new StructureEventArgs(structureContaining)); + } + + private void LinkDeleteLink_Click(object sender, EventArgs e) + { + if (this.SelectedLink == null || MessageBox.Show("Delete link '" + this.SelectedLink.Description + "': are you sure?", "Labyrinth", MessageBoxButtons.YesNo, MessageBoxIcon.Question) != DialogResult.Yes) + return; + Structure structureContaining = this.get_structure_containing(this.SelectedLink); + structureContaining.Links.Remove(this.SelectedLink); + this.update_links(); + this.OnStructureModified(new StructureEventArgs(structureContaining)); + } + + private void LinkLinkProperties_Click(object sender, EventArgs e) + { + if (this.SelectedLink == null) + return; + Structure structureContaining = this.get_structure_containing(this.SelectedLink); + if (new LinkDlg(this.SelectedLink).ShowDialog() != DialogResult.OK) + return; + this.update_links(); + this.OnStructureModified(new StructureEventArgs(structureContaining)); + } + + private void update_annotations() + { + this.AnnotationPanel.Annotations = this.fElement.Annotations; + } + + private void update_timelines() + { + this.TimelineList.BeginUpdate(); + this.TimelineList.Items.Clear(); + if (this.fElement != null) + { + ArrayList arrayList = new ArrayList(); + foreach (Timeline timeline in LabyrinthData.Project.Timelines) + { + if (timeline.ElementIDs.Contains(this.fElement.ID)) + arrayList.Add((object)new ListViewItem(timeline.Name) + { + ImageIndex = 1, + Tag = (object)timeline + }); + } + this.TimelineList.Items.AddRange((ListViewItem[])arrayList.ToArray(typeof(ListViewItem))); + } + if (this.TimelineList.Items.Count == 0) + { + ListViewItem listViewItem = this.TimelineList.Items.Add("No timelines"); + listViewItem.ImageIndex = -1; + listViewItem.ForeColor = SystemColors.GrayText; + } + this.TimelineList.EndUpdate(); + } + + private void update_timeline_annotations() + { + var annotationCollection = new List(); + if (this.SelectedTimeline != null) + { + foreach (TimelinePoint point in this.SelectedTimeline.Points) + { + foreach (TimelineItem timelineItem in point.Items) + { + if (timelineItem.ElementID == this.fElement.ID) + annotationCollection.Add((Annotation)timelineItem.Annotation); + } + } + } + this.TimelineAnnotationPanel.Annotations = annotationCollection; + } + + private void update_links() + { + this.LinkList.BeginUpdate(); + this.LinkList.Items.Clear(); + ArrayList arrayList = new ArrayList(); + foreach (Structure structure in LabyrinthData.Project.Structures) + { + foreach (Labyrinth.Plot.Link link in structure.Links) + { + if (link.LHS == this.fElement.ID || link.RHS == this.fElement.ID) + { + int index = LabyrinthData.Project.Elements.IndexOf(link.LHS != this.fElement.ID ? link.LHS : link.RHS); + if (index != -1) + arrayList.Add((object)new ListViewItem(LabyrinthData.Project.Elements[index].Name) + { + SubItems = { + link.Description, + structure.Name + }, + ImageIndex = 2, + Tag = (object)link + }); + } + } + } + this.LinkList.Items.AddRange((ListViewItem[])arrayList.ToArray(typeof(ListViewItem))); + if (this.LinkList.Items.Count == 0) + { + ListViewItem listViewItem = this.LinkList.Items.Add("No links"); + listViewItem.ImageIndex = -1; + listViewItem.ForeColor = SystemColors.GrayText; + } + this.LinkList.EndUpdate(); + } + + private Structure get_structure_containing(Labyrinth.Plot.Link l) + { + foreach (Structure structure in LabyrinthData.Project.Structures) + { + if (structure.Links.Contains(l)) + return structure; + } + return (Structure)null; + } + + private void TimelineList_MouseDown(object sender, MouseEventArgs e) + { + this.TimelineList.SelectedItems.Clear(); + ListViewItem itemAt = this.TimelineList.GetItemAt(e.X, e.Y); + if (itemAt != null) + itemAt.Selected = true; + this.UpdateUI(); + } + + private void LinkList_MouseDown(object sender, MouseEventArgs e) + { + this.LinkList.SelectedItems.Clear(); + ListViewItem itemAt = this.LinkList.GetItemAt(e.X, e.Y); + if (itemAt != null) + itemAt.Selected = true; + this.UpdateUI(); + } + + private void LinkList_DoubleClick(object sender, EventArgs e) + { + if (this.SelectedLink == null) + return; + this.LinkOpenElement_Click(sender, e); + } + + private void TimelineAnnotationList_DoubleClick(object sender, EventArgs e) + { + if (this.TimelineAnnotationPanel.SelectedAnnotation == null) + return; + this.TimelineProperties_Click(sender, e); + } + + private string export_annotations(bool markup) + { + string str1 = ""; + string title = "Annotations for " + this.fElement.Name; + if (markup) + str1 = str1 + "" + Environment.NewLine + LabyrinthData.HTMLHeader(title) + Environment.NewLine + "" + Environment.NewLine; + if (markup) + str1 += "

"; + string str2 = str1 + title; + if (markup) + str2 += "

"; + string str3 = str2 + Environment.NewLine; + foreach (Annotation annotation in this.AnnotationPanel.Annotations) + { + str3 += Environment.NewLine; + str3 = str3 + this.annotation_to_string(annotation.Title, annotation.Content, markup) + Environment.NewLine; + } + if (markup) + str3 = str3 + "" + Environment.NewLine + "" + Environment.NewLine; + return str3; + } + + private string export_timeline_annotations(bool markup) + { + string str1 = ""; + string title1 = "Annotations for " + this.fElement.Name + " in " + this.SelectedTimeline.Name; + if (markup) + str1 = str1 + "" + Environment.NewLine + LabyrinthData.HTMLHeader(title1) + Environment.NewLine + "" + Environment.NewLine; + if (markup) + str1 += "

"; + string str2 = str1 + title1; + if (markup) + str2 += "

"; + string str3 = str2 + Environment.NewLine; + foreach (Annotation annotation in this.TimelineAnnotationPanel.Annotations) + { + TimelinePoint timelinePoint = (TimelinePoint)null; + foreach (TimelinePoint point in this.SelectedTimeline.Points) + { + foreach (TimelineItem timelineItem in point.Items) + { + if (timelineItem.Annotation == annotation) + { + timelinePoint = point; + break; + } + } + } + str3 += Environment.NewLine; + string title2 = timelinePoint.Name + ": " + annotation.Title; + str3 = str3 + this.annotation_to_string(title2, annotation.Content, markup) + Environment.NewLine; + } + if (markup) + str3 = str3 + "" + Environment.NewLine + "" + Environment.NewLine; + return str3; + } + + private string annotation_to_string(string title, string content, bool markup) + { + string str1 = ""; + if (markup) + str1 = str1 + "

" + Environment.NewLine; + string str2 = str1 + title + Environment.NewLine; + if (markup) + str2 = str2 + "

" + Environment.NewLine; + if (markup) + str2 = str2 + "

" + Environment.NewLine; + string str3 = str2 + (markup ? content.Replace("\n", "
") : content) + Environment.NewLine; + if (markup) + str3 += "

"; + return str3; + } + + private string export_links(bool markup) + { + string str1 = ""; + string title = "Links for " + this.fElement.Name; + if (markup) + str1 = str1 + "" + Environment.NewLine + LabyrinthData.HTMLHeader(title) + Environment.NewLine + "" + Environment.NewLine; + if (markup) + str1 += "

"; + string str2 = str1 + title; + if (markup) + str2 += "

"; + string str3 = str2 + Environment.NewLine; + if (markup) + str3 = str3 + "" + Environment.NewLine + "" + Environment.NewLine + "" + Environment.NewLine + "" + Environment.NewLine + "" + Environment.NewLine + "" + Environment.NewLine; + foreach (ListViewItem listViewItem in this.LinkList.Items) + { + Labyrinth.Plot.Link tag = listViewItem.Tag as Labyrinth.Plot.Link; + if (tag != null) + { + Element element = LabyrinthData.Project.Elements[LabyrinthData.Project.Elements.IndexOf(tag.LHS == this.fElement.ID ? tag.RHS : tag.LHS)]; + Structure structure1 = (Structure)null; + foreach (Structure structure2 in LabyrinthData.Project.Structures) + { + if (structure2.Links.Contains(tag)) + { + structure1 = structure2; + break; + } + } + if (markup) + { + str3 = str3 + "" + Environment.NewLine; + str3 = str3 + "" + Environment.NewLine; + str3 = str3 + "" + Environment.NewLine; + str3 = str3 + "" + Environment.NewLine; + str3 = str3 + "" + Environment.NewLine; + } + else + { + str3 += Environment.NewLine; + str3 = str3 + element.Name + "\t" + tag.Description + "\t" + structure1.Name; + } + } + } + if (markup) + str3 = str3 + "" + Environment.NewLine + "" + Environment.NewLine; + return str3; + } + + private void print(bool preview) + { + PrintDocument printDocument = new PrintDocument(); + printDocument.DocumentName = LabyrinthData.Project.Name + ": " + this.fElement.Name; + printDocument.PrintController = (PrintController)new StandardPrintController(); + printDocument.DefaultPageSettings = LabyrinthData.PageSettings; + printDocument.PrinterSettings = LabyrinthData.PrinterSettings; + printDocument.PrintPage += new PrintPageEventHandler(this.PrintPage); + this.fItemsToPrint.Clear(); + if (this.Pages.SelectedTab == this.AnnotationsPage) + { + this.fItemsToPrint.AddRange((ICollection)this.fElement.Annotations); + printDocument.DocumentName += " (annotations)"; + } + else if (this.Pages.SelectedTab == this.LinksPage) + { + foreach (ListViewItem listViewItem in this.LinkList.Items) + this.fItemsToPrint.Add(listViewItem.Tag); + printDocument.DocumentName += " (links)"; + } + else if (this.Pages.SelectedTab == this.TimelinePage) + { + this.fItemsToPrint.AddRange((ICollection)this.TimelineAnnotationPanel.Annotations); + printDocument.DocumentName += " (timeline annotations)"; + } + if (preview) + { + int num = (int)new PrintPreviewDialog() + { + Document = printDocument + }.ShowDialog(); + } + else + { + PrintDialog printDialog = new PrintDialog(); + printDialog.Document = printDocument; + if (printDialog.ShowDialog() != DialogResult.OK) + return; + for (int index = 0; index != (int)printDialog.PrinterSettings.Copies; ++index) + printDialog.Document.Print(); + } + } + + private void PrintPage(object sender, PrintPageEventArgs e) + { + int num1 = 0; + Font font = new Font(this.Font, this.Font.Style); + while (this.fItemsToPrint.Count != 0) + { + TextAnnotation textAnnotation = this.fItemsToPrint[0] as TextAnnotation; + Labyrinth.Plot.Link l = this.fItemsToPrint[0] as Labyrinth.Plot.Link; + int num2 = 0; + if (textAnnotation != null) + num2 = this.measure_annotation((Annotation)textAnnotation, e.Graphics, e.MarginBounds.Width, font); + else if (l != null) + num2 = this.measure_link(l, e.Graphics, e.MarginBounds.Width, font); + if (num2 > e.MarginBounds.Height - num1) + { + if (num1 == 0) + { + float emSize = font.SizeInPoints * (float)e.MarginBounds.Height / (float)num2; + font = new Font(font.FontFamily, emSize); + } + else + break; + } + Rectangle rect; + int x = e.MarginBounds.X; + int num3 = num1; + Rectangle marginBounds = e.MarginBounds; + int y1 = marginBounds.Y; + int y2 = num3 + y1; + marginBounds = e.MarginBounds; + int width = marginBounds.Width; + int height = num2; + rect = new Rectangle(x, y2, width, height); + num1 = num1 + num2 + this.Font.Height; + if (textAnnotation != null) + this.render_annotation((Annotation)textAnnotation, e.Graphics, font, rect); + else if (l != null) + this.render_link(l, e.Graphics, font, rect); + this.fItemsToPrint.RemoveAt(0); + } + e.HasMorePages = this.fItemsToPrint.Count != 0; + } + + private int measure_annotation(Annotation a, Graphics g, int width, Font font) + { + Font font1 = new Font(font, font.Style | FontStyle.Bold); + return (int)((double)g.MeasureString(a.Title, font1, width).Height + (double)g.MeasureString(a.Content, font, width).Height); + } + + private void render_annotation(Annotation a, Graphics g, Font f, Rectangle rect) + { + Brush windowText = SystemBrushes.WindowText; + StringFormat format = new StringFormat(); + format.Trimming = StringTrimming.EllipsisWord; + Font font = new Font(f, f.Style | FontStyle.Bold); + float height = g.MeasureString(a.Title, font, rect.Width, format).Height; + g.DrawString(a.Title, font, windowText, (RectangleF)rect, format); + rect.Y += (int)height; + rect.Height -= (int)height; + g.DrawString(a.Content, f, windowText, (RectangleF)rect, format); + } + + private int measure_link(Labyrinth.Plot.Link l, Graphics g, int width, Font font) + { + string text = LabyrinthData.Project.Elements[LabyrinthData.Project.Elements.IndexOf(l.LHS)].Name + ", " + LabyrinthData.Project.Elements[LabyrinthData.Project.Elements.IndexOf(l.RHS)].Name; + Structure structure1 = null; + foreach (Structure structure2 in LabyrinthData.Project.Structures) + { + if (structure2.Links.Contains(l)) + { + structure1 = structure2; + break; + } + } + return (int)Math.Max(Math.Max(g.MeasureString(text, font, width / 2).Height, g.MeasureString(l.Description, font, width / 4).Height), g.MeasureString(structure1.Name, font, width / 4).Height); + } + + private void render_link(Labyrinth.Plot.Link l, Graphics g, Font f, Rectangle rect) + { + string s = LabyrinthData.Project.Elements[LabyrinthData.Project.Elements.IndexOf(l.LHS)].Name + ", " + LabyrinthData.Project.Elements[LabyrinthData.Project.Elements.IndexOf(l.RHS)].Name; + Structure structure1 = (Structure)null; + foreach (Structure structure2 in LabyrinthData.Project.Structures) + { + if (structure2.Links.Contains(l)) + { + structure1 = structure2; + break; + } + } + Rectangle rectangle1 = new Rectangle(rect.X, rect.Y, rect.Width / 2, rect.Height); + Rectangle rectangle2 = new Rectangle(rectangle1.X + rectangle1.Width, rect.Y, rect.Width / 4, rect.Height); + Rectangle rectangle3 = new Rectangle(rectangle2.X + rectangle2.Width, rect.Y, rect.Width / 4, rect.Height); + g.DrawString(s, this.Font, SystemBrushes.WindowText, (RectangleF)rectangle1); + g.DrawString(l.Description, this.Font, SystemBrushes.WindowText, (RectangleF)rectangle2); + g.DrawString(structure1.Name, this.Font, SystemBrushes.WindowText, (RectangleF)rectangle3); + } + + private void AnnotationPanel_DoubleClick(object sender, EventArgs e) + { + if (this.AnnotationPanel.SelectedAnnotation != null) + this.AnnotationProperties_Click(sender, e); + else + this.AnnotationNewText_Click(sender, e); + } + + private void AnnotationList_DragOver(object sender, DragEventArgs e) + { + e.Effect = DragDropEffects.None; + if (e.Data.GetDataPresent(DataFormats.Text)) + e.Effect = DragDropEffects.Copy; + if (!e.Data.GetDataPresent(DataFormats.FileDrop)) + return; + e.Effect = DragDropEffects.Link; + } + + private void AnnotationList_DragDrop(object sender, DragEventArgs e) + { + if (e.Data.GetDataPresent(DataFormats.Rtf)) + { + string data1 = e.Data.GetData(DataFormats.Rtf) as string; + string data2 = e.Data.GetData(typeof(string)) as string; + TextAnnotation textAnnotation = new TextAnnotation(); + textAnnotation.Title = "New Annotation"; + textAnnotation.Content = data2; + textAnnotation.RTF = data1; + this.fElement.Annotations.Add((Annotation)textAnnotation); + this.update_annotations(); + this.OnElementModified(new ElementEventArgs(this.fElement)); + } + else if (e.Data.GetDataPresent(typeof(string))) + { + string data = e.Data.GetData(typeof(string)) as string; + TextAnnotation textAnnotation = new TextAnnotation(); + textAnnotation.Title = "New Annotation"; + textAnnotation.Content = data; + this.fElement.Annotations.Add((Annotation)textAnnotation); + this.update_annotations(); + this.OnElementModified(new ElementEventArgs(this.fElement)); + } + else + { + if (!e.Data.GetDataPresent(DataFormats.FileDrop)) + return; + foreach (string str in e.Data.GetData(DataFormats.FileDrop) as string[]) + { + LinkAnnotation linkAnnotation = new LinkAnnotation(); + linkAnnotation.Content = str; + this.fElement.Annotations.Add((Annotation)linkAnnotation); + } + this.update_annotations(); + this.OnElementModified(new ElementEventArgs(this.fElement)); + } + } + + private MenuItem[] get_annotation_submenu() + { + ArrayList arrayList = new ArrayList(); + arrayList.Add((object)new MenuItem("Text Annotation", new EventHandler(this.AnnotationNewText_Click))); + arrayList.Add((object)new MenuItem("File Link Annotation", new EventHandler(this.AnnotationNewLink_Click))); + arrayList.Add((object)new MenuItem("Sketch Annotation", new EventHandler(this.AnnotationNewSketch_Click))); + var noteCollection = new List(); + foreach (Note note in LabyrinthData.Project.Notes) + { + if (note.IsTemplate) + noteCollection.Add(note); + } + if (noteCollection.Count != 0) + { + arrayList.Add((object)new MenuItem("-")); + foreach (Note note in noteCollection) + arrayList.Add((object)new MenuItem(note.Title, new EventHandler(this.AnnotationNewTemplate_Click))); + } + return (MenuItem[])arrayList.ToArray(typeof(MenuItem)); + } + + private void AnnotationNewText_Click(object sender, EventArgs e) + { + try + { + this.new_text_annotation((Note)null); + } + catch (Exception ex) + { + LabyrinthData.Log((object)ex); + } + } + + private void AnnotationNewLink_Click(object sender, EventArgs e) + { + try + { + LinkAnnotation linkAnnotation = new LinkAnnotation(); + if (!Annotations.Open((Annotation)linkAnnotation)) + return; + this.fElement.Annotations.Add((Annotation)linkAnnotation); + this.update_annotations(); + this.OnElementModified(new ElementEventArgs(this.fElement)); + this.AnnotationPanel.SelectedAnnotation = (Annotation)linkAnnotation; + } + catch (Exception ex) + { + LabyrinthData.Log((object)ex); + } + } + + private void AnnotationNewSketch_Click(object sender, EventArgs e) + { + try + { + string str = "New Sketch"; + string title = str; + int num = 1; + for (; this.fElement.Annotations.IndexOf(title) != -1; title = str + " " + (object)num) + ++num; + SketchAnnotation sketchAnnotation = new SketchAnnotation(); + sketchAnnotation.Title = title; + if (!Annotations.Open((Annotation)sketchAnnotation)) + return; + this.fElement.Annotations.Add((Annotation)sketchAnnotation); + this.update_annotations(); + this.OnElementModified(new ElementEventArgs(this.fElement)); + this.AnnotationPanel.SelectedAnnotation = (Annotation)sketchAnnotation; + } + catch (Exception ex) + { + LabyrinthData.Log((object)ex); + } + } + + private void AnnotationNewTemplate_Click(object sender, EventArgs e) + { + try + { + var noteCollection = new List(); + foreach (Note note in LabyrinthData.Project.Notes) + { + if (note.IsTemplate) + noteCollection.Add(note); + } + MenuItem menuItem = sender as MenuItem; + if (menuItem == null) + return; + int index = noteCollection.IndexOf(menuItem.Text); + if (index == -1) + return; + this.new_text_annotation(noteCollection[index]); + } + catch (Exception ex) + { + LabyrinthData.Log((object)ex); + } + } + + private void new_text_annotation(Note template) + { + string str = template != null ? template.Title : "New Text Annotation"; + string title = str; + int num = 1; + for (; this.fElement.Annotations.IndexOf(title) != -1; title = str + " " + (object)num) + ++num; + TextAnnotation textAnnotation = new TextAnnotation(); + textAnnotation.Title = title; + if (template != null) + textAnnotation.RTF = template.RTF; + if (!Annotations.Open((Annotation)textAnnotation)) + return; + this.fElement.Annotations.Add((Annotation)textAnnotation); + this.update_annotations(); + this.OnElementModified(new ElementEventArgs(this.fElement)); + this.AnnotationPanel.SelectedAnnotation = (Annotation)textAnnotation; + } + + private void LinkList_ColumnClick(object sender, ColumnClickEventArgs e) + { + ListViewSorter.Sort(this.LinkList, e.Column); + } + + private void TimelineList_ColumnClick(object sender, ColumnClickEventArgs e) + { + ListViewSorter.Sort(this.TimelineList, e.Column); + } + + private void AnnotationList_Layout(object sender, LayoutEventArgs e) + { + this.update_annotations(); + } + + private void TimelineAnnotationList_Layout(object sender, LayoutEventArgs e) + { + this.update_timeline_annotations(); + } + + private void AnnotationContextMenu_Popup(object sender, EventArgs e) + { + this.AnnotationNew.MenuItems.Clear(); + this.AnnotationNew.MenuItems.AddRange(this.get_annotation_submenu()); + } + } +} \ No newline at end of file diff --git a/Labyrinth3/IDE/Pages/ElementPage.resx b/Labyrinth3/IDE/Pages/ElementPage.resx new file mode 100644 index 0000000..9a12e39 --- /dev/null +++ b/Labyrinth3/IDE/Pages/ElementPage.resx @@ -0,0 +1,251 @@ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + text/microsoft-resx + + + 2.0 + + + System.Resources.ResXResourceReader, System.Windows.Forms, Version=4.0.0.0, Culture=neutral, PublicKeyToken=b77a5c561934e089 + + + System.Resources.ResXResourceWriter, System.Windows.Forms, Version=4.0.0.0, Culture=neutral, PublicKeyToken=b77a5c561934e089 + + + + 143, 17 + + + ElementPage + + + + True + + + + AAEAAAD/////AQAAAAAAAAAMAgAAAFdTeXN0ZW0uV2luZG93cy5Gb3JtcywgVmVyc2lvbj00LjAuMC4w + LCBDdWx0dXJlPW5ldXRyYWwsIFB1YmxpY0tleVRva2VuPWI3N2E1YzU2MTkzNGUwODkFAQAAACZTeXN0 + ZW0uV2luZG93cy5Gb3Jtcy5JbWFnZUxpc3RTdHJlYW1lcgEAAAAERGF0YQcCAgAAAAkDAAAADwMAAAA+ + CAAAAk1TRnQBSQFMAgEBAwEAAQQBAAEIAQABEAEAARABAAT/AQkBEAj/AUIBTQE2AQQGAAE2AQQCAAEo + AwABQAMAARADAAEBAQABCAYAAQQYAAGAAgABgAMAAoABAAGAAwABgAEAAYABAAKAAgADwAEAAcAB3AHA + AQAB8AHKAaYBAAEzBQABMwEAATMBAAEzAQACMwIAAxYBAAMcAQADIgEAAykBAANVAQADTQEAA0IBAAM5 + AQABgAF8Af8BAAJQAf8BAAGTAQAB1gEAAf8B7AHMAQABxgHWAe8BAAHWAucBAAGQAakBrQIAAf8BMwMA + AWYDAAGZAwABzAIAATMDAAIzAgABMwFmAgABMwGZAgABMwHMAgABMwH/AgABZgMAAWYBMwIAAmYCAAFm + AZkCAAFmAcwCAAFmAf8CAAGZAwABmQEzAgABmQFmAgACmQIAAZkBzAIAAZkB/wIAAcwDAAHMATMCAAHM + AWYCAAHMAZkCAALMAgABzAH/AgAB/wFmAgAB/wGZAgAB/wHMAQABMwH/AgAB/wEAATMBAAEzAQABZgEA + ATMBAAGZAQABMwEAAcwBAAEzAQAB/wEAAf8BMwIAAzMBAAIzAWYBAAIzAZkBAAIzAcwBAAIzAf8BAAEz + AWYCAAEzAWYBMwEAATMCZgEAATMBZgGZAQABMwFmAcwBAAEzAWYB/wEAATMBmQIAATMBmQEzAQABMwGZ + AWYBAAEzApkBAAEzAZkBzAEAATMBmQH/AQABMwHMAgABMwHMATMBAAEzAcwBZgEAATMBzAGZAQABMwLM + AQABMwHMAf8BAAEzAf8BMwEAATMB/wFmAQABMwH/AZkBAAEzAf8BzAEAATMC/wEAAWYDAAFmAQABMwEA + AWYBAAFmAQABZgEAAZkBAAFmAQABzAEAAWYBAAH/AQABZgEzAgABZgIzAQABZgEzAWYBAAFmATMBmQEA + AWYBMwHMAQABZgEzAf8BAAJmAgACZgEzAQADZgEAAmYBmQEAAmYBzAEAAWYBmQIAAWYBmQEzAQABZgGZ + AWYBAAFmApkBAAFmAZkBzAEAAWYBmQH/AQABZgHMAgABZgHMATMBAAFmAcwBmQEAAWYCzAEAAWYBzAH/ + AQABZgH/AgABZgH/ATMBAAFmAf8BmQEAAWYB/wHMAQABzAEAAf8BAAH/AQABzAEAApkCAAGZATMBmQEA + AZkBAAGZAQABmQEAAcwBAAGZAwABmQIzAQABmQEAAWYBAAGZATMBzAEAAZkBAAH/AQABmQFmAgABmQFm + ATMBAAGZATMBZgEAAZkBZgGZAQABmQFmAcwBAAGZATMB/wEAApkBMwEAApkBZgEAA5kBAAKZAcwBAAKZ + Af8BAAGZAcwCAAGZAcwBMwEAAWYBzAFmAQABmQHMAZkBAAGZAswBAAGZAcwB/wEAAZkB/wIAAZkB/wEz + AQABmQHMAWYBAAGZAf8BmQEAAZkB/wHMAQABmQL/AQABzAMAAZkBAAEzAQABzAEAAWYBAAHMAQABmQEA + AcwBAAHMAQABmQEzAgABzAIzAQABzAEzAWYBAAHMATMBmQEAAcwBMwHMAQABzAEzAf8BAAHMAWYCAAHM + AWYBMwEAAZkCZgEAAcwBZgGZAQABzAFmAcwBAAGZAWYB/wEAAcwBmQIAAcwBmQEzAQABzAGZAWYBAAHM + ApkBAAHMAZkBzAEAAcwBmQH/AQACzAIAAswBMwEAAswBZgEAAswBmQEAA8wBAALMAf8BAAHMAf8CAAHM + Af8BMwEAAZkB/wFmAQABzAH/AZkBAAHMAf8BzAEAAcwC/wEAAcwBAAEzAQAB/wEAAWYBAAH/AQABmQEA + AcwBMwIAAf8CMwEAAf8BMwFmAQAB/wEzAZkBAAH/ATMBzAEAAf8BMwH/AQAB/wFmAgAB/wFmATMBAAHM + AmYBAAH/AWYBmQEAAf8BZgHMAQABzAFmAf8BAAH/AZkCAAH/AZkBMwEAAf8BmQFmAQAB/wKZAQAB/wGZ + AcwBAAH/AZkB/wEAAf8BzAIAAf8BzAEzAQAB/wHMAWYBAAH/AcwBmQEAAf8CzAEAAf8BzAH/AQAC/wEz + AQABzAH/AWYBAAL/AZkBAAL/AcwBAAJmAf8BAAFmAf8BZgEAAWYC/wEAAf8CZgEAAf8BZgH/AQAC/wFm + AQABIQEAAaUBAANfAQADdwEAA4YBAAOWAQADywEAA7IBAAPXAQAD3QEAA+MBAAPqAQAD8QEAA/gBAAHw + AfsB/wEAAaQCoAEAA4ADAAH/AgAB/wMAAv8BAAH/AwAB/wEAAf8BAAL/AgAD//8AAwAB7AH7Af8B+wH/ + AfsB/wH7Af8B7AEAAf8B+zMAAewB/wH7Af8B+wH/AfsB/wH7AuwBAAH/MwAB7AH7Af8B+wH/AfsB/wH7 + Af8B7AH7Aew0AAHsAf8B+wH/AfsB/wH7Af8B+wTsMwAB7AH7Af8B+wH/AfsB/wH7Af8B+wH/AfsB/zMA + AewB/wH7Af8B+wH/AfsB/wH7Af8B+wH/AfszAAHsAfsB/wH7Af8B+wH/AfsB/wH7Af8B+wH/MwAN7P8A + MwABQgFNAT4HAAE+AwABKAMAAUADAAEQAwABAQEAAQEFAAGAFwAD/wEABv8CAAX/Ac8CAAX/AccCAAGA + AQEC/wH8AQMCAAGAAQEC/wHzAccCAAGAAQEB3wH9Ae8BzwIAAYABAQHfAf0B7wH/AgABgAEBAdsBbQHz + Af8CAAGAAQEB2wFtAfwBfwIAAYABAQHAAQEB/wGfAgABgAEBA/8B7wIAAYABAQP/Ae8CAAX/AZ8CAAT/ + AfABfwIABv8CAAb/GAAL + + + + 17, 17 + + + 55 + + + 578, 17 + + + 419, 17 + + + 248, 17 + + + + AAEAAAD/////AQAAAAAAAAAMAgAAAFdTeXN0ZW0uV2luZG93cy5Gb3JtcywgVmVyc2lvbj00LjAuMC4w + LCBDdWx0dXJlPW5ldXRyYWwsIFB1YmxpY0tleVRva2VuPWI3N2E1YzU2MTkzNGUwODkFAQAAACZTeXN0 + ZW0uV2luZG93cy5Gb3Jtcy5JbWFnZUxpc3RTdHJlYW1lcgEAAAAERGF0YQcCAgAAAAkDAAAADwMAAAC6 + DAAAAk1TRnQBSQFMAgEBCQEAAQ4BAAEIAQABEAEAARABAAT/AQkBEAj/AUIBTQE2AQQGAAE2AQQCAAEo + AwABQAMAATADAAEBAQABCAYAAQwYAAGAAgABgAMAAoABAAGAAwABgAEAAYABAAKAAgADwAEAAcAB3AHA + AQAB8AHKAaYBAAEzBQABMwEAATMBAAEzAQACMwIAAxYBAAMcAQADIgEAAykBAANVAQADTQEAA0IBAAM5 + AQABgAF8Af8BAAJQAf8BAAGTAQAB1gEAAf8B7AHMAQABxgHWAe8BAAHWAucBAAGQAakBrQIAAf8BMwMA + AWYDAAGZAwABzAIAATMDAAIzAgABMwFmAgABMwGZAgABMwHMAgABMwH/AgABZgMAAWYBMwIAAmYCAAFm + AZkCAAFmAcwCAAFmAf8CAAGZAwABmQEzAgABmQFmAgACmQIAAZkBzAIAAZkB/wIAAcwDAAHMATMCAAHM + AWYCAAHMAZkCAALMAgABzAH/AgAB/wFmAgAB/wGZAgAB/wHMAQABMwH/AgAB/wEAATMBAAEzAQABZgEA + ATMBAAGZAQABMwEAAcwBAAEzAQAB/wEAAf8BMwIAAzMBAAIzAWYBAAIzAZkBAAIzAcwBAAIzAf8BAAEz + AWYCAAEzAWYBMwEAATMCZgEAATMBZgGZAQABMwFmAcwBAAEzAWYB/wEAATMBmQIAATMBmQEzAQABMwGZ + AWYBAAEzApkBAAEzAZkBzAEAATMBmQH/AQABMwHMAgABMwHMATMBAAEzAcwBZgEAATMBzAGZAQABMwLM + AQABMwHMAf8BAAEzAf8BMwEAATMB/wFmAQABMwH/AZkBAAEzAf8BzAEAATMC/wEAAWYDAAFmAQABMwEA + AWYBAAFmAQABZgEAAZkBAAFmAQABzAEAAWYBAAH/AQABZgEzAgABZgIzAQABZgEzAWYBAAFmATMBmQEA + AWYBMwHMAQABZgEzAf8BAAJmAgACZgEzAQADZgEAAmYBmQEAAmYBzAEAAWYBmQIAAWYBmQEzAQABZgGZ + AWYBAAFmApkBAAFmAZkBzAEAAWYBmQH/AQABZgHMAgABZgHMATMBAAFmAcwBmQEAAWYCzAEAAWYBzAH/ + AQABZgH/AgABZgH/ATMBAAFmAf8BmQEAAWYB/wHMAQABzAEAAf8BAAH/AQABzAEAApkCAAGZATMBmQEA + AZkBAAGZAQABmQEAAcwBAAGZAwABmQIzAQABmQEAAWYBAAGZATMBzAEAAZkBAAH/AQABmQFmAgABmQFm + ATMBAAGZATMBZgEAAZkBZgGZAQABmQFmAcwBAAGZATMB/wEAApkBMwEAApkBZgEAA5kBAAKZAcwBAAKZ + Af8BAAGZAcwCAAGZAcwBMwEAAWYBzAFmAQABmQHMAZkBAAGZAswBAAGZAcwB/wEAAZkB/wIAAZkB/wEz + AQABmQHMAWYBAAGZAf8BmQEAAZkB/wHMAQABmQL/AQABzAMAAZkBAAEzAQABzAEAAWYBAAHMAQABmQEA + AcwBAAHMAQABmQEzAgABzAIzAQABzAEzAWYBAAHMATMBmQEAAcwBMwHMAQABzAEzAf8BAAHMAWYCAAHM + AWYBMwEAAZkCZgEAAcwBZgGZAQABzAFmAcwBAAGZAWYB/wEAAcwBmQIAAcwBmQEzAQABzAGZAWYBAAHM + ApkBAAHMAZkBzAEAAcwBmQH/AQACzAIAAswBMwEAAswBZgEAAswBmQEAA8wBAALMAf8BAAHMAf8CAAHM + Af8BMwEAAZkB/wFmAQABzAH/AZkBAAHMAf8BzAEAAcwC/wEAAcwBAAEzAQAB/wEAAWYBAAH/AQABmQEA + AcwBMwIAAf8CMwEAAf8BMwFmAQAB/wEzAZkBAAH/ATMBzAEAAf8BMwH/AQAB/wFmAgAB/wFmATMBAAHM + AmYBAAH/AWYBmQEAAf8BZgHMAQABzAFmAf8BAAH/AZkCAAH/AZkBMwEAAf8BmQFmAQAB/wKZAQAB/wGZ + AcwBAAH/AZkB/wEAAf8BzAIAAf8BzAEzAQAB/wHMAWYBAAH/AcwBmQEAAf8CzAEAAf8BzAH/AQAC/wEz + AQABzAH/AWYBAAL/AZkBAAL/AcwBAAJmAf8BAAFmAf8BZgEAAWYC/wEAAf8CZgEAAf8BZgH/AQAC/wFm + AQABIQEAAaUBAANfAQADdwEAA4YBAAOWAQADywEAA7IBAAPXAQAD3QEAA+MBAAPqAQAD8QEAA/gBAAHw + AfsB/wEAAaQCoAEAA4ADAAH/AgAB/wMAAv8BAAH/AwAB/wEAAf8BAAL/AgAD//8ACQAB7D8AAew/AAEH + PwABBz4AAgcB7DwABAcB7DoAAQcC/wMHAez/ALIAAfwaAATsDQAC7BIAAvwYAAQBAewMAAIBAuwMAAj8 + FwAEAQHsCwAEAQLsCwAJ/BYABAEB7AoABgEC7AoACPwXAAQBAewJAAgBEAAC/BgABAEB7AsABAEB7BEA + AfwZAAQBAewLAAQBAewGAAHsAfsB/wH7Af8B+wH/AfsB/wHsAQAB/wH7GAAEAQHsCwAEAQHsBgAB7AH/ + AfsB/wH7Af8B+wH/AfsB7AEHAQAB/xgABAED7AkABAEB7AYAAewB+wH/AfsB/wH7Af8B+wH/AewB+wEH + FwAIAQoABAEB7AYAAewB/wH7Af8B+wH/AfsB/wH7BOwXAAYBCwAEAQHsBgAB7AH7Af8B+wH/AfsB/wH7 + Af8B+wH/AfsB/xgABAEMAAQBAewGAAHsAf8B+wH/AfsB/wH7Af8B+wH/AfsB/wH7GQACAQ0ABAEHAAHs + AfsB/wH7Af8B+wH/AfsB/wH7Af8B+wH/MwAN7MMACv8WAAr/FgAB/wIAAf8FAAH/BwAJBwEAAQcEAAf/ + GQAK/xIAAQcDAAb/AgACBwYAAewB+wH/AfsB/wH7Af8B+wH/AewBAAH/AfsDAAH/AgAB/wUAAf8GAAYH + A/sCBwUABf8CAAIHAf4GAAHsAf8B+wH/AfsB/wH7Af8B+wLsAQAB/wMACv8GAAYHAwACBwEAAQcDAAX/ + AQAEBwYAAewB+wH/AfsB/wH7Af8B+wH/AewB+wHsBAAH/wEAAv8SAAIHAgAF/wEAAQcB/gIHBgAB7AH/ + AfsB/wH7Af8B+wH/AfsE7AMAAf8CAAP/AQABBwEAAf8GAAoHAQABBwEAAQcCAAX/AgAC/gEHBQAB+wHs + AfsB7AH7Af8B+wH/AfsB/wH7Af8B+wH/AwAB/wEAAQcBAAH/AQABBwEAAQcEAAIECwABBwEAAQcDAAb/ + AgACBwUAAewB+wLsAvsB7AH7Af8B+wH/AfsB/wH7AwAC/wEAAQcBAAEHAQABBwEAAwcBAAIEAwAI/wEA + AQcBAAEHAgAH/wkAAewB+wHsAfsC7AH/AfsB/wH7Af8B+wH/BwABBwEAAQcBAAUHAgQEAAH/BQAB/wYA + Cv8FAAPsAQcB7AEHAfsH7AgAAQcBAAYHAgQEAAj/BQAH/wkAAfsB7AH7AQAC7BAABgcBAAIEBQAB/wUA + Af8FAAf/AQABBwcAAewB+wHsAfsB7AH7FwACBAUACP8EAAf/CAAB7AH7AQAB7AIAAew5AAH7AgAB7AH7 + CwABQgFNAT4HAAE+AwABKAMAAUADAAEwAwABAQEAAQEFAAGAAQEWAAP/AQAC/wYAAv8GAAL/BgAC/wYA + AfwBfwYAAfwBfwYAAfwBfwYAAfwBfwYAAfgBPwYAAfABHwYAAeABDwYAAcABBwYAAv8GAAL/BgAC/wYA + Av8GAAf/AfcC/wH+AR8B/wE/Af8B8wHvAf0B/AEfAf4BHwH+AQEBxwH/AfwBHwH8AQ8B/gEAAcMB+wH8 + AR8B+AEHAf4BAQHjAfcB/AEfAfABDwH/AfMB8QHnAfwBHwH8AR8BgAEBAfgBzwH8AR8B/AEfAYABAQH8 + AR8B/AEfAfwBHwGAAQEB/gE/AfwBBwH8AR8BgAEBAfwBHwHwAQ8B/AEfAYABAQH4Ac8B+AEfAfwBHwGA + AQEB4QHnAfwBPwH8AR8BgAEBAcMB8wH+AX8B/AE/AYABAQHHAf0E/wGAAQEQ/wEAAQ8C/wEAAQwC/wEA + AQ8BwAEHAQABCAL/AQABDwGAAQMBAAEBAYABAQEAAQ8BAAEBAQABAwGAAQEBAAEPAQABAQEAAQMBgAEB + AQABDwEAAQEBAAELAYABAQEAAQ8DAAELAYABAQEAAQ8DAAEDAQABAQEAAQQBgAIAAQcBAAEBAgABwAIA + AQ8BgAEBAgAB4AEBAQABDwEAAQEB+AEAAeABBwEAAQ8BiQH/AfwBAAHwAQcBAAEfAYEB/wH+AQQB8AED + AQABPwEtA/8B+AEDAQABfwFnAf8WAAs= + + + \ No newline at end of file diff --git a/Labyrinth3/IDE/Pages/NotePage.cs b/Labyrinth3/IDE/Pages/NotePage.cs new file mode 100644 index 0000000..76640a2 --- /dev/null +++ b/Labyrinth3/IDE/Pages/NotePage.cs @@ -0,0 +1,225 @@ +// Decompiled with JetBrains decompiler +// Type: Labyrinth.Pages.NotePage +// Assembly: Labyrinth, Version=3.6.1928.15690, Culture=neutral, PublicKeyToken=null +// MVID: 1462002E-0BD1-49D2-9B56-C22E66C903E7 +// Assembly location: C:\Dropbox\Workspace\Programs\Labyrinth\Labyrinth.exe + +using Labyrinth.Controls; +using Labyrinth.Events; +using Labyrinth.Extensibility; +using Labyrinth.Forms; +using Labyrinth.Plot; +using System; +using System.ComponentModel; +using System.Drawing; +using System.IO; +using System.Resources; +using System.Windows.Forms; + +namespace Labyrinth.Pages +{ + public class NotePage : UserControl, INotePage, IPage + { + private Note fNote = (Note)null; + private ToolBar Toolbar; + private ImageList Images; + private ToolBarButton PropertiesBtn; + private RTFPanel RTFPanel; + private ToolBarButton Sep1; + private ToolBarButton ExportBtn; + private IContainer components; + + public NotePage(Note n) + { + this.InitializeComponent(); + Application.Idle += new EventHandler(this.update_rtfpanel); + this.fNote = n; + this.UpdateData(); + } + + protected override void Dispose(bool disposing) + { + if (disposing && this.components != null) + this.components.Dispose(); + base.Dispose(disposing); + } + + private void InitializeComponent() + { + this.components = (IContainer)new Container(); + ResourceManager resourceManager = new ResourceManager(typeof(NotePage)); + this.Toolbar = new ToolBar(); + this.PropertiesBtn = new ToolBarButton(); + this.Sep1 = new ToolBarButton(); + this.ExportBtn = new ToolBarButton(); + this.Images = new ImageList(this.components); + this.RTFPanel = new RTFPanel(); + this.SuspendLayout(); + this.Toolbar.Appearance = ToolBarAppearance.Flat; + this.Toolbar.Buttons.AddRange(new ToolBarButton[3] + { + this.PropertiesBtn, + this.Sep1, + this.ExportBtn + }); + this.Toolbar.DropDownArrows = true; + this.Toolbar.ImageList = this.Images; + this.Toolbar.Name = "Toolbar"; + this.Toolbar.ShowToolTips = true; + this.Toolbar.Size = new Size(432, 25); + this.Toolbar.TabIndex = 1; + this.Toolbar.ButtonClick += new ToolBarButtonClickEventHandler(this.Toolbar_ButtonClick); + this.PropertiesBtn.ImageIndex = 0; + this.PropertiesBtn.ToolTipText = "Properties"; + this.Sep1.Style = ToolBarButtonStyle.Separator; + this.ExportBtn.ImageIndex = 1; + this.ExportBtn.ToolTipText = "Export"; + this.Images.ColorDepth = ColorDepth.Depth8Bit; + this.Images.ImageSize = new Size(16, 16); + this.Images.ImageStream = (ImageListStreamer)resourceManager.GetObject("Images.ImageStream"); + this.Images.TransparentColor = Color.Magenta; + this.RTFPanel.Dock = DockStyle.Fill; + this.RTFPanel.Location = new Point(0, 25); + this.RTFPanel.Name = "RTFPanel"; + this.RTFPanel.RTF = "{\\rtf1\\ansi\\ansicpg1252\\deff0\\deflang2057{\\fonttbl{\\f0\\fnil\\fcharset0 Tahoma;}}\r\n{\\*\\generator Riched20 5.40.11.2212;}\\viewkind4\\uc1\\pard\\f0\\fs17\\par\r\n}\r\n\0"; + this.RTFPanel.Size = new Size(432, 215); + this.RTFPanel.TabIndex = 2; + this.RTFPanel.ContentModified += new EventHandler(this.RTFPanel_ContentModified); + this.Controls.AddRange(new Control[2] + { + (Control) this.RTFPanel, + (Control) this.Toolbar + }); + this.Font = new Font("Tahoma", 11f, FontStyle.Regular, GraphicsUnit.World); + this.Name = nameof(NotePage); + this.Size = new Size(432, 240); + this.ResumeLayout(false); + } + + public string Title + { + get + { + return this.fNote.Title; + } + } + + public bool IsObsolete + { + get + { + return LabyrinthData.Project.Notes.IndexOf(this.fNote) == -1; + } + } + + public void UpdateUI() + { + } + + public void UpdateData() + { + if (this.fNote.RTF != "") + this.RTFPanel.RTF = this.fNote.RTF; + else + this.RTFPanel.Text = this.fNote.Text; + } + + public Note Note + { + get + { + return this.fNote; + } + } + + public event NoteEventHandler NoteModified; + + protected void OnNoteModified(NoteEventArgs e) + { + try + { + if (this.NoteModified == null) + return; + this.NoteModified((object)this, e); + } + catch (Exception ex) + { + LabyrinthData.Log((object)ex); + } + } + + private void RTFPanel_ContentModified(object sender, EventArgs e) + { + this.fNote.Text = this.RTFPanel.Text; + this.fNote.RTF = this.RTFPanel.RTF; + this.OnNoteModified(new NoteEventArgs(this.fNote)); + } + + private void update_rtfpanel(object sender, EventArgs e) + { + this.RTFPanel.UpdateUI(); + } + + private void Toolbar_ButtonClick(object sender, ToolBarButtonClickEventArgs e) + { + try + { + if (e.Button == this.PropertiesBtn) + { + if (new NoteDlg(this.fNote).ShowDialog() != DialogResult.OK) + return; + this.UpdateData(); + this.OnNoteModified(new NoteEventArgs(this.fNote)); + } + else + { + if (e.Button != this.ExportBtn) + return; + string str = "Rich Text Files|*.rtf|HTML Files|*.html|Text Files|*.txt"; + try + { + SaveFileDialog saveFileDialog = new SaveFileDialog(); + saveFileDialog.FileName = this.fNote.Title; + saveFileDialog.Filter = str; + if (saveFileDialog.ShowDialog() != DialogResult.OK) + return; + switch (saveFileDialog.FilterIndex) + { + case 1: + StreamWriter streamWriter1 = new StreamWriter(saveFileDialog.FileName); + streamWriter1.Write(this.RTFPanel.RTF); + streamWriter1.Close(); + break; + + case 2: + StreamWriter streamWriter2 = new StreamWriter(saveFileDialog.FileName); + streamWriter2.WriteLine(LabyrinthData.HTMLHeader(this.fNote.Title)); + streamWriter2.WriteLine(""); + streamWriter2.WriteLine("
");
+                                streamWriter2.WriteLine(this.RTFPanel.Text);
+                                streamWriter2.WriteLine("
"); + streamWriter2.WriteLine(""); + streamWriter2.WriteLine(""); + streamWriter2.Close(); + break; + + case 3: + StreamWriter streamWriter3 = new StreamWriter(saveFileDialog.FileName); + streamWriter3.Write(this.RTFPanel.Text); + streamWriter3.Close(); + break; + } + } + catch (Exception ex) + { + LabyrinthData.Log((object)ex); + } + } + } + catch (Exception ex) + { + LabyrinthData.Log((object)ex); + } + } + } +} \ No newline at end of file diff --git a/Labyrinth3/IDE/Pages/NotePage.resx b/Labyrinth3/IDE/Pages/NotePage.resx new file mode 100644 index 0000000..b537a01 --- /dev/null +++ b/Labyrinth3/IDE/Pages/NotePage.resx @@ -0,0 +1,176 @@ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + text/microsoft-resx + + + 2.0 + + + System.Resources.ResXResourceReader, System.Windows.Forms, Version=4.0.0.0, Culture=neutral, PublicKeyToken=b77a5c561934e089 + + + System.Resources.ResXResourceWriter, System.Windows.Forms, Version=4.0.0.0, Culture=neutral, PublicKeyToken=b77a5c561934e089 + + + NotePage + + + + AAEAAAD/////AQAAAAAAAAAMAgAAAFdTeXN0ZW0uV2luZG93cy5Gb3JtcywgVmVyc2lvbj00LjAuMC4w + LCBDdWx0dXJlPW5ldXRyYWwsIFB1YmxpY0tleVRva2VuPWI3N2E1YzU2MTkzNGUwODkFAQAAACZTeXN0 + ZW0uV2luZG93cy5Gb3Jtcy5JbWFnZUxpc3RTdHJlYW1lcgEAAAAERGF0YQcCAgAAAAkDAAAADwMAAADQ + CAAAAk1TRnQBSQFMAgEBAgEAAQQBAAEIAQABEAEAARABAAT/AQkBEAj/AUIBTQE2AQQGAAE2AQQCAAEo + AwABQAMAARADAAEBAQABCAYAAQQYAAGAAgABgAMAAoABAAGAAwABgAEAAYABAAKAAgADwAEAAcAB3AHA + AQAB8AHKAaYBAAEzBQABMwEAATMBAAEzAQACMwIAAxYBAAMcAQADIgEAAykBAANVAQADTQEAA0IBAAM5 + AQABgAF8Af8BAAJQAf8BAAGTAQAB1gEAAf8B7AHMAQABxgHWAe8BAAHWAucBAAGQAakBrQIAAf8BMwMA + AWYDAAGZAwABzAIAATMDAAIzAgABMwFmAgABMwGZAgABMwHMAgABMwH/AgABZgMAAWYBMwIAAmYCAAFm + AZkCAAFmAcwCAAFmAf8CAAGZAwABmQEzAgABmQFmAgACmQIAAZkBzAIAAZkB/wIAAcwDAAHMATMCAAHM + AWYCAAHMAZkCAALMAgABzAH/AgAB/wFmAgAB/wGZAgAB/wHMAQABMwH/AgAB/wEAATMBAAEzAQABZgEA + ATMBAAGZAQABMwEAAcwBAAEzAQAB/wEAAf8BMwIAAzMBAAIzAWYBAAIzAZkBAAIzAcwBAAIzAf8BAAEz + AWYCAAEzAWYBMwEAATMCZgEAATMBZgGZAQABMwFmAcwBAAEzAWYB/wEAATMBmQIAATMBmQEzAQABMwGZ + AWYBAAEzApkBAAEzAZkBzAEAATMBmQH/AQABMwHMAgABMwHMATMBAAEzAcwBZgEAATMBzAGZAQABMwLM + AQABMwHMAf8BAAEzAf8BMwEAATMB/wFmAQABMwH/AZkBAAEzAf8BzAEAATMC/wEAAWYDAAFmAQABMwEA + AWYBAAFmAQABZgEAAZkBAAFmAQABzAEAAWYBAAH/AQABZgEzAgABZgIzAQABZgEzAWYBAAFmATMBmQEA + AWYBMwHMAQABZgEzAf8BAAJmAgACZgEzAQADZgEAAmYBmQEAAmYBzAEAAWYBmQIAAWYBmQEzAQABZgGZ + AWYBAAFmApkBAAFmAZkBzAEAAWYBmQH/AQABZgHMAgABZgHMATMBAAFmAcwBmQEAAWYCzAEAAWYBzAH/ + AQABZgH/AgABZgH/ATMBAAFmAf8BmQEAAWYB/wHMAQABzAEAAf8BAAH/AQABzAEAApkCAAGZATMBmQEA + AZkBAAGZAQABmQEAAcwBAAGZAwABmQIzAQABmQEAAWYBAAGZATMBzAEAAZkBAAH/AQABmQFmAgABmQFm + ATMBAAGZATMBZgEAAZkBZgGZAQABmQFmAcwBAAGZATMB/wEAApkBMwEAApkBZgEAA5kBAAKZAcwBAAKZ + Af8BAAGZAcwCAAGZAcwBMwEAAWYBzAFmAQABmQHMAZkBAAGZAswBAAGZAcwB/wEAAZkB/wIAAZkB/wEz + AQABmQHMAWYBAAGZAf8BmQEAAZkB/wHMAQABmQL/AQABzAMAAZkBAAEzAQABzAEAAWYBAAHMAQABmQEA + AcwBAAHMAQABmQEzAgABzAIzAQABzAEzAWYBAAHMATMBmQEAAcwBMwHMAQABzAEzAf8BAAHMAWYCAAHM + AWYBMwEAAZkCZgEAAcwBZgGZAQABzAFmAcwBAAGZAWYB/wEAAcwBmQIAAcwBmQEzAQABzAGZAWYBAAHM + ApkBAAHMAZkBzAEAAcwBmQH/AQACzAIAAswBMwEAAswBZgEAAswBmQEAA8wBAALMAf8BAAHMAf8CAAHM + Af8BMwEAAZkB/wFmAQABzAH/AZkBAAHMAf8BzAEAAcwC/wEAAcwBAAEzAQAB/wEAAWYBAAH/AQABmQEA + AcwBMwIAAf8CMwEAAf8BMwFmAQAB/wEzAZkBAAH/ATMBzAEAAf8BMwH/AQAB/wFmAgAB/wFmATMBAAHM + AmYBAAH/AWYBmQEAAf8BZgHMAQABzAFmAf8BAAH/AZkCAAH/AZkBMwEAAf8BmQFmAQAB/wKZAQAB/wGZ + AcwBAAH/AZkB/wEAAf8BzAIAAf8BzAEzAQAB/wHMAWYBAAH/AcwBmQEAAf8CzAEAAf8BzAH/AQAC/wEz + AQABzAH/AWYBAAL/AZkBAAL/AcwBAAJmAf8BAAFmAf8BZgEAAWYC/wEAAf8CZgEAAf8BZgH/AQAC/wFm + AQABIQEAAaUBAANfAQADdwEAA4YBAAOWAQADywEAA7IBAAPXAQAD3QEAA+MBAAPqAQAD8QEAA/gBAAHw + AfsB/wEAAaQCoAEAA4ADAAH/AgAB/wMAAv8BAAH/AwAB/wEAAf8BAAL/AgAD/xQABwcCAAH8NgACBwbs + AQcC/CMACv8HAAHsAQcD/wj8IgAB/wIAAf8FAAH/BwAB7AEHAf8B7AEHCfwhAAr/BwAB7AEHA/8I/CIA + Af8CAAH/BQAB/wcAAewBBwH/BOwBBwL/AvwjAAr/BwAB7AEHCP8B/AEHIwAH/wEAAv8HAAHsAQcB/wTs + AQcC/wHsAQcjAAH/AgAD/wEAAQcBAAH/BwAB7AEHCP8B7AEHIwAB/wEAAQcBAAH/AQABBwEAAQcEAAIE + AgAB7AEHAf8D7AEHA/8B7AEHIwAC/wEAAQcBAAEHAQABBwEAAwcBAAIEAgAB7AEHCP8B7AEHJwABBwEA + AQcBAAUHAgQCAAHsAQcI/wHsAQcoAAEHAQAGBwIEAgAB7AEHAewB/wHsAf8B7AH/AewB/wHsAQcpAAYH + AQACBAIAAQcC7AEDAQcB7AEHAewBBwHsAQcxAAIEAwAB7AH7AgMB+wHsAfsC7AEHPQABByUAAUIBTQE+ + BwABPgMAASgDAAFAAwABEAMAAQEBAAEBBQABgBcAA/8BAAL/AeABNwUAAQ8B4AEDBQABDwHAAQEFAAEP + AcAGAAEPAcABAQUAAQ8BwAEDBQABDwHAAQMFAAEPAcABAwUAAQ8BwAEDBQABBAHAAQMGAAHAAQMGAAHA + AQMEAAH4AQABwAEDBAAB/AEAAcABBwQAAf4BBAHgAQcEAAP/Ad8aAAs= + + + + + 57 + + + + 17, 17 + + \ No newline at end of file diff --git a/Labyrinth3/IDE/Pages/SearchPage.cs b/Labyrinth3/IDE/Pages/SearchPage.cs new file mode 100644 index 0000000..24c3c9d --- /dev/null +++ b/Labyrinth3/IDE/Pages/SearchPage.cs @@ -0,0 +1,652 @@ +// Decompiled with JetBrains decompiler +// Type: Labyrinth.Pages.SearchPage +// Assembly: Labyrinth, Version=3.6.1928.15690, Culture=neutral, PublicKeyToken=null +// MVID: 1462002E-0BD1-49D2-9B56-C22E66C903E7 +// Assembly location: C:\Dropbox\Workspace\Programs\Labyrinth\Labyrinth.exe + +using Labyrinth.Events; +using Labyrinth.Extensibility; +using Labyrinth.Forms; +using Labyrinth.Plot; +using System; +using System.Collections; +using System.ComponentModel; +using System.Drawing; +using System.Resources; +using System.Windows.Forms; + +namespace Labyrinth.Pages +{ + public class SearchPage : UserControl, ISearchPage, IPage + { + private ArrayList fCustomSearches = new ArrayList(); + private ImageList ToolbarImages; + private ContextMenu ResultContextMenu; + private MenuItem ResultOpen; + private Crownwood.Magic.Controls.TabControl TypePages; + private ToolBarButton NewSearchBtn; + private ToolBar ToolBar; + private CheckBox CaseSensitiveBox; + private TextBox SearchTextBox; + private Label SearchForLbl; + private CheckBox NegateBox; + private MenuItem ResultProperties; + private Crownwood.Magic.Controls.TabPage StandardPage; + private ListView ResultsList; + private ColumnHeader NameHdr; + private ColumnHeader TypeHdr; + private ColumnHeader DetailsHdr; + private Splitter Splitter; + private Panel SearchPanel; + private IContainer components; + + public SearchPage() + { + this.InitializeComponent(); + this.ResultsList.ListViewItemSorter = (IComparer)new ListViewSorter(); + this.TypePages.Appearance = Crownwood.Magic.Controls.TabControl.VisualAppearance.MultiBox; + this.TypePages.HideTabsMode = Crownwood.Magic.Controls.TabControl.HideTabsModes.HideAlways; + this.ResultsList.SmallImageList = LabyrinthData.ElementImages; + this.UpdateData(); + } + + protected override void Dispose(bool disposing) + { + if (disposing && this.components != null) + this.components.Dispose(); + base.Dispose(disposing); + } + + private void InitializeComponent() + { + this.components = (IContainer)new Container(); + ResourceManager resourceManager = new ResourceManager(typeof(SearchPage)); + this.ToolbarImages = new ImageList(this.components); + this.ResultContextMenu = new ContextMenu(); + this.ResultOpen = new MenuItem(); + this.ResultProperties = new MenuItem(); + this.TypePages = new Crownwood.Magic.Controls.TabControl(); + this.StandardPage = new Crownwood.Magic.Controls.TabPage(); + this.ResultsList = new ListView(); + this.NameHdr = new ColumnHeader(); + this.TypeHdr = new ColumnHeader(); + this.DetailsHdr = new ColumnHeader(); + this.Splitter = new Splitter(); + this.SearchPanel = new Panel(); + this.NegateBox = new CheckBox(); + this.CaseSensitiveBox = new CheckBox(); + this.SearchTextBox = new TextBox(); + this.SearchForLbl = new Label(); + this.NewSearchBtn = new ToolBarButton(); + this.ToolBar = new ToolBar(); + this.StandardPage.SuspendLayout(); + this.SearchPanel.SuspendLayout(); + this.SuspendLayout(); + this.ToolbarImages.ColorDepth = ColorDepth.Depth8Bit; + this.ToolbarImages.ImageSize = new Size(16, 16); + this.ToolbarImages.ImageStream = (ImageListStreamer)resourceManager.GetObject("ToolbarImages.ImageStream"); + this.ToolbarImages.TransparentColor = Color.Magenta; + this.ResultContextMenu.MenuItems.AddRange(new MenuItem[2] + { + this.ResultOpen, + this.ResultProperties + }); + this.ResultOpen.Index = 0; + this.ResultOpen.Text = "Open Result Item"; + this.ResultOpen.Click += new EventHandler(this.ResultOpen_Click); + this.ResultProperties.Index = 1; + this.ResultProperties.Text = "Result Item Properties"; + this.ResultProperties.Click += new EventHandler(this.ResultProperties_Click); + this.TypePages.Dock = DockStyle.Fill; + this.TypePages.HideTabsMode = Crownwood.Magic.Controls.TabControl.HideTabsModes.ShowAlways; + this.TypePages.Location = new Point(0, 25); + this.TypePages.Name = "TypePages"; + this.TypePages.SelectedIndex = 0; + this.TypePages.SelectedTab = this.StandardPage; + this.TypePages.Size = new Size(560, 239); + this.TypePages.TabIndex = 4; + this.TypePages.TabPages.AddRange(new Crownwood.Magic.Controls.TabPage[1] + { + this.StandardPage + }); + this.StandardPage.Controls.AddRange(new Control[3] + { + (Control) this.ResultsList, + (Control) this.Splitter, + (Control) this.SearchPanel + }); + this.StandardPage.Name = "StandardPage"; + this.StandardPage.Size = new Size(560, 214); + this.StandardPage.TabIndex = 0; + this.StandardPage.Title = "Standard"; + this.ResultsList.Columns.AddRange(new ColumnHeader[3] + { + this.NameHdr, + this.TypeHdr, + this.DetailsHdr + }); + this.ResultsList.ContextMenu = this.ResultContextMenu; + this.ResultsList.Dock = DockStyle.Fill; + this.ResultsList.FullRowSelect = true; + this.ResultsList.Location = new Point(195, 0); + this.ResultsList.Name = "ResultsList"; + this.ResultsList.Size = new Size(365, 214); + this.ResultsList.Sorting = SortOrder.Ascending; + this.ResultsList.TabIndex = 2; + this.ResultsList.View = View.Details; + this.ResultsList.MouseDown += new MouseEventHandler(this.SimpleResultsList_MouseDown); + this.ResultsList.DoubleClick += new EventHandler(this.ResultsList_DoubleClick); + this.ResultsList.ColumnClick += new ColumnClickEventHandler(this.SimpleResultsList_ColumnClick); + this.NameHdr.Text = "Result"; + this.NameHdr.Width = 150; + this.TypeHdr.Text = "Type"; + this.TypeHdr.Width = 90; + this.DetailsHdr.Text = "Source"; + this.DetailsHdr.Width = 90; + this.Splitter.Location = new Point(192, 0); + this.Splitter.Name = "Splitter"; + this.Splitter.Size = new Size(3, 214); + this.Splitter.TabIndex = 1; + this.Splitter.TabStop = false; + this.SearchPanel.BorderStyle = BorderStyle.Fixed3D; + this.SearchPanel.Controls.AddRange(new Control[4] + { + (Control) this.NegateBox, + (Control) this.CaseSensitiveBox, + (Control) this.SearchTextBox, + (Control) this.SearchForLbl + }); + this.SearchPanel.Dock = DockStyle.Left; + this.SearchPanel.Name = "SearchPanel"; + this.SearchPanel.Size = new Size(192, 214); + this.SearchPanel.TabIndex = 0; + this.NegateBox.Anchor = AnchorStyles.Top | AnchorStyles.Left | AnchorStyles.Right; + this.NegateBox.Location = new Point(16, 120); + this.NegateBox.Name = "NegateBox"; + this.NegateBox.Size = new Size(152, 32); + this.NegateBox.TabIndex = 3; + this.NegateBox.Text = "Search for items which do NOT contain this text"; + this.NegateBox.CheckedChanged += new EventHandler(this.NegateBox_CheckedChanged); + this.CaseSensitiveBox.Font = new Font("Tahoma", 11f, FontStyle.Regular, GraphicsUnit.World); + this.CaseSensitiveBox.Location = new Point(16, 88); + this.CaseSensitiveBox.Name = "CaseSensitiveBox"; + this.CaseSensitiveBox.Size = new Size(96, 24); + this.CaseSensitiveBox.TabIndex = 2; + this.CaseSensitiveBox.Text = "Case-sensitive"; + this.CaseSensitiveBox.CheckedChanged += new EventHandler(this.CaseSensitiveBox_CheckedChanged); + this.SearchTextBox.Anchor = AnchorStyles.Top | AnchorStyles.Left | AnchorStyles.Right; + this.SearchTextBox.Location = new Point(16, 56); + this.SearchTextBox.Name = "SearchTextBox"; + this.SearchTextBox.Size = new Size(156, 21); + this.SearchTextBox.TabIndex = 1; + this.SearchTextBox.Text = ""; + this.SearchTextBox.TextChanged += new EventHandler(this.SearchTextBox_TextChanged); + this.SearchForLbl.Anchor = AnchorStyles.Top | AnchorStyles.Left | AnchorStyles.Right; + this.SearchForLbl.Location = new Point(16, 16); + this.SearchForLbl.Name = "SearchForLbl"; + this.SearchForLbl.Size = new Size(152, 32); + this.SearchForLbl.TabIndex = 0; + this.SearchForLbl.Text = "Search for items containing the following text:"; + this.SearchForLbl.TextAlign = ContentAlignment.MiddleLeft; + this.NewSearchBtn.ImageIndex = 0; + this.NewSearchBtn.ToolTipText = "New Search"; + this.ToolBar.Appearance = ToolBarAppearance.Flat; + this.ToolBar.Buttons.AddRange(new ToolBarButton[1] + { + this.NewSearchBtn + }); + this.ToolBar.ButtonSize = new Size(23, 22); + this.ToolBar.DropDownArrows = true; + this.ToolBar.Font = new Font("Tahoma", 11f, FontStyle.Regular, GraphicsUnit.World); + this.ToolBar.ImageList = this.ToolbarImages; + this.ToolBar.Name = "ToolBar"; + this.ToolBar.ShowToolTips = true; + this.ToolBar.Size = new Size(560, 25); + this.ToolBar.TabIndex = 0; + this.ToolBar.ButtonClick += new ToolBarButtonClickEventHandler(this.ToolBar_ButtonClick); + this.Controls.AddRange(new Control[2] + { + (Control) this.TypePages, + (Control) this.ToolBar + }); + this.Font = new Font("Tahoma", 11f, FontStyle.Regular, GraphicsUnit.World); + this.Name = nameof(SearchPage); + this.Size = new Size(560, 264); + this.StandardPage.ResumeLayout(false); + this.SearchPanel.ResumeLayout(false); + this.ResumeLayout(false); + } + + public string Title + { + get + { + return "Search"; + } + } + + public bool IsObsolete + { + get + { + return false; + } + } + + public void UpdateUI() + { + this.ResultOpen.Enabled = this.SelectedResult != null; + this.ResultProperties.Enabled = this.SelectedResult != null; + this.NewSearchBtn.Enabled = true; + } + + public void UpdateData() + { + this.update_simple_page(); + } + + public string SimpleText + { + get + { + return this.SearchTextBox.Text; + } + set + { + this.SearchTextBox.Text = value; + } + } + + public bool SimpleCaseSensitive + { + get + { + return this.CaseSensitiveBox.Checked; + } + set + { + this.CaseSensitiveBox.Checked = value; + } + } + + public SearchResult SelectedResult + { + get + { + if (this.TypePages.SelectedTab == this.StandardPage && this.ResultsList.SelectedItems.Count != 0) + return this.ResultsList.SelectedItems[0].Tag as SearchResult; + return (SearchResult)null; + } + } + + public void AddCustomSearches(ICustomSearch[] array) + { + foreach (ICustomSearch customSearch in array) + { + this.fCustomSearches.Add((object)customSearch); + this.TypePages.TabPages.Add(new Crownwood.Magic.Controls.TabPage(customSearch.Name, customSearch.Control)); + customSearch.Init(); + } + if (this.TypePages.TabPages.Count <= 1) + return; + this.TypePages.HideTabsMode = Crownwood.Magic.Controls.TabControl.HideTabsModes.ShowAlways; + } + + public event ElementEventHandler ElementModified; + + public event ElementEventHandler ElementActivated; + + public event TimelineEventHandler TimelineModified; + + public event TimelineEventHandler TimelineActivated; + + public event StructureEventHandler StructureActivated; + + public event StructureEventHandler StructureModified; + + protected void OnElementModified(ElementEventArgs e) + { + try + { + if (this.ElementModified == null) + return; + this.ElementModified((object)this, e); + } + catch (Exception ex) + { + LabyrinthData.Log((object)ex); + } + } + + protected void OnElementActivated(ElementEventArgs e) + { + try + { + if (this.ElementActivated == null) + return; + this.ElementActivated((object)this, e); + } + catch (Exception ex) + { + LabyrinthData.Log((object)ex); + } + } + + protected void OnTimelineModified(TimelineEventArgs e) + { + try + { + if (this.TimelineModified == null) + return; + this.TimelineModified((object)this, e); + } + catch (Exception ex) + { + LabyrinthData.Log((object)ex); + } + } + + protected void OnTimelineActivated(TimelineEventArgs e) + { + try + { + if (this.TimelineActivated == null) + return; + this.TimelineActivated((object)this, e); + } + catch (Exception ex) + { + LabyrinthData.Log((object)ex); + } + } + + protected void OnStructureActivated(StructureEventArgs e) + { + try + { + if (this.StructureActivated == null) + return; + this.StructureActivated((object)this, e); + } + catch (Exception ex) + { + LabyrinthData.Log((object)ex); + } + } + + protected void OnStructureModified(StructureEventArgs e) + { + try + { + if (this.StructureModified == null) + return; + this.StructureModified((object)this, e); + } + catch (Exception ex) + { + LabyrinthData.Log((object)ex); + } + } + + private void ResultsList_DoubleClick(object sender, EventArgs e) + { + if (this.SelectedResult == null) + return; + this.ResultOpen_Click(sender, e); + } + + private void SimpleResultsList_MouseDown(object sender, MouseEventArgs e) + { + this.ResultsList.SelectedItems.Clear(); + ListViewItem itemAt = this.ResultsList.GetItemAt(e.X, e.Y); + if (itemAt != null) + itemAt.Selected = true; + this.UpdateUI(); + } + + private void update_simple_page() + { + string text = this.SearchTextBox.Text; + bool casesensitive = this.CaseSensitiveBox.Checked; + bool negated = this.NegateBox.Checked; + if (text != "") + { + try + { + this.Cursor = Cursors.WaitCursor; + this.update_results(LabyrinthData.Project.PerformSearch(text.Split((char[])null), casesensitive, negated), this.ResultsList); + } + finally + { + this.Cursor = Cursors.Default; + } + } + else + this.ResultsList.Items.Clear(); + } + + private void update_results(SearchResult[] results, ListView control) + { + control.BeginUpdate(); + control.Items.Clear(); + if (results.Length != 0) + { + ArrayList arrayList = new ArrayList(); + foreach (SearchResult result in results) + arrayList.Add((object)new ListViewItem(result.Data.ToString()) + { + SubItems = { + result.Data.GetType().Name, + result.Details != null ? result.Details.ToString() : "" + }, + ImageIndex = LabyrinthData.GetImageIndex(result.Data), + Tag = (object)result + }); + control.Items.AddRange((ListViewItem[])arrayList.ToArray(typeof(ListViewItem))); + } + else + { + ListViewItem listViewItem = control.Items.Add("No results were found."); + listViewItem.ImageIndex = 0; + listViewItem.ForeColor = SystemColors.GrayText; + } + control.EndUpdate(); + } + + private void ResultOpen_Click(object sender, EventArgs e) + { + if (this.SelectedResult == null) + return; + Element data1 = this.SelectedResult.Data as Element; + if (data1 != null) + { + this.OnElementActivated(new ElementEventArgs(data1)); + } + else + { + Structure data2 = this.SelectedResult.Data as Structure; + if (data2 != null) + { + this.OnStructureActivated(new StructureEventArgs(data2)); + } + else + { + Timeline data3 = this.SelectedResult.Data as Timeline; + if (data3 != null) + { + this.OnTimelineActivated(new TimelineEventArgs(data3)); + } + else + { + Annotation data4 = this.SelectedResult.Data as Annotation; + if (data4 != null) + { + Element details1 = this.SelectedResult.Details as Element; + Timeline details2 = this.SelectedResult.Details as Timeline; + if (details1 != null) + this.OnElementActivated(new ElementEventArgs(details1)); + else if (details2 != null) + this.OnTimelineActivated(new TimelineEventArgs(details2)); + else + this.open_annotation(data4); + } + else + { + Labyrinth.Plot.Link data5 = this.SelectedResult.Data as Labyrinth.Plot.Link; + if (data5 == null) + return; + Structure details = this.SelectedResult.Details as Structure; + if (details != null) + this.OnStructureActivated(new StructureEventArgs(details)); + else + this.open_link(data5); + } + } + } + } + } + + private void ResultProperties_Click(object sender, EventArgs e) + { + if (this.SelectedResult == null) + return; + Element data1 = this.SelectedResult.Data as Element; + if (data1 != null) + { + this.open_element(data1); + } + else + { + Structure data2 = this.SelectedResult.Data as Structure; + if (data2 != null) + { + this.open_structure(data2); + } + else + { + Timeline data3 = this.SelectedResult.Data as Timeline; + if (data3 != null) + { + this.open_timeline(data3); + } + else + { + Annotation data4 = this.SelectedResult.Data as Annotation; + if (data4 != null) + { + this.open_annotation(data4); + } + else + { + Labyrinth.Plot.Link data5 = this.SelectedResult.Data as Labyrinth.Plot.Link; + if (data5 == null) + return; + this.open_link(data5); + } + } + } + } + } + + private void open_element(Element e) + { + if (new ElementDlg(e).ShowDialog() != DialogResult.OK) + return; + this.OnElementModified(new ElementEventArgs(e)); + } + + private void open_structure(Structure s) + { + if (new StructureDlg(s).ShowDialog() != DialogResult.OK) + return; + this.OnStructureModified(new StructureEventArgs(s)); + } + + private void open_timeline(Timeline tl) + { + if (new TimelineDlg(tl).ShowDialog() != DialogResult.OK) + return; + this.OnTimelineModified(new TimelineEventArgs(tl)); + } + + private void open_annotation(Annotation note) + { + if (!Annotations.Open(note)) + return; + foreach (Element element in LabyrinthData.Project.Elements) + { + if (element.Annotations.Contains(note)) + { + this.OnElementModified(new ElementEventArgs(element)); + return; + } + } + foreach (Timeline timeline in LabyrinthData.Project.Timelines) + { + foreach (TimelinePoint point in timeline.Points) + { + foreach (TimelineItem timelineItem in point.Items) + { + if (timelineItem.Annotation == note) + { + this.OnTimelineModified(new TimelineEventArgs(timeline)); + return; + } + } + } + } + } + + private void open_link(Labyrinth.Plot.Link l) + { + if (new LinkDlg(l).ShowDialog() != DialogResult.OK) + return; + foreach (Structure structure in LabyrinthData.Project.Structures) + { + if (structure.Links.Contains(l)) + { + this.OnStructureModified(new StructureEventArgs(structure)); + break; + } + } + } + + private void ToolBar_ButtonClick(object sender, ToolBarButtonClickEventArgs e) + { + try + { + if (e.Button != this.NewSearchBtn) + return; + this.SearchTextBox.Text = ""; + this.CaseSensitiveBox.Checked = false; + this.update_simple_page(); + foreach (ICustomSearch fCustomSearch in this.fCustomSearches) + fCustomSearch.Clear(); + } + catch (Exception ex) + { + LabyrinthData.Log((object)ex); + } + } + + private void SearchTextBox_TextChanged(object sender, EventArgs e) + { + this.update_simple_page(); + } + + private void CaseSensitiveBox_CheckedChanged(object sender, EventArgs e) + { + this.update_simple_page(); + } + + private void NegateBox_CheckedChanged(object sender, EventArgs e) + { + this.update_simple_page(); + } + + private void SimpleResultsList_ColumnClick(object sender, ColumnClickEventArgs e) + { + ListViewSorter.Sort(this.ResultsList, e.Column); + } + } +} \ No newline at end of file diff --git a/Labyrinth3/IDE/Pages/SearchPage.resx b/Labyrinth3/IDE/Pages/SearchPage.resx new file mode 100644 index 0000000..0164f49 --- /dev/null +++ b/Labyrinth3/IDE/Pages/SearchPage.resx @@ -0,0 +1,182 @@ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + text/microsoft-resx + + + 2.0 + + + System.Resources.ResXResourceReader, System.Windows.Forms, Version=4.0.0.0, Culture=neutral, PublicKeyToken=b77a5c561934e089 + + + System.Resources.ResXResourceWriter, System.Windows.Forms, Version=4.0.0.0, Culture=neutral, PublicKeyToken=b77a5c561934e089 + + + SearchPage + + + + 17, 17 + + + 143, 17 + + + + True + + + 63 + + + + AAEAAAD/////AQAAAAAAAAAMAgAAAFdTeXN0ZW0uV2luZG93cy5Gb3JtcywgVmVyc2lvbj00LjAuMC4w + LCBDdWx0dXJlPW5ldXRyYWwsIFB1YmxpY0tleVRva2VuPWI3N2E1YzU2MTkzNGUwODkFAQAAACZTeXN0 + ZW0uV2luZG93cy5Gb3Jtcy5JbWFnZUxpc3RTdHJlYW1lcgEAAAAERGF0YQcCAgAAAAkDAAAADwMAAACq + CAAAAk1TRnQBSQFMAgEBBAEAAQkBAAEIAQABEAEAARABAAT/AQkBEAj/AUIBTQE2AQQGAAE2AQQCAAEo + AwABQAMAASADAAEBAQABCAYAAQgYAAGAAgABgAMAAoABAAGAAwABgAEAAYABAAKAAgADwAEAAcAB3AHA + AQAB8AHKAaYBAAEzBQABMwEAATMBAAEzAQACMwIAAxYBAAMcAQADIgEAAykBAANVAQADTQEAA0IBAAM5 + AQABgAF8Af8BAAJQAf8BAAGTAQAB1gEAAf8B7AHMAQABxgHWAe8BAAHWAucBAAGQAakBrQIAAf8BMwMA + AWYDAAGZAwABzAIAATMDAAIzAgABMwFmAgABMwGZAgABMwHMAgABMwH/AgABZgMAAWYBMwIAAmYCAAFm + AZkCAAFmAcwCAAFmAf8CAAGZAwABmQEzAgABmQFmAgACmQIAAZkBzAIAAZkB/wIAAcwDAAHMATMCAAHM + AWYCAAHMAZkCAALMAgABzAH/AgAB/wFmAgAB/wGZAgAB/wHMAQABMwH/AgAB/wEAATMBAAEzAQABZgEA + ATMBAAGZAQABMwEAAcwBAAEzAQAB/wEAAf8BMwIAAzMBAAIzAWYBAAIzAZkBAAIzAcwBAAIzAf8BAAEz + AWYCAAEzAWYBMwEAATMCZgEAATMBZgGZAQABMwFmAcwBAAEzAWYB/wEAATMBmQIAATMBmQEzAQABMwGZ + AWYBAAEzApkBAAEzAZkBzAEAATMBmQH/AQABMwHMAgABMwHMATMBAAEzAcwBZgEAATMBzAGZAQABMwLM + AQABMwHMAf8BAAEzAf8BMwEAATMB/wFmAQABMwH/AZkBAAEzAf8BzAEAATMC/wEAAWYDAAFmAQABMwEA + AWYBAAFmAQABZgEAAZkBAAFmAQABzAEAAWYBAAH/AQABZgEzAgABZgIzAQABZgEzAWYBAAFmATMBmQEA + AWYBMwHMAQABZgEzAf8BAAJmAgACZgEzAQADZgEAAmYBmQEAAmYBzAEAAWYBmQIAAWYBmQEzAQABZgGZ + AWYBAAFmApkBAAFmAZkBzAEAAWYBmQH/AQABZgHMAgABZgHMATMBAAFmAcwBmQEAAWYCzAEAAWYBzAH/ + AQABZgH/AgABZgH/ATMBAAFmAf8BmQEAAWYB/wHMAQABzAEAAf8BAAH/AQABzAEAApkCAAGZATMBmQEA + AZkBAAGZAQABmQEAAcwBAAGZAwABmQIzAQABmQEAAWYBAAGZATMBzAEAAZkBAAH/AQABmQFmAgABmQFm + ATMBAAGZATMBZgEAAZkBZgGZAQABmQFmAcwBAAGZATMB/wEAApkBMwEAApkBZgEAA5kBAAKZAcwBAAKZ + Af8BAAGZAcwCAAGZAcwBMwEAAWYBzAFmAQABmQHMAZkBAAGZAswBAAGZAcwB/wEAAZkB/wIAAZkB/wEz + AQABmQHMAWYBAAGZAf8BmQEAAZkB/wHMAQABmQL/AQABzAMAAZkBAAEzAQABzAEAAWYBAAHMAQABmQEA + AcwBAAHMAQABmQEzAgABzAIzAQABzAEzAWYBAAHMATMBmQEAAcwBMwHMAQABzAEzAf8BAAHMAWYCAAHM + AWYBMwEAAZkCZgEAAcwBZgGZAQABzAFmAcwBAAGZAWYB/wEAAcwBmQIAAcwBmQEzAQABzAGZAWYBAAHM + ApkBAAHMAZkBzAEAAcwBmQH/AQACzAIAAswBMwEAAswBZgEAAswBmQEAA8wBAALMAf8BAAHMAf8CAAHM + Af8BMwEAAZkB/wFmAQABzAH/AZkBAAHMAf8BzAEAAcwC/wEAAcwBAAEzAQAB/wEAAWYBAAH/AQABmQEA + AcwBMwIAAf8CMwEAAf8BMwFmAQAB/wEzAZkBAAH/ATMBzAEAAf8BMwH/AQAB/wFmAgAB/wFmATMBAAHM + AmYBAAH/AWYBmQEAAf8BZgHMAQABzAFmAf8BAAH/AZkCAAH/AZkBMwEAAf8BmQFmAQAB/wKZAQAB/wGZ + AcwBAAH/AZkB/wEAAf8BzAIAAf8BzAEzAQAB/wHMAWYBAAH/AcwBmQEAAf8CzAEAAf8BzAH/AQAC/wEz + AQABzAH/AWYBAAL/AZkBAAL/AcwBAAJmAf8BAAFmAf8BZgEAAWYC/wEAAf8CZgEAAf8BZgH/AQAC/wFm + AQABIQEAAaUBAANfAQADdwEAA4YBAAOWAQADywEAA7IBAAPXAQAD3QEAA+MBAAPqAQAD8QEAA/gBAAHw + AfsB/wEAAaQCoAEAA4ADAAH/AgAB/wMAAv8BAAH/AwAB/wEAAf8BAAL/AgAD//8A/wD/AP8AtgAK/wYA + Af8JAAH/JQAB/wIAAf8FAAH/BgAB/wkAAf8LAAL/GAAK/xwAAv8YAAH/AgAB/wUAAf8HAAH/BgAB/w0A + Av8YAAr/BwAB/wMAAQcCAAH/CgAI/xUAB/8BAAL/BwAB/wMAAQcCAAH/CgAI/xUAAf8CAAP/AQABBwEA + Af8cAAL/GAAB/wEAAQcBAAH/AQABBwEAAQcEAAIEAwAB/wUAAf8NAAL/GAAC/wEAAQcBAAEHAQABBwEA + AwcBAAIEFwAC/xwAAQcBAAEHAQAFBwIENgABBwEABgcCBAQAAf8FAAH/LAAGBwEAAgQ+AAIEQAABQgFN + AT4HAAE+AwABKAMAAUADAAEgAwABAQEAAQEGAAEBFgAD/4EADv8BAAEPAQcBwQL/Ae8B/QEAAQ8BBwHB + AfwBPwHHAf8BAAEPAQcBwQH8AT8BwwH7AQABDwIBAfwBPwHjAfcBAAEPAQABAQHgAQcB8QHnAQABDwEA + AQEB4AEHAfgBzwEAAQ8BAAEBAeABBwH8AR8BAAEPAYABAwHgAQcB/gE/AQABBAHBAQcB/AE/AfwBHwIA + AcEBBwH8AT8B+AHPAgAB4wGPAfwBPwHhAecB+AEAAeMBjwL/AcMB8wH8AQAB4wGPAv8BxwH9Af4BBAj/ + FgAL + + + \ No newline at end of file diff --git a/Labyrinth3/IDE/Pages/StructurePage.cs b/Labyrinth3/IDE/Pages/StructurePage.cs new file mode 100644 index 0000000..cf36761 --- /dev/null +++ b/Labyrinth3/IDE/Pages/StructurePage.cs @@ -0,0 +1,767 @@ +// Decompiled with JetBrains decompiler +// Type: Labyrinth.Pages.StructurePage +// Assembly: Labyrinth, Version=3.6.1928.15690, Culture=neutral, PublicKeyToken=null +// MVID: 1462002E-0BD1-49D2-9B56-C22E66C903E7 +// Assembly location: C:\Dropbox\Workspace\Programs\Labyrinth\Labyrinth.exe + +using Labyrinth.Collections; +using Labyrinth.Controls; +using Labyrinth.Events; +using Labyrinth.Extensibility; +using Labyrinth.Forms; +using Labyrinth.Plot; +using System; +using System.Collections; +using System.Collections.Generic; +using System.ComponentModel; +using System.Drawing; +using System.Drawing.Imaging; +using System.Drawing.Printing; +using System.Resources; +using System.Windows.Forms; + +namespace Labyrinth.Pages +{ + public class StructurePage : UserControl, IStructurePage, IPage + { + private Structure fStructure = (Structure)null; + private int fZoom = 0; + private IContainer components; + private ToolBar ToolBar; + private ListView LinkList; + private ColumnHeader LinkTextHdr; + private Splitter ListSplitter; + private StructureView StructureView; + private ToolBarButton AddLinkBtn; + private ImageList Images; + private ContextMenu StructureContextMenu; + private ContextMenu LinkContextMenu; + private MenuItem StructureOpenElement; + private MenuItem StructureDeleteNode; + private MenuItem StructureElementProperties; + private MenuItem LinkDeleteLink; + private MenuItem LinkLinkProperties; + private ToolBarButton ExportBtn; + private ToolBarButton Sep1; + private ToolBarButton Sep2; + private ToolBarButton PrintBtn; + private ToolBarButton PrintPreviewBtn; + private ToolBarButton ShowLinksPanelBtn; + private ToolBarButton ShowArrowsBtn; + private ToolBarButton ShowTextBtn; + private ColumnHeader FromHdr; + private ColumnHeader ToHdr; + private MenuItem LinkReverseLink; + private Panel StructurePanel; + private ToolBarButton Sep3; + private ToolBarButton ZoomInBtn; + private ToolBarButton ZoomOutBtn; + private ToolBarButton PropertiesBtn; + + public StructurePage(Structure s) + { + this.InitializeComponent(); + this.LinkList.ListViewItemSorter = (IComparer)new ListViewSorter(); + this.fStructure = s; + this.StructureView.Location = new Point(0, 0); + this.StructureView.Structure = this.fStructure; + this.LinkList.Visible = false; + this.ListSplitter.Visible = false; + this.UpdateData(); + } + + protected override void Dispose(bool disposing) + { + if (disposing && this.components != null) + this.components.Dispose(); + base.Dispose(disposing); + } + + private void InitializeComponent() + { + this.components = (IContainer)new Container(); + ResourceManager resourceManager = new ResourceManager(typeof(StructurePage)); + this.Images = new ImageList(this.components); + this.ToolBar = new ToolBar(); + this.PropertiesBtn = new ToolBarButton(); + this.Sep1 = new ToolBarButton(); + this.AddLinkBtn = new ToolBarButton(); + this.ShowLinksPanelBtn = new ToolBarButton(); + this.ShowArrowsBtn = new ToolBarButton(); + this.ShowTextBtn = new ToolBarButton(); + this.Sep2 = new ToolBarButton(); + this.PrintBtn = new ToolBarButton(); + this.PrintPreviewBtn = new ToolBarButton(); + this.ExportBtn = new ToolBarButton(); + this.LinkList = new ListView(); + this.FromHdr = new ColumnHeader(); + this.ToHdr = new ColumnHeader(); + this.LinkTextHdr = new ColumnHeader(); + this.LinkContextMenu = new ContextMenu(); + this.LinkReverseLink = new MenuItem(); + this.LinkDeleteLink = new MenuItem(); + this.LinkLinkProperties = new MenuItem(); + this.ListSplitter = new Splitter(); + this.StructureView = new StructureView(); + this.StructureContextMenu = new ContextMenu(); + this.StructureOpenElement = new MenuItem(); + this.StructureDeleteNode = new MenuItem(); + this.StructureElementProperties = new MenuItem(); + this.StructurePanel = new Panel(); + this.Sep3 = new ToolBarButton(); + this.ZoomInBtn = new ToolBarButton(); + this.ZoomOutBtn = new ToolBarButton(); + this.StructurePanel.SuspendLayout(); + this.SuspendLayout(); + this.Images.ColorDepth = ColorDepth.Depth8Bit; + this.Images.ImageSize = new Size(16, 16); + this.Images.ImageStream = (ImageListStreamer)resourceManager.GetObject("Images.ImageStream"); + this.Images.TransparentColor = Color.Magenta; + this.ToolBar.Appearance = ToolBarAppearance.Flat; + this.ToolBar.Buttons.AddRange(new ToolBarButton[13] + { + this.PropertiesBtn, + this.Sep1, + this.AddLinkBtn, + this.ShowLinksPanelBtn, + this.ShowArrowsBtn, + this.ShowTextBtn, + this.Sep2, + this.PrintBtn, + this.PrintPreviewBtn, + this.ExportBtn, + this.Sep3, + this.ZoomInBtn, + this.ZoomOutBtn + }); + this.ToolBar.DropDownArrows = true; + this.ToolBar.ImageList = this.Images; + this.ToolBar.Name = "ToolBar"; + this.ToolBar.ShowToolTips = true; + this.ToolBar.Size = new Size(448, 25); + this.ToolBar.TabIndex = 0; + this.ToolBar.ButtonClick += new ToolBarButtonClickEventHandler(this.ToolBar_ButtonClick); + this.PropertiesBtn.ImageIndex = 0; + this.Sep1.Style = ToolBarButtonStyle.Separator; + this.AddLinkBtn.ImageIndex = 3; + this.AddLinkBtn.ToolTipText = "Add Link"; + this.ShowLinksPanelBtn.ImageIndex = 4; + this.ShowLinksPanelBtn.ToolTipText = "Show Links Panel"; + this.ShowArrowsBtn.ImageIndex = 5; + this.ShowArrowsBtn.ToolTipText = "Show Arrows"; + this.ShowTextBtn.ImageIndex = 6; + this.ShowTextBtn.ToolTipText = "Show Link Text"; + this.Sep2.Style = ToolBarButtonStyle.Separator; + this.PrintBtn.ImageIndex = 1; + this.PrintBtn.ToolTipText = "Print"; + this.PrintPreviewBtn.ImageIndex = 2; + this.PrintPreviewBtn.ToolTipText = "Print Preview"; + this.ExportBtn.ImageIndex = 7; + this.ExportBtn.ToolTipText = "Export Structure"; + this.LinkList.Columns.AddRange(new ColumnHeader[3] + { + this.FromHdr, + this.ToHdr, + this.LinkTextHdr + }); + this.LinkList.ContextMenu = this.LinkContextMenu; + this.LinkList.Dock = DockStyle.Bottom; + this.LinkList.FullRowSelect = true; + this.LinkList.Location = new Point(0, 176); + this.LinkList.Name = "LinkList"; + this.LinkList.Size = new Size(448, 88); + this.LinkList.SmallImageList = this.Images; + this.LinkList.Sorting = SortOrder.Ascending; + this.LinkList.TabIndex = 3; + this.LinkList.View = View.Details; + this.LinkList.MouseDown += new MouseEventHandler(this.LinkList_MouseDown); + this.LinkList.DoubleClick += new EventHandler(this.LinkList_DoubleClick); + this.LinkList.ColumnClick += new ColumnClickEventHandler(this.LinkList_ColumnClick); + this.FromHdr.Text = "From"; + this.FromHdr.Width = 120; + this.ToHdr.Text = "To"; + this.ToHdr.Width = 120; + this.LinkTextHdr.Text = "Link Text"; + this.LinkTextHdr.Width = 180; + this.LinkContextMenu.MenuItems.AddRange(new MenuItem[3] + { + this.LinkReverseLink, + this.LinkDeleteLink, + this.LinkLinkProperties + }); + this.LinkReverseLink.Index = 0; + this.LinkReverseLink.Text = "Reverse Link"; + this.LinkReverseLink.Click += new EventHandler(this.LinkReverseLink_Click); + this.LinkDeleteLink.Index = 1; + this.LinkDeleteLink.Text = "Delete Link"; + this.LinkDeleteLink.Click += new EventHandler(this.LinkDeleteLink_Click); + this.LinkLinkProperties.Index = 2; + this.LinkLinkProperties.Text = "Link Properties"; + this.LinkLinkProperties.Click += new EventHandler(this.LinkLinkProperties_Click); + this.ListSplitter.Dock = DockStyle.Bottom; + this.ListSplitter.Location = new Point(0, 173); + this.ListSplitter.Name = "ListSplitter"; + this.ListSplitter.Size = new Size(448, 3); + this.ListSplitter.TabIndex = 2; + this.ListSplitter.TabStop = false; + this.StructureView.AddingLink = false; + this.StructureView.AllowDrop = true; + this.StructureView.BackColor = SystemColors.ControlDark; + this.StructureView.ContextMenu = this.StructureContextMenu; + this.StructureView.Location = new Point(8, 8); + this.StructureView.Name = "StructureView"; + this.StructureView.ShowArrows = true; + this.StructureView.ShowText = true; + this.StructureView.Size = new Size(328, 103); + this.StructureView.Structure = (Structure)null; + this.StructureView.TabIndex = 1; + this.StructureView.StructureModified += new EventHandler(this.StructureView_StructureModified); + this.StructureView.DragDrop += new DragEventHandler(this.StructureView_DragDrop); + this.StructureView.DoubleClick += new EventHandler(this.StructureView_DoubleClick); + this.StructureView.DragOver += new DragEventHandler(this.StructureView_DragOver); + this.StructureContextMenu.MenuItems.AddRange(new MenuItem[3] + { + this.StructureOpenElement, + this.StructureDeleteNode, + this.StructureElementProperties + }); + this.StructureOpenElement.Index = 0; + this.StructureOpenElement.Text = "Open Element"; + this.StructureOpenElement.Click += new EventHandler(this.StructureOpenElement_Click); + this.StructureDeleteNode.Index = 1; + this.StructureDeleteNode.Text = "Remove Element"; + this.StructureDeleteNode.Click += new EventHandler(this.StructureDeleteNode_Click); + this.StructureElementProperties.Index = 2; + this.StructureElementProperties.Text = "Element Properties"; + this.StructureElementProperties.Click += new EventHandler(this.StructureElementProperties_Click); + this.StructurePanel.AutoScroll = true; + this.StructurePanel.Controls.AddRange(new Control[1] + { + (Control) this.StructureView + }); + this.StructurePanel.Dock = DockStyle.Fill; + this.StructurePanel.Location = new Point(0, 25); + this.StructurePanel.Name = "StructurePanel"; + this.StructurePanel.Size = new Size(448, 148); + this.StructurePanel.TabIndex = 4; + this.StructurePanel.Layout += new LayoutEventHandler(this.StructurePanel_Layout); + this.Sep3.Style = ToolBarButtonStyle.Separator; + this.ZoomInBtn.ImageIndex = 8; + this.ZoomInBtn.ToolTipText = "Zoom In"; + this.ZoomOutBtn.ImageIndex = 9; + this.ZoomOutBtn.ToolTipText = "Zoom Out"; + this.Controls.AddRange(new Control[4] + { + (Control) this.StructurePanel, + (Control) this.ListSplitter, + (Control) this.LinkList, + (Control) this.ToolBar + }); + this.Font = new Font("Tahoma", 11f, FontStyle.Regular, GraphicsUnit.World); + this.Name = nameof(StructurePage); + this.Size = new Size(448, 264); + this.StructurePanel.ResumeLayout(false); + this.ResumeLayout(false); + } + + public string Title + { + get + { + return this.fStructure.Name; + } + } + + public bool IsObsolete + { + get + { + return LabyrinthData.Project.Structures.IndexOf(this.fStructure) == -1; + } + } + + public void UpdateUI() + { + this.PropertiesBtn.Enabled = true; + this.PrintBtn.Enabled = true; + this.PrintPreviewBtn.Enabled = true; + this.AddLinkBtn.Enabled = this.fStructure.Nodes.Count >= 2; + this.AddLinkBtn.Pushed = this.StructureView.AddingLink; + this.ShowLinksPanelBtn.Enabled = true; + this.ShowLinksPanelBtn.Pushed = this.LinkList.Visible; + this.ShowArrowsBtn.Enabled = true; + this.ShowArrowsBtn.Pushed = this.StructureView.ShowArrows; + this.ShowTextBtn.Enabled = true; + this.ShowTextBtn.Pushed = this.StructureView.ShowText; + this.ExportBtn.Enabled = true; + this.ZoomInBtn.Enabled = true; + this.ZoomOutBtn.Enabled = this.fZoom != 0; + this.StructureOpenElement.Enabled = this.StructureView.SelectedNode != null; + this.StructureDeleteNode.Enabled = this.StructureView.SelectedNode != null; + this.StructureElementProperties.Enabled = this.StructureView.SelectedNode != null; + this.LinkDeleteLink.Enabled = this.SelectedLink != null; + this.LinkLinkProperties.Enabled = this.SelectedLink != null; + } + + public void UpdateData() + { + this.StructureView.Refresh(); + this.update_links(); + } + + public Structure Structure + { + get + { + return this.fStructure; + } + } + + public Node SelectedNode + { + get + { + return this.StructureView.SelectedNode; + } + } + + public Labyrinth.Plot.Link SelectedLink + { + get + { + if (this.LinkList.SelectedItems.Count != 0) + return this.LinkList.SelectedItems[0].Tag as Labyrinth.Plot.Link; + return (Labyrinth.Plot.Link)null; + } + } + + public int Zoom + { + get + { + return this.fZoom; + } + set + { + if (this.fZoom == value) + return; + this.fZoom = value; + this.resize_structure(); + } + } + + public event StructureEventHandler StructureModified; + + public event ElementEventHandler ElementActivated; + + public event ElementEventHandler ElementModified; + + protected void OnStructureModified(StructureEventArgs e) + { + try + { + if (this.StructureModified == null) + return; + this.StructureModified((object)this, e); + } + catch (Exception ex) + { + LabyrinthData.Log((object)ex); + } + } + + protected void OnElementActivated(ElementEventArgs e) + { + try + { + if (this.ElementActivated == null) + return; + this.ElementActivated((object)this, e); + } + catch (Exception ex) + { + LabyrinthData.Log((object)ex); + } + } + + protected void OnElementModified(ElementEventArgs e) + { + try + { + if (this.ElementModified == null) + return; + this.ElementModified((object)this, e); + } + catch (Exception ex) + { + LabyrinthData.Log((object)ex); + } + } + + private void ToolBar_ButtonClick(object sender, ToolBarButtonClickEventArgs e) + { + try + { + if (e.Button == this.PropertiesBtn) + { + if (new StructureDlg(this.fStructure).ShowDialog() != DialogResult.OK) + return; + this.UpdateData(); + this.OnStructureModified(new StructureEventArgs(this.fStructure)); + } + else if (e.Button == this.AddLinkBtn) + this.StructureView.AddingLink = !this.StructureView.AddingLink; + else if (e.Button == this.ShowLinksPanelBtn) + { + bool visible = this.LinkList.Visible; + this.ListSplitter.Visible = !visible; + this.LinkList.Visible = !visible; + } + else if (e.Button == this.ShowArrowsBtn) + { + this.StructureView.ShowArrows = !this.StructureView.ShowArrows; + this.Refresh(); + } + else if (e.Button == this.ShowTextBtn) + { + this.StructureView.ShowText = !this.StructureView.ShowText; + this.Refresh(); + } + else if (e.Button == this.ExportBtn) + { + string str = "JPG Images|*.jpg|GIF Images|*.gif|Bitmaps|*.bmp"; + try + { + SaveFileDialog saveFileDialog = new SaveFileDialog(); + saveFileDialog.FileName = this.fStructure.Name; + saveFileDialog.Filter = str; + if (saveFileDialog.ShowDialog() != DialogResult.OK) + return; + switch (saveFileDialog.FilterIndex) + { + case 1: + this.StructureView.CreateImage().Save(saveFileDialog.FileName, ImageFormat.Jpeg); + break; + + case 2: + this.StructureView.CreateImage().Save(saveFileDialog.FileName, ImageFormat.Gif); + break; + + case 3: + this.StructureView.CreateImage().Save(saveFileDialog.FileName, ImageFormat.Bmp); + break; + } + } + catch (Exception ex) + { + LabyrinthData.Log((object)ex); + } + } + else if (e.Button == this.PrintBtn) + { + PrintDialog printDialog = new PrintDialog(); + printDialog.Document = this.create_print_doc(); + if (printDialog.ShowDialog() != DialogResult.OK) + return; + for (int index = 0; index != (int)printDialog.PrinterSettings.Copies; ++index) + printDialog.Document.Print(); + } + else if (e.Button == this.PrintPreviewBtn) + { + int num = (int)new PrintPreviewDialog() + { + Document = this.create_print_doc() + }.ShowDialog(); + } + else if (e.Button == this.ZoomInBtn) + { + ++this.fZoom; + this.resize_structure(); + } + else + { + if (e.Button != this.ZoomOutBtn) + return; + --this.fZoom; + if (this.fZoom < 0) + this.fZoom = 0; + this.resize_structure(); + } + } + catch (Exception ex) + { + LabyrinthData.Log((object)ex); + } + } + + private PrintDocument create_print_doc() + { + PrintDocument printDocument = new PrintDocument(); + printDocument.DocumentName = LabyrinthData.Project.Name + ": " + this.fStructure.Name; + printDocument.PrintController = (PrintController)new StandardPrintController(); + printDocument.DefaultPageSettings = LabyrinthData.PageSettings; + printDocument.PrinterSettings = LabyrinthData.PrinterSettings; + printDocument.PrintPage += new PrintPageEventHandler(this.PrintPage); + return printDocument; + } + + private void PrintPage(object sender, PrintPageEventArgs e) + { + StringFormat format = new StringFormat(); + format.Alignment = StringAlignment.Center; + format.LineAlignment = StringAlignment.Center; + format.Trimming = StringTrimming.EllipsisCharacter; + string str = LabyrinthData.Project.Name + ": " + this.fStructure.Name; + int height = (int)e.Graphics.MeasureString(str, this.Font, e.MarginBounds.Width).Height; + RectangleF layoutRectangle; + Rectangle marginBounds1 = e.MarginBounds; + double x = (double)marginBounds1.X; + marginBounds1 = e.MarginBounds; + double y = (double)marginBounds1.Y; + marginBounds1 = e.MarginBounds; + double width = (double)marginBounds1.Width; + double num = (double)height; + layoutRectangle = new RectangleF((float)x, (float)y, (float)width, (float)num); + e.Graphics.DrawString(str, this.Font, SystemBrushes.WindowText, layoutRectangle, format); + Rectangle marginBounds2 = e.MarginBounds; + marginBounds2.Y += height; + marginBounds2.Height -= height; + this.StructureView.Render(e.Graphics, marginBounds2); + } + + private void StructureView_StructureModified(object sender, EventArgs e) + { + this.update_links(); + this.OnStructureModified(new StructureEventArgs(this.fStructure)); + } + + private void update_links() + { + this.LinkList.BeginUpdate(); + this.LinkList.Items.Clear(); + if (this.fStructure.Links.Count != 0) + { + ArrayList arrayList = new ArrayList(); + foreach (Labyrinth.Plot.Link link in this.fStructure.Links) + { + Element element1 = this.get_element(link.LHS); + Element element2 = this.get_element(link.RHS); + if (element1 != null && element2 != null) + arrayList.Add((object)new ListViewItem(element1.Name) + { + SubItems = { + element2.Name, + link.Description + }, + ImageIndex = 3, + Tag = (object)link + }); + } + this.LinkList.Items.AddRange((ListViewItem[])arrayList.ToArray(typeof(ListViewItem))); + } + else + { + ListViewItem listViewItem = this.LinkList.Items.Add("No links"); + listViewItem.ForeColor = SystemColors.GrayText; + listViewItem.ImageIndex = -1; + } + this.LinkList.EndUpdate(); + } + + private Element get_element(Guid id) + { + int index = LabyrinthData.Project.Elements.IndexOf(id); + if (index != -1) + return LabyrinthData.Project.Elements[index]; + return (Element)null; + } + + private void StructureOpenElement_Click(object sender, EventArgs e) + { + if (this.StructureView.SelectedNode == null) + return; + Element element = this.get_element(this.StructureView.SelectedNode.ElementID); + if (element == null) + return; + this.OnElementActivated(new ElementEventArgs(element)); + } + + private void StructureDeleteNode_Click(object sender, EventArgs e) + { + if (this.StructureView.SelectedNode == null || MessageBox.Show("Delete reference: are you sure?" + "\n" + "The element will not be deleted.", "Labyrinth", MessageBoxButtons.YesNo, MessageBoxIcon.Question) != DialogResult.Yes) + return; + this.fStructure.RemoveElement(this.StructureView.SelectedNode.ElementID); + this.StructureView.Refresh(); + this.update_links(); + this.OnStructureModified(new StructureEventArgs(this.fStructure)); + } + + private void StructureElementProperties_Click(object sender, EventArgs e) + { + if (this.StructureView.SelectedNode == null) + return; + Element element = this.get_element(this.StructureView.SelectedNode.ElementID); + if (element == null || new ElementDlg(element).ShowDialog() != DialogResult.OK) + return; + this.StructureView.Refresh(); + this.update_links(); + this.OnElementModified(new ElementEventArgs(element)); + } + + private void LinkReverseLink_Click(object sender, EventArgs e) + { + if (this.SelectedLink == null) + return; + Guid lhs = this.SelectedLink.LHS; + this.SelectedLink.LHS = this.SelectedLink.RHS; + this.SelectedLink.RHS = lhs; + this.StructureView.Refresh(); + this.update_links(); + this.OnStructureModified(new StructureEventArgs(this.fStructure)); + } + + private void LinkDeleteLink_Click(object sender, EventArgs e) + { + if (this.SelectedLink == null || MessageBox.Show("Delete link: are you sure?", "Labyrinth", MessageBoxButtons.YesNo, MessageBoxIcon.Question) != DialogResult.Yes) + return; + this.fStructure.Links.Remove(this.SelectedLink); + this.StructureView.Refresh(); + this.update_links(); + this.OnStructureModified(new StructureEventArgs(this.fStructure)); + } + + private void LinkLinkProperties_Click(object sender, EventArgs e) + { + if (this.SelectedLink == null || new LinkDlg(this.SelectedLink).ShowDialog() != DialogResult.OK) + return; + this.StructureView.Refresh(); + this.update_links(); + this.OnStructureModified(new StructureEventArgs(this.fStructure)); + } + + private void StructureView_DoubleClick(object sender, EventArgs e) + { + if (this.StructureView.SelectedNode == null) + return; + this.StructureOpenElement_Click(sender, e); + } + + private void LinkList_DoubleClick(object sender, EventArgs e) + { + if (this.SelectedLink == null) + return; + this.LinkLinkProperties_Click(sender, e); + } + + private void LinkList_MouseDown(object sender, MouseEventArgs e) + { + this.LinkList.SelectedItems.Clear(); + ListViewItem itemAt = this.LinkList.GetItemAt(e.X, e.Y); + if (itemAt != null) + itemAt.Selected = true; + this.UpdateUI(); + } + + private void StructureView_DragOver(object sender, DragEventArgs e) + { + e.Effect = DragDropEffects.None; + Element data1 = e.Data.GetData(typeof(Element)) as Element; + Structure data2 = e.Data.GetData(typeof(Structure)) as Structure; + Timeline data3 = e.Data.GetData(typeof(Timeline)) as Timeline; + if (data1 == null && (data2 == null || data2 == this.fStructure) && data3 == null) + return; + e.Effect = DragDropEffects.Copy; + } + + private void StructureView_DragDrop(object sender, DragEventArgs e) + { + Point client = this.StructureView.PointToClient(Cursor.Position); + bool flag = false; + Element data1 = e.Data.GetData(typeof(Element)) as Element; + if (data1 != null) + { + if (this.find_node(data1.ID) != null) + { + int num = (int)MessageBox.Show("This element is already part of this structure.", "Labyrinth", MessageBoxButtons.OK, MessageBoxIcon.Asterisk); + return; + } + List ids = new List(); + ids.Add(data1.ID); + flag = this.add_elements(ids, client); + } + Structure data2 = e.Data.GetData(typeof(Structure)) as Structure; + if (data2 != null) + { + if (MessageBox.Show("Do you want to add all the elements from this structure?", "Labyrinth", MessageBoxButtons.YesNo, MessageBoxIcon.Question) != DialogResult.Yes) + return; + List ids = new List(); + foreach (Node node in data2.Nodes) + { + if (this.find_node(node.ElementID) == null) + ids.Add(node.ElementID); + } + flag = this.add_elements(ids, client); + } + Timeline data3 = e.Data.GetData(typeof(Timeline)) as Timeline; + if (data3 != null) + { + if (MessageBox.Show("Do you want to add all the elements from this timeline?", "Labyrinth", MessageBoxButtons.YesNo, MessageBoxIcon.Question) != DialogResult.Yes) + return; + flag = this.add_elements(data3.ElementIDs, client); + } + if (!flag) + return; + this.Refresh(); + this.OnStructureModified(new StructureEventArgs(this.fStructure)); + } + + private bool add_elements(List ids, Point p) + { + bool flag = false; + Random random = new Random(); + foreach (Guid id in ids) + { + float x = (float)p.X / (float)this.StructureView.Width; + float y = (float)p.Y / (float)this.StructureView.Height; + if (id != ids[ids.Count - 1]) + { + float num = 0.02f; + x += (float)(random.NextDouble() * random.NextDouble() * (double)num * 2.0) - num; + y += (float)(random.NextDouble() * random.NextDouble() * (double)num * 2.0) - num; + } + this.fStructure.Nodes.Add(new Node() + { + ElementID = id, + Position = new PointF(x, y) + }); + flag = true; + } + return flag; + } + + private Node find_node(Guid element_id) + { + foreach (Node node in this.fStructure.Nodes) + { + if (node.ElementID == element_id) + return node; + } + return (Node)null; + } + + private void LinkList_ColumnClick(object sender, ColumnClickEventArgs e) + { + ListViewSorter.Sort(this.LinkList, e.Column); + } + + private void StructurePanel_Layout(object sender, LayoutEventArgs e) + { + this.resize_structure(); + } + + private void resize_structure() + { + this.StructureView.Size = new Size((int)((double)this.StructureView.Parent.Width * Math.Pow(1.1, (double)this.fZoom)), (int)((double)this.StructureView.Parent.Height * Math.Pow(1.1, (double)this.fZoom))); + } + } +} \ No newline at end of file diff --git a/Labyrinth3/IDE/Pages/StructurePage.resx b/Labyrinth3/IDE/Pages/StructurePage.resx new file mode 100644 index 0000000..c524cc4 --- /dev/null +++ b/Labyrinth3/IDE/Pages/StructurePage.resx @@ -0,0 +1,195 @@ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + text/microsoft-resx + + + 2.0 + + + System.Resources.ResXResourceReader, System.Windows.Forms, Version=4.0.0.0, Culture=neutral, PublicKeyToken=b77a5c561934e089 + + + System.Resources.ResXResourceWriter, System.Windows.Forms, Version=4.0.0.0, Culture=neutral, PublicKeyToken=b77a5c561934e089 + + + StructurePage + + + + AAEAAAD/////AQAAAAAAAAAMAgAAAFdTeXN0ZW0uV2luZG93cy5Gb3JtcywgVmVyc2lvbj00LjAuMC4w + LCBDdWx0dXJlPW5ldXRyYWwsIFB1YmxpY0tleVRva2VuPWI3N2E1YzU2MTkzNGUwODkFAQAAACZTeXN0 + ZW0uV2luZG93cy5Gb3Jtcy5JbWFnZUxpc3RTdHJlYW1lcgEAAAAERGF0YQcCAgAAAAkDAAAADwMAAADe + CwAAAk1TRnQBSQFMAgEBCgEAAQ4BAAEIAQABEAEAARABAAT/AQkBEAj/AUIBTQE2AQQGAAE2AQQCAAEo + AwABQAMAATADAAEBAQABCAYAAQwYAAGAAgABgAMAAoABAAGAAwABgAEAAYABAAKAAgADwAEAAcAB3AHA + AQAB8AHKAaYBAAEzBQABMwEAATMBAAEzAQACMwIAAxYBAAMcAQADIgEAAykBAANVAQADTQEAA0IBAAM5 + AQABgAF8Af8BAAJQAf8BAAGTAQAB1gEAAf8B7AHMAQABxgHWAe8BAAHWAucBAAGQAakBrQIAAf8BMwMA + AWYDAAGZAwABzAIAATMDAAIzAgABMwFmAgABMwGZAgABMwHMAgABMwH/AgABZgMAAWYBMwIAAmYCAAFm + AZkCAAFmAcwCAAFmAf8CAAGZAwABmQEzAgABmQFmAgACmQIAAZkBzAIAAZkB/wIAAcwDAAHMATMCAAHM + AWYCAAHMAZkCAALMAgABzAH/AgAB/wFmAgAB/wGZAgAB/wHMAQABMwH/AgAB/wEAATMBAAEzAQABZgEA + ATMBAAGZAQABMwEAAcwBAAEzAQAB/wEAAf8BMwIAAzMBAAIzAWYBAAIzAZkBAAIzAcwBAAIzAf8BAAEz + AWYCAAEzAWYBMwEAATMCZgEAATMBZgGZAQABMwFmAcwBAAEzAWYB/wEAATMBmQIAATMBmQEzAQABMwGZ + AWYBAAEzApkBAAEzAZkBzAEAATMBmQH/AQABMwHMAgABMwHMATMBAAEzAcwBZgEAATMBzAGZAQABMwLM + AQABMwHMAf8BAAEzAf8BMwEAATMB/wFmAQABMwH/AZkBAAEzAf8BzAEAATMC/wEAAWYDAAFmAQABMwEA + AWYBAAFmAQABZgEAAZkBAAFmAQABzAEAAWYBAAH/AQABZgEzAgABZgIzAQABZgEzAWYBAAFmATMBmQEA + AWYBMwHMAQABZgEzAf8BAAJmAgACZgEzAQADZgEAAmYBmQEAAmYBzAEAAWYBmQIAAWYBmQEzAQABZgGZ + AWYBAAFmApkBAAFmAZkBzAEAAWYBmQH/AQABZgHMAgABZgHMATMBAAFmAcwBmQEAAWYCzAEAAWYBzAH/ + AQABZgH/AgABZgH/ATMBAAFmAf8BmQEAAWYB/wHMAQABzAEAAf8BAAH/AQABzAEAApkCAAGZATMBmQEA + AZkBAAGZAQABmQEAAcwBAAGZAwABmQIzAQABmQEAAWYBAAGZATMBzAEAAZkBAAH/AQABmQFmAgABmQFm + ATMBAAGZATMBZgEAAZkBZgGZAQABmQFmAcwBAAGZATMB/wEAApkBMwEAApkBZgEAA5kBAAKZAcwBAAKZ + Af8BAAGZAcwCAAGZAcwBMwEAAWYBzAFmAQABmQHMAZkBAAGZAswBAAGZAcwB/wEAAZkB/wIAAZkB/wEz + AQABmQHMAWYBAAGZAf8BmQEAAZkB/wHMAQABmQL/AQABzAMAAZkBAAEzAQABzAEAAWYBAAHMAQABmQEA + AcwBAAHMAQABmQEzAgABzAIzAQABzAEzAWYBAAHMATMBmQEAAcwBMwHMAQABzAEzAf8BAAHMAWYCAAHM + AWYBMwEAAZkCZgEAAcwBZgGZAQABzAFmAcwBAAGZAWYB/wEAAcwBmQIAAcwBmQEzAQABzAGZAWYBAAHM + ApkBAAHMAZkBzAEAAcwBmQH/AQACzAIAAswBMwEAAswBZgEAAswBmQEAA8wBAALMAf8BAAHMAf8CAAHM + Af8BMwEAAZkB/wFmAQABzAH/AZkBAAHMAf8BzAEAAcwC/wEAAcwBAAEzAQAB/wEAAWYBAAH/AQABmQEA + AcwBMwIAAf8CMwEAAf8BMwFmAQAB/wEzAZkBAAH/ATMBzAEAAf8BMwH/AQAB/wFmAgAB/wFmATMBAAHM + AmYBAAH/AWYBmQEAAf8BZgHMAQABzAFmAf8BAAH/AZkCAAH/AZkBMwEAAf8BmQFmAQAB/wKZAQAB/wGZ + AcwBAAH/AZkB/wEAAf8BzAIAAf8BzAEzAQAB/wHMAWYBAAH/AcwBmQEAAf8CzAEAAf8BzAH/AQAC/wEz + AQABzAH/AWYBAAL/AZkBAAL/AcwBAAJmAf8BAAFmAf8BZgEAAWYC/wEAAf8CZgEAAf8BZgH/AQAC/wFm + AQABIQEAAaUBAANfAQADdwEAA4YBAAOWAQADywEAA7IBAAPXAQAD3QEAA+MBAAPqAQAD8QEAA/gBAAHw + AfsB/wEAAaQCoAEAA4ADAAH/AgAB/wMAAv8BAAH/AwAB/wEAAf8BAAL/AgAD/04AAgEOAAIBLQADAQ0A + AwEsAAMBDQADAScAA+wCAAMBCAAD7AIAAwEmAALsAwAC7AIBBwAC7AMAAuwCASYAAewCAAPsAgAB7AcA + AewHAAHsJwAB7AIAAewB/wHsAgAB7AcAAewHAAHsJgAB7AEAA+wB/wPsAQAB7AUAAewBAAfsAQAB7CUA + AewBAAHsBf8B7AEAAewFAAHsAQAB7AX/AewBAAHsJQAB7AEAA+wB/wPsAQAB7AUAAewBAAfsAQAB7CYA + AewCAAHsAf8B7AIAAewHAAHsBwAB7CcAAewCAAPsAgAB7AcAAewHAAHsKAAC7AMAAuwJAALsAwAC7CsA + A+wNAAPsagAM/y4AAfwFAAH/AQAB/wQAAf8DAAH/LgAC/AQADP8pAAj8AwAB/wEAAf8EAAH/AwAB/ygA + AewJ/AIADP8pAAj8AwAM7CYAAewFAAHsAQAC/AQADAcmAAHsBAAB7AIAAfwFAAwHJgAB7D4AAewFAAPs + NwAB7AIAAew8AAHsAQAB7D4AAez/AI0ACv8WAAr/FgAB/wIAAf8FAAH/BwAJBwEAAQcEAAf/GQAK/xIA + AQcDAAb/AgACBxYAAf8CAAH/BQAB/wYABgcD+wIHBQAF/wIAAgcB/hYACv8GAAYHAwACBwEAAQcDAAX/ + AQAEBxYAB/8BAAL/EgACBwIABf8BAAEHAf4CBxYAAf8CAAP/AQABBwEAAf8GAAoHAQABBwEAAQcCAAX/ + AgAC/gEHFgAB/wEAAQcBAAH/AQABBwEAAQcEAAIECwABBwEAAQcDAAb/AgACBxYAAv8BAAEHAQABBwEA + AQcBAAMHAQACBAMACP8BAAEHAQABBwIAB/8dAAEHAQABBwEABQcCBAQAAf8FAAH/BgAK/xsAAQcBAAYH + AgQEAAj/BQAH/x8ABgcBAAIEBQAB/wUAAf8FAAf/AQABByQAAgQFAAj/BAAH/1gAAUIBTQE+BwABPgMA + ASgDAAFAAwABMAMAAQEBAAEBBQABgAEBFgAD/wEABP8EAAH/AfkB/wH5BAAB/wHxAf8B8QQAAf8B4wH/ + AeMEAAH4AccB+AHHBAAB5wEPAecBDwQAAdgD3wQAAdgD3wQAAaABLwGgAS8EAAGgAS8BoAEvBAABoAEv + AaABLwQAAdgD3wQAAdgD3wQAAecBPwHnAT8EAAH4Af8B+AH/BAAE/wQAAYABAQX/AfcBgAEBAv8B6gF3 + Af8B8wGAAQEC/wHqAasB/gEBAYABAQH8Af8B4gGvAfABAAGAAQEB+wF/AeoBbwHyAQEBgAEBAfsBvwHq + AasB9wHTAYABAQH7Ad8B9gF3AfcBtwGAAQEB+wHvAv8B9gF/AYABAQH7Ae8C/wHuAQ8C/wH7Ad8C/wHt + AfMB/wHfAfsBvwH/Ad8B6wHzAfwBzwH7AX8B/AHPAccB/wHzAQcB/AH/AfMBBwHPAf8CzwL/As8D/wHf + A/8B3xL/AQABDwL/AQABDAH/Ac8BAAEPAcABBwEAAQgB/wHHAQABDwGAAQMBAAEBAfwBAwEAAQ8BAAEB + AQABAwHzAccBAAEPAQABAQEAAQMB7wHPAQABDwEAAQEBAAELAe8B/wEAAQ8DAAELAfMB/wEAAQ8DAAED + AfwBfwEAAQQBgAIAAQcB/wGfAgABwAIAAQ8B/wHvAgAB4AEBAQABDwH/Ae8B+AEAAeABBwEAAQ8B/wGf + AfwBAAHwAQcBAAEfAfABfwH+AQQB8AEDAQABPwT/AfgBAwEAAX8C/xYACw== + + + + + 56 + + + + 268, 17 + + + 17, 17 + + + 105, 17 + + \ No newline at end of file diff --git a/Labyrinth3/IDE/Pages/TaskPage.cs b/Labyrinth3/IDE/Pages/TaskPage.cs new file mode 100644 index 0000000..ae36304 --- /dev/null +++ b/Labyrinth3/IDE/Pages/TaskPage.cs @@ -0,0 +1,439 @@ +// Decompiled with JetBrains decompiler +// Type: Labyrinth.Pages.TaskPage +// Assembly: Labyrinth, Version=3.6.1928.15690, Culture=neutral, PublicKeyToken=null +// MVID: 1462002E-0BD1-49D2-9B56-C22E66C903E7 +// Assembly location: C:\Dropbox\Workspace\Programs\Labyrinth\Labyrinth.exe + +using Labyrinth.Collections; +using Labyrinth.Extensibility; +using Labyrinth.Forms; +using Labyrinth.Plot; +using System; +using System.Collections; +using System.ComponentModel; +using System.Drawing; +using System.IO; +using System.Resources; +using System.Windows.Forms; + +namespace Labyrinth.Pages +{ + public class TaskPage : UserControl, ITaskPage, IPage + { + private ToolBar ToolBar; + private ListView TaskList; + private ColumnHeader TaskHdr; + private ToolBarButton NewBtn; + private ToolBarButton DeleteBtn; + private ToolBarButton PropertiesBtn; + private ContextMenu TaskMenu; + private MenuItem TaskNew; + private MenuItem TaskProperties; + private MenuItem TaskDelete; + private ColumnHeader DeadlineHdr; + private ColumnHeader ImportanceHdr; + private ColumnHeader CompletedHdr; + private ImageList ToolbarImages; + private ToolBarButton Sep1; + private ToolBarButton ExportBtn; + private IContainer components; + + public TaskPage() + { + this.InitializeComponent(); + this.TaskList.SmallImageList = LabyrinthData.ElementImages; + this.TaskList.ListViewItemSorter = (IComparer)new ListViewSorter(); + this.update_tasks(); + } + + protected override void Dispose(bool disposing) + { + if (disposing && this.components != null) + this.components.Dispose(); + base.Dispose(disposing); + } + + private void InitializeComponent() + { + this.components = (IContainer)new Container(); + ResourceManager resourceManager = new ResourceManager(typeof(TaskPage)); + this.ToolbarImages = new ImageList(this.components); + this.ToolBar = new ToolBar(); + this.NewBtn = new ToolBarButton(); + this.DeleteBtn = new ToolBarButton(); + this.PropertiesBtn = new ToolBarButton(); + this.TaskList = new ListView(); + this.TaskHdr = new ColumnHeader(); + this.DeadlineHdr = new ColumnHeader(); + this.ImportanceHdr = new ColumnHeader(); + this.CompletedHdr = new ColumnHeader(); + this.TaskMenu = new ContextMenu(); + this.TaskNew = new MenuItem(); + this.TaskDelete = new MenuItem(); + this.TaskProperties = new MenuItem(); + this.Sep1 = new ToolBarButton(); + this.ExportBtn = new ToolBarButton(); + this.SuspendLayout(); + this.ToolbarImages.ColorDepth = ColorDepth.Depth8Bit; + this.ToolbarImages.ImageSize = new Size(16, 16); + this.ToolbarImages.ImageStream = (ImageListStreamer)resourceManager.GetObject("ToolbarImages.ImageStream"); + this.ToolbarImages.TransparentColor = Color.Magenta; + this.ToolBar.Appearance = ToolBarAppearance.Flat; + this.ToolBar.Buttons.AddRange(new ToolBarButton[5] + { + this.NewBtn, + this.DeleteBtn, + this.PropertiesBtn, + this.Sep1, + this.ExportBtn + }); + this.ToolBar.DropDownArrows = true; + this.ToolBar.ImageList = this.ToolbarImages; + this.ToolBar.Name = "ToolBar"; + this.ToolBar.ShowToolTips = true; + this.ToolBar.Size = new Size(552, 25); + this.ToolBar.TabIndex = 0; + this.ToolBar.ButtonClick += new ToolBarButtonClickEventHandler(this.ToolBar_ButtonClick); + this.NewBtn.ImageIndex = 0; + this.NewBtn.ToolTipText = "New Task"; + this.DeleteBtn.ImageIndex = 1; + this.DeleteBtn.ToolTipText = "Delete Task"; + this.PropertiesBtn.ImageIndex = 2; + this.PropertiesBtn.ToolTipText = "Task Properties"; + this.TaskList.Columns.AddRange(new ColumnHeader[4] + { + this.TaskHdr, + this.DeadlineHdr, + this.ImportanceHdr, + this.CompletedHdr + }); + this.TaskList.ContextMenu = this.TaskMenu; + this.TaskList.Dock = DockStyle.Fill; + this.TaskList.FullRowSelect = true; + this.TaskList.Location = new Point(0, 25); + this.TaskList.Name = "TaskList"; + this.TaskList.Size = new Size(552, 231); + this.TaskList.Sorting = SortOrder.Ascending; + this.TaskList.TabIndex = 1; + this.TaskList.View = View.Details; + this.TaskList.MouseDown += new MouseEventHandler(this.TaskList_MouseDown); + this.TaskList.DoubleClick += new EventHandler(this.TaskList_DoubleClick); + this.TaskList.ColumnClick += new ColumnClickEventHandler(this.TaskList_ColumnClick); + this.TaskHdr.Text = "Task"; + this.TaskHdr.Width = 200; + this.DeadlineHdr.Text = "Deadline"; + this.DeadlineHdr.Width = 90; + this.ImportanceHdr.Text = "Importance"; + this.ImportanceHdr.Width = 90; + this.CompletedHdr.Text = "Completed"; + this.CompletedHdr.Width = 90; + this.TaskMenu.MenuItems.AddRange(new MenuItem[3] + { + this.TaskNew, + this.TaskDelete, + this.TaskProperties + }); + this.TaskNew.Index = 0; + this.TaskNew.Text = "New Task"; + this.TaskNew.Click += new EventHandler(this.TaskNew_Click); + this.TaskDelete.Index = 1; + this.TaskDelete.Text = "Delete Task"; + this.TaskDelete.Click += new EventHandler(this.TaskDelete_Click); + this.TaskProperties.Index = 2; + this.TaskProperties.Text = "Task Properties"; + this.TaskProperties.Click += new EventHandler(this.TaskProperties_Click); + this.Sep1.Style = ToolBarButtonStyle.Separator; + this.ExportBtn.ImageIndex = 3; + this.ExportBtn.ToolTipText = "Export Tasks"; + this.Controls.AddRange(new Control[2] + { + (Control) this.TaskList, + (Control) this.ToolBar + }); + this.Name = nameof(TaskPage); + this.Size = new Size(552, 256); + this.ResumeLayout(false); + } + + public string Title + { + get + { + return "Task List"; + } + } + + public bool IsObsolete + { + get + { + return false; + } + } + + public void UpdateUI() + { + this.TaskNew.Enabled = true; + this.TaskDelete.Enabled = this.SelectedTask != null; + this.TaskProperties.Enabled = this.SelectedTask != null; + this.NewBtn.Enabled = this.TaskNew.Enabled; + this.DeleteBtn.Enabled = this.TaskDelete.Enabled; + this.PropertiesBtn.Enabled = this.TaskProperties.Enabled; + } + + public void UpdateData() + { + this.update_tasks(); + } + + public Task SelectedTask + { + get + { + if (this.TaskList.SelectedItems.Count != 0) + return this.TaskList.SelectedItems[0].Tag as Task; + return (Task)null; + } + } + + private void ToolBar_ButtonClick(object sender, ToolBarButtonClickEventArgs e) + { + try + { + if (e.Button == this.NewBtn) + this.TaskNew_Click(sender, (EventArgs)e); + else if (e.Button == this.DeleteBtn) + this.TaskDelete_Click(sender, (EventArgs)e); + else if (e.Button == this.PropertiesBtn) + { + this.TaskProperties_Click(sender, (EventArgs)e); + } + else + { + if (e.Button != this.ExportBtn) + return; + string str1 = "HTML Files|*.html|Text Files|*.txt"; + try + { + SaveFileDialog saveFileDialog = new SaveFileDialog(); + saveFileDialog.FileName = LabyrinthData.Project.Name + " Tasks"; + saveFileDialog.Filter = str1; + if (saveFileDialog.ShowDialog() != DialogResult.OK) + return; + string str2 = this.export_tasks(saveFileDialog.FilterIndex == 1); + StreamWriter text = File.CreateText(saveFileDialog.FileName); + text.WriteLine(str2); + text.Close(); + } + catch (Exception ex) + { + LabyrinthData.Log((object)ex); + } + } + } + catch (Exception ex) + { + LabyrinthData.Log((object)ex); + } + } + + private void TaskNew_Click(object sender, EventArgs e) + { + string str = "New Task"; + string title = str; + int num = 1; + for (; LabyrinthData.Project.Tasks.IndexOf(title) != -1; title = str + " " + (object)num) + ++num; + Task t = new Task(); + t.Title = title; + if (new TaskDlg(t).ShowDialog() != DialogResult.OK) + return; + LabyrinthData.Project.Tasks.Add(t); + this.update_tasks(); + } + + private void TaskDelete_Click(object sender, EventArgs e) + { + if (this.SelectedTask == null || MessageBox.Show("Delete task '" + this.SelectedTask.Title + "': Are you sure?", "Labyrinth", MessageBoxButtons.YesNo, MessageBoxIcon.Question) != DialogResult.Yes) + return; + LabyrinthData.Project.Tasks.Remove(this.SelectedTask); + this.update_tasks(); + } + + private void TaskProperties_Click(object sender, EventArgs e) + { + if (this.SelectedTask == null || new TaskDlg(this.SelectedTask).ShowDialog() != DialogResult.OK) + return; + this.update_tasks(); + } + + private void TaskList_DoubleClick(object sender, EventArgs e) + { + if (this.SelectedTask != null) + this.TaskProperties_Click(sender, e); + else + this.TaskNew_Click(sender, e); + } + + private void TaskList_MouseDown(object sender, MouseEventArgs e) + { + this.TaskList.SelectedItems.Clear(); + ListViewItem itemAt = this.TaskList.GetItemAt(e.X, e.Y); + if (itemAt != null) + itemAt.Selected = true; + this.UpdateUI(); + } + + private void TaskList_ColumnClick(object sender, ColumnClickEventArgs e) + { + ListViewSorter.Sort(this.TaskList, e.Column); + } + + public void update_tasks() + { + this.TaskList.BeginUpdate(); + this.TaskList.Items.Clear(); + Font font = new Font(this.Font, FontStyle.Bold); + if (LabyrinthData.Project.Tasks.Count != 0) + { + ArrayList arrayList = new ArrayList(); + foreach (Task task in LabyrinthData.Project.Tasks) + { + Font prototype = this.Font; + Color color1 = SystemColors.WindowText; + Color color2 = SystemColors.WindowText; + Color window = SystemColors.Window; + switch (task.Importance) + { + case Importance.Low: + color1 = SystemColors.GrayText; + break; + + case Importance.High: + prototype = new Font(prototype, prototype.Style | FontStyle.Bold); + break; + } + if (task.HasDeadline) + { + TimeSpan timeSpan = task.Deadline - DateTime.Now; + if (!(timeSpan > new TimeSpan(1, 0, 0, 0))) + { + if (timeSpan > TimeSpan.Zero) + { + color2 = Color.Red; + } + else + { + color1 = Color.Red; + color2 = Color.Red; + } + } + } + if (task.Completed) + { + prototype = new Font(prototype, prototype.Style | FontStyle.Strikeout); + color1 = SystemColors.GrayText; + } + arrayList.Add((object)new ListViewItem(task.Title) + { + UseItemStyleForSubItems = false, + Font = prototype, + ForeColor = color1, + ImageIndex = LabyrinthData.GetImageIndex(task), + Tag = (object)task, + SubItems = { + { + task.HasDeadline ? task.Deadline.ToShortDateString() : "", + color2, + window, + prototype + }, + { + task.Importance.ToString(), + color1, + window, + prototype + }, + { + task.Completed.ToString(), + color1, + window, + prototype + } + } + }); + } + this.TaskList.Items.AddRange((ListViewItem[])arrayList.ToArray(typeof(ListViewItem))); + } + else + { + ListViewItem listViewItem = this.TaskList.Items.Add("No tasks"); + listViewItem.ForeColor = SystemColors.GrayText; + listViewItem.ImageIndex = -1; + } + this.TaskList.EndUpdate(); + } + + private string export_tasks(bool markup) + { + string str1 = ""; + string title = LabyrinthData.Project.Name + " Tasks"; + if (markup) + str1 = str1 + "" + Environment.NewLine + LabyrinthData.HTMLHeader(title) + Environment.NewLine + "" + Environment.NewLine; + if (markup) + str1 += "

"; + string str2 = str1 + title; + if (markup) + str2 += "

"; + string str3 = str2 + Environment.NewLine; + foreach (Task task in LabyrinthData.Project.Tasks) + { + string str4 = ""; + if (task.Completed) + { + if (str4 != "") + str4 += "; "; + str4 += "Completed"; + } + if (task.Importance != Importance.Normal) + { + if (str4 != "") + str4 += "; "; + str4 += "Importance: "; + if (task.Importance == Importance.High) + str4 += "high"; + if (task.Importance == Importance.Low) + str4 += "low"; + } + if (task.HasDeadline) + { + if (str4 != "") + str4 += "; "; + str4 = str4 + "Deadline: " + task.Deadline.ToShortDateString(); + } + str3 += Environment.NewLine; + if (markup) + str3 = str3 + "

" + Environment.NewLine; + str3 = str3 + task.Title + Environment.NewLine; + if (markup) + str3 = str3 + "

" + Environment.NewLine; + if (str4 != "") + { + if (markup) + str3 = str3 + "

" + Environment.NewLine; + str3 = str3 + str4 + Environment.NewLine; + if (markup) + str3 = str3 + "

" + Environment.NewLine; + } + if (markup) + str3 = str3 + "

" + Environment.NewLine; + str3 = str3 + (markup ? task.Details.Replace("\n", "
") : task.Details) + Environment.NewLine; + if (markup) + str3 = str3 + "

" + Environment.NewLine; + } + if (markup) + str3 = str3 + "" + Environment.NewLine + "" + Environment.NewLine; + return str3; + } + } +} \ No newline at end of file diff --git a/Labyrinth3/IDE/Pages/TaskPage.resx b/Labyrinth3/IDE/Pages/TaskPage.resx new file mode 100644 index 0000000..2af555f --- /dev/null +++ b/Labyrinth3/IDE/Pages/TaskPage.resx @@ -0,0 +1,180 @@ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + text/microsoft-resx + + + 2.0 + + + System.Resources.ResXResourceReader, System.Windows.Forms, Version=4.0.0.0, Culture=neutral, PublicKeyToken=b77a5c561934e089 + + + System.Resources.ResXResourceWriter, System.Windows.Forms, Version=4.0.0.0, Culture=neutral, PublicKeyToken=b77a5c561934e089 + + + TaskPage + + + + 17, 17 + + + 105, 17 + + + + AAEAAAD/////AQAAAAAAAAAMAgAAAFdTeXN0ZW0uV2luZG93cy5Gb3JtcywgVmVyc2lvbj00LjAuMC4w + LCBDdWx0dXJlPW5ldXRyYWwsIFB1YmxpY0tleVRva2VuPWI3N2E1YzU2MTkzNGUwODkFAQAAACZTeXN0 + ZW0uV2luZG93cy5Gb3Jtcy5JbWFnZUxpc3RTdHJlYW1lcgEAAAAERGF0YQcCAgAAAAkDAAAADwMAAADq + CQAAAk1TRnQBSQFMAgEBBAEAAQkBAAEIAQABEAEAARABAAT/AQkBEAj/AUIBTQE2AQQGAAE2AQQCAAEo + AwABQAMAASADAAEBAQABCAYAAQgYAAGAAgABgAMAAoABAAGAAwABgAEAAYABAAKAAgADwAEAAcAB3AHA + AQAB8AHKAaYBAAEzBQABMwEAATMBAAEzAQACMwIAAxYBAAMcAQADIgEAAykBAANVAQADTQEAA0IBAAM5 + AQABgAF8Af8BAAJQAf8BAAGTAQAB1gEAAf8B7AHMAQABxgHWAe8BAAHWAucBAAGQAakBrQIAAf8BMwMA + AWYDAAGZAwABzAIAATMDAAIzAgABMwFmAgABMwGZAgABMwHMAgABMwH/AgABZgMAAWYBMwIAAmYCAAFm + AZkCAAFmAcwCAAFmAf8CAAGZAwABmQEzAgABmQFmAgACmQIAAZkBzAIAAZkB/wIAAcwDAAHMATMCAAHM + AWYCAAHMAZkCAALMAgABzAH/AgAB/wFmAgAB/wGZAgAB/wHMAQABMwH/AgAB/wEAATMBAAEzAQABZgEA + ATMBAAGZAQABMwEAAcwBAAEzAQAB/wEAAf8BMwIAAzMBAAIzAWYBAAIzAZkBAAIzAcwBAAIzAf8BAAEz + AWYCAAEzAWYBMwEAATMCZgEAATMBZgGZAQABMwFmAcwBAAEzAWYB/wEAATMBmQIAATMBmQEzAQABMwGZ + AWYBAAEzApkBAAEzAZkBzAEAATMBmQH/AQABMwHMAgABMwHMATMBAAEzAcwBZgEAATMBzAGZAQABMwLM + AQABMwHMAf8BAAEzAf8BMwEAATMB/wFmAQABMwH/AZkBAAEzAf8BzAEAATMC/wEAAWYDAAFmAQABMwEA + AWYBAAFmAQABZgEAAZkBAAFmAQABzAEAAWYBAAH/AQABZgEzAgABZgIzAQABZgEzAWYBAAFmATMBmQEA + AWYBMwHMAQABZgEzAf8BAAJmAgACZgEzAQADZgEAAmYBmQEAAmYBzAEAAWYBmQIAAWYBmQEzAQABZgGZ + AWYBAAFmApkBAAFmAZkBzAEAAWYBmQH/AQABZgHMAgABZgHMATMBAAFmAcwBmQEAAWYCzAEAAWYBzAH/ + AQABZgH/AgABZgH/ATMBAAFmAf8BmQEAAWYB/wHMAQABzAEAAf8BAAH/AQABzAEAApkCAAGZATMBmQEA + AZkBAAGZAQABmQEAAcwBAAGZAwABmQIzAQABmQEAAWYBAAGZATMBzAEAAZkBAAH/AQABmQFmAgABmQFm + ATMBAAGZATMBZgEAAZkBZgGZAQABmQFmAcwBAAGZATMB/wEAApkBMwEAApkBZgEAA5kBAAKZAcwBAAKZ + Af8BAAGZAcwCAAGZAcwBMwEAAWYBzAFmAQABmQHMAZkBAAGZAswBAAGZAcwB/wEAAZkB/wIAAZkB/wEz + AQABmQHMAWYBAAGZAf8BmQEAAZkB/wHMAQABmQL/AQABzAMAAZkBAAEzAQABzAEAAWYBAAHMAQABmQEA + AcwBAAHMAQABmQEzAgABzAIzAQABzAEzAWYBAAHMATMBmQEAAcwBMwHMAQABzAEzAf8BAAHMAWYCAAHM + AWYBMwEAAZkCZgEAAcwBZgGZAQABzAFmAcwBAAGZAWYB/wEAAcwBmQIAAcwBmQEzAQABzAGZAWYBAAHM + ApkBAAHMAZkBzAEAAcwBmQH/AQACzAIAAswBMwEAAswBZgEAAswBmQEAA8wBAALMAf8BAAHMAf8CAAHM + Af8BMwEAAZkB/wFmAQABzAH/AZkBAAHMAf8BzAEAAcwC/wEAAcwBAAEzAQAB/wEAAWYBAAH/AQABmQEA + AcwBMwIAAf8CMwEAAf8BMwFmAQAB/wEzAZkBAAH/ATMBzAEAAf8BMwH/AQAB/wFmAgAB/wFmATMBAAHM + AmYBAAH/AWYBmQEAAf8BZgHMAQABzAFmAf8BAAH/AZkCAAH/AZkBMwEAAf8BmQFmAQAB/wKZAQAB/wGZ + AcwBAAH/AZkB/wEAAf8BzAIAAf8BzAEzAQAB/wHMAWYBAAH/AcwBmQEAAf8CzAEAAf8BzAH/AQAC/wEz + AQABzAH/AWYBAAL/AZkBAAL/AcwBAAJmAf8BAAFmAf8BZgEAAWYC/wEAAf8CZgEAAf8BZgH/AQAC/wFm + AQABIQEAAaUBAANfAQADdwEAA4YBAAOWAQADywEAA7IBAAPXAQAD3QEAA+MBAAPqAQAD8QEAA/gBAAHw + AfsB/wEAAaQCoAEAA4ADAAH/AgAB/wMAAv8BAAH/AwAB/wEAAf8BAAL/AgAD//8A/wD/AP8AQQAB/AYA + CuwmAAnsAvwEAAEHCv8B7BMACv8HAAEHBP8I/AMAAQcD/wIHBf8B7BMAAf8CAAH/BQAB/wcAAQcD/wEH + CfwCAAEHA/8BAQIHBP8B7BMACv8HAAEHA/8BAQj8AwABBwL/AwECBwP/AewTAAH/AgAB/wUAAf8HAAEH + Av8DAQIHAv8C/AQAAQcB/wIBAf8CAQEHA/8B7BMACv8HAAEHAf8CAQH/AgEBBwL/AfwB7AQAAQcF/wEB + AgcC/wHsEwAH/wEAAv8HAAEHBf8BAQIHAv8B7AMAAfsBBwH/AewB+wH/AfsB/wEBAgcB/wHsEwAB/wIA + A/8BAAEHAQAB/wcAAQcG/wEBAgcB/wHsAwAB7AH7Af8B7AH7Af8B7AL/AQEBBwH/AewTAAH/AQABBwEA + Af8BAAEHAQABBwQAAgQCAAEHB/8BAQEHAf8B7AQAAewB/wHsAfsC7AP/AQEB/wHsEwAC/wEAAQcBAAEH + AQABBwEAAwcBAAIEAgABBwj/AQEB/wHsAwAF7AH/AfsF/wHsFwABBwEAAQcBAAUHAgQCAAEHCv8B7AQA + AfsB7AH7BuwC/wHsGAABBwEABgcCBAIAAQcC/wbsAv8B7AQAAewB+wHsAfsB7AH7AgcB7AIHGgAGBwEA + AgQDAAIHAewB/wMHAewCBwQAAewB+wEAAewBAAEHAewCByQAAgQGAAQHBwAB+wIAAewB+zoAAUIBTQE+ + BwABPgMAASgDAAFAAwABIAMAAQEBAAEBBgABARYAA/+BAAf/AfcB4AEHAv8BAAEPAeABAwHAAQMB7wH9 + AQABDwHAAQEBwAEDAccB/wEAAQ8BwAEAAcABAwHDAfsBAAEPAcABAQHAAQMB4wH3AQABDwHAAQMBwAED + AfEB5wEAAQ8BwAEDAcABAwH4Ac8BAAEPAcABAwGAAQMB/AEfAQABDwHAAQMBgAEDAf4BPwEAAQQBwAED + AcABAwH8AR8CAAHAAQMBgAEDAfgBzwIAAcABAwHAAQMB4QHnAfgBAAHAAQMBwAEHAcMB8wH8AQAB4AEH + AZQBPwHHAf0B/gEEAfwBPwGzB/8WAAs= + + + \ No newline at end of file diff --git a/Labyrinth3/IDE/Pages/TimelinePage.cs b/Labyrinth3/IDE/Pages/TimelinePage.cs new file mode 100644 index 0000000..fb2a2f3 --- /dev/null +++ b/Labyrinth3/IDE/Pages/TimelinePage.cs @@ -0,0 +1,951 @@ +// Decompiled with JetBrains decompiler +// Type: Labyrinth.Pages.TimelinePage +// Assembly: Labyrinth, Version=3.6.1928.15690, Culture=neutral, PublicKeyToken=null +// MVID: 1462002E-0BD1-49D2-9B56-C22E66C903E7 +// Assembly location: C:\Dropbox\Workspace\Programs\Labyrinth\Labyrinth.exe + +using Labyrinth.Collections; +using Labyrinth.Controls; +using Labyrinth.Events; +using Labyrinth.Extensibility; +using Labyrinth.Forms; +using Labyrinth.Plot; +using System; +using System.Collections; +using System.ComponentModel; +using System.Drawing; +using System.Drawing.Imaging; +using System.Drawing.Printing; +using System.IO; +using System.Resources; +using System.Windows.Forms; + +namespace Labyrinth.Pages +{ + public class TimelinePage : UserControl, ITimelinePage, IPage + { + private Timeline fTimeline = (Timeline)null; + private int fZoom = 0; + private IContainer components; + private ImageList ToolbarImages; + private ToolBar ToolBar; + private ContextMenu TimelineContextMenu; + private MenuItem TimelineDeleteAnnotation; + private MenuItem TimelineAnnotationProperties; + private MenuItem TimelineNewAnnotation; + private MenuItem menuItem10; + private MenuItem menuItem9; + private MenuItem TimelinePointProperties; + private MenuItem TimelineDeletePoint; + private MenuItem TimelineNewPoint; + private MenuItem TimelineElementProperties; + private MenuItem TimelineDeleteElement; + private MenuItem TimelineOpenElement; + private ToolBarButton Sep1; + private ToolBarButton MoveLeftBtn; + private ToolBarButton MoveRightBtn; + private ToolBarButton Sep2; + private ToolBarButton MoveUpBtn; + private ToolBarButton MoveDownBtn; + private ToolBarButton Sep3; + private ToolBarButton ExportBtn; + private ToolBarButton PrintBtn; + private ToolBarButton PrintPreviewBtn; + private TimelineGrid TimelineGrid; + private Panel TimelinePanel; + private ToolBarButton Sep4; + private ToolBarButton ZoomInBtn; + private ToolBarButton ZoomOutBtn; + private ToolBarButton PropertiesBtn; + + public TimelinePage(Timeline tl) + { + this.InitializeComponent(); + this.fTimeline = tl; + this.TimelineGrid.Location = new Point(0, 0); + this.TimelineGrid.Timeline = this.fTimeline; + this.UpdateData(); + } + + protected override void Dispose(bool disposing) + { + if (disposing && this.components != null) + this.components.Dispose(); + base.Dispose(disposing); + } + + private void InitializeComponent() + { + this.components = (IContainer)new Container(); + ResourceManager resourceManager = new ResourceManager(typeof(TimelinePage)); + this.ToolbarImages = new ImageList(this.components); + this.ToolBar = new ToolBar(); + this.PropertiesBtn = new ToolBarButton(); + this.PrintBtn = new ToolBarButton(); + this.PrintPreviewBtn = new ToolBarButton(); + this.Sep1 = new ToolBarButton(); + this.MoveLeftBtn = new ToolBarButton(); + this.MoveRightBtn = new ToolBarButton(); + this.Sep2 = new ToolBarButton(); + this.MoveUpBtn = new ToolBarButton(); + this.MoveDownBtn = new ToolBarButton(); + this.Sep3 = new ToolBarButton(); + this.ExportBtn = new ToolBarButton(); + this.Sep4 = new ToolBarButton(); + this.ZoomInBtn = new ToolBarButton(); + this.ZoomOutBtn = new ToolBarButton(); + this.TimelineContextMenu = new ContextMenu(); + this.TimelineNewAnnotation = new MenuItem(); + this.TimelineAnnotationProperties = new MenuItem(); + this.TimelineDeleteAnnotation = new MenuItem(); + this.menuItem9 = new MenuItem(); + this.TimelineOpenElement = new MenuItem(); + this.TimelineDeleteElement = new MenuItem(); + this.TimelineElementProperties = new MenuItem(); + this.menuItem10 = new MenuItem(); + this.TimelineNewPoint = new MenuItem(); + this.TimelineDeletePoint = new MenuItem(); + this.TimelinePointProperties = new MenuItem(); + this.TimelineGrid = new TimelineGrid(); + this.TimelinePanel = new Panel(); + this.TimelinePanel.SuspendLayout(); + this.SuspendLayout(); + this.ToolbarImages.ColorDepth = ColorDepth.Depth8Bit; + this.ToolbarImages.ImageSize = new Size(16, 16); + this.ToolbarImages.ImageStream = (ImageListStreamer)resourceManager.GetObject("ToolbarImages.ImageStream"); + this.ToolbarImages.TransparentColor = Color.Magenta; + this.ToolBar.Appearance = ToolBarAppearance.Flat; + this.ToolBar.Buttons.AddRange(new ToolBarButton[14] + { + this.PropertiesBtn, + this.PrintBtn, + this.PrintPreviewBtn, + this.Sep1, + this.MoveLeftBtn, + this.MoveRightBtn, + this.Sep2, + this.MoveUpBtn, + this.MoveDownBtn, + this.Sep3, + this.ExportBtn, + this.Sep4, + this.ZoomInBtn, + this.ZoomOutBtn + }); + this.ToolBar.DropDownArrows = true; + this.ToolBar.ImageList = this.ToolbarImages; + this.ToolBar.Name = "ToolBar"; + this.ToolBar.ShowToolTips = true; + this.ToolBar.Size = new Size(360, 25); + this.ToolBar.TabIndex = 0; + this.ToolBar.ButtonClick += new ToolBarButtonClickEventHandler(this.ToolBar_ButtonClick); + this.PropertiesBtn.ImageIndex = 0; + this.PrintBtn.ImageIndex = 6; + this.PrintBtn.ToolTipText = "Print"; + this.PrintPreviewBtn.ImageIndex = 7; + this.PrintPreviewBtn.ToolTipText = "Print Preview"; + this.Sep1.Style = ToolBarButtonStyle.Separator; + this.MoveLeftBtn.ImageIndex = 1; + this.MoveLeftBtn.ToolTipText = "Move left"; + this.MoveRightBtn.ImageIndex = 2; + this.MoveRightBtn.ToolTipText = "Move right"; + this.Sep2.Style = ToolBarButtonStyle.Separator; + this.MoveUpBtn.ImageIndex = 3; + this.MoveUpBtn.ToolTipText = "Move up"; + this.MoveDownBtn.ImageIndex = 4; + this.MoveDownBtn.ToolTipText = "Move down"; + this.Sep3.Style = ToolBarButtonStyle.Separator; + this.ExportBtn.ImageIndex = 5; + this.ExportBtn.ToolTipText = "Export Timeline"; + this.Sep4.Style = ToolBarButtonStyle.Separator; + this.ZoomInBtn.ImageIndex = 8; + this.ZoomInBtn.ToolTipText = "Zoom In"; + this.ZoomOutBtn.ImageIndex = 9; + this.ZoomOutBtn.ToolTipText = "Zoom Out"; + this.TimelineContextMenu.MenuItems.AddRange(new MenuItem[11] + { + this.TimelineNewAnnotation, + this.TimelineAnnotationProperties, + this.TimelineDeleteAnnotation, + this.menuItem9, + this.TimelineOpenElement, + this.TimelineDeleteElement, + this.TimelineElementProperties, + this.menuItem10, + this.TimelineNewPoint, + this.TimelineDeletePoint, + this.TimelinePointProperties + }); + this.TimelineNewAnnotation.Index = 0; + this.TimelineNewAnnotation.Text = "New Annotation..."; + this.TimelineNewAnnotation.Click += new EventHandler(this.TimelineAddAnnotation_Click); + this.TimelineAnnotationProperties.Index = 1; + this.TimelineAnnotationProperties.Text = "Open Annotation"; + this.TimelineAnnotationProperties.Click += new EventHandler(this.TimelineAnnotationProperties_Click); + this.TimelineDeleteAnnotation.Index = 2; + this.TimelineDeleteAnnotation.Text = "Delete Annotation"; + this.TimelineDeleteAnnotation.Click += new EventHandler(this.TimelineDeleteAnnotation_Click); + this.menuItem9.Index = 3; + this.menuItem9.Text = "-"; + this.TimelineOpenElement.Index = 4; + this.TimelineOpenElement.Text = "Open Element"; + this.TimelineOpenElement.Click += new EventHandler(this.TimelineOpenElement_Click); + this.TimelineDeleteElement.Index = 5; + this.TimelineDeleteElement.Text = "Remove Element"; + this.TimelineDeleteElement.Click += new EventHandler(this.TimelineDeleteElement_Click); + this.TimelineElementProperties.Index = 6; + this.TimelineElementProperties.Text = "Element Properties"; + this.TimelineElementProperties.Click += new EventHandler(this.TimelineElementProperties_Click); + this.menuItem10.Index = 7; + this.menuItem10.Text = "-"; + this.TimelineNewPoint.Index = 8; + this.TimelineNewPoint.Text = "New Point..."; + this.TimelineNewPoint.Click += new EventHandler(this.TimelineAddPoint_Click); + this.TimelineDeletePoint.Index = 9; + this.TimelineDeletePoint.Text = "Delete Point"; + this.TimelineDeletePoint.Click += new EventHandler(this.TimelineDeletePoint_Click); + this.TimelinePointProperties.Index = 10; + this.TimelinePointProperties.Text = "Point Properties"; + this.TimelinePointProperties.Click += new EventHandler(this.TimelinePointProperties_Click); + this.TimelineGrid.AllowDrop = true; + this.TimelineGrid.ContextMenu = this.TimelineContextMenu; + this.TimelineGrid.Font = new Font("Tahoma", 11f, FontStyle.Regular, GraphicsUnit.World, (byte)0); + this.TimelineGrid.Location = new Point(8, 8); + this.TimelineGrid.Name = "TimelineGrid"; + this.TimelineGrid.Size = new Size(224, 85); + this.TimelineGrid.TabIndex = 1; + this.TimelineGrid.Timeline = (Timeline)null; + this.TimelineGrid.DragDrop += new DragEventHandler(this.RowHdrPanel_DragDrop); + this.TimelineGrid.DoubleClick += new EventHandler(this.TimelineGrid_DoubleClick); + this.TimelineGrid.DragOver += new DragEventHandler(this.RowHdrPanel_DragOver); + this.TimelinePanel.AutoScroll = true; + this.TimelinePanel.Controls.AddRange(new Control[1] + { + (Control) this.TimelineGrid + }); + this.TimelinePanel.Dock = DockStyle.Fill; + this.TimelinePanel.Location = new Point(0, 25); + this.TimelinePanel.Name = "TimelinePanel"; + this.TimelinePanel.Size = new Size(360, 215); + this.TimelinePanel.TabIndex = 2; + this.TimelinePanel.Layout += new LayoutEventHandler(this.TimelinePanel_Layout); + this.Controls.AddRange(new Control[2] + { + (Control) this.TimelinePanel, + (Control) this.ToolBar + }); + this.Font = new Font("Tahoma", 11f, FontStyle.Regular, GraphicsUnit.World); + this.Name = nameof(TimelinePage); + this.Size = new Size(360, 240); + this.TimelinePanel.ResumeLayout(false); + this.ResumeLayout(false); + } + + public string Title + { + get + { + return this.fTimeline.Name; + } + } + + public bool IsObsolete + { + get + { + return LabyrinthData.Project.Timelines.IndexOf(this.fTimeline) == -1; + } + } + + public void UpdateUI() + { + Element selectedElement = this.TimelineGrid.SelectedElement; + TimelinePoint selectedPoint = this.TimelineGrid.SelectedPoint; + Annotation annotation = this.get_annotation(selectedElement, selectedPoint); + this.TimelineNewAnnotation.Enabled = selectedElement != null && selectedPoint != null && annotation == null; + this.TimelineDeleteAnnotation.Enabled = selectedElement != null && selectedPoint != null && annotation != null; + this.TimelineAnnotationProperties.Enabled = annotation != null; + this.TimelineOpenElement.Enabled = selectedElement != null; + this.TimelineDeleteElement.Enabled = selectedElement != null; + this.TimelineElementProperties.Enabled = selectedElement != null; + this.TimelineNewPoint.Enabled = true; + this.TimelineDeletePoint.Enabled = selectedPoint != null; + this.TimelinePointProperties.Enabled = selectedPoint != null; + this.PropertiesBtn.Enabled = true; + this.PrintBtn.Enabled = true; + this.PrintPreviewBtn.Enabled = true; + this.MoveLeftBtn.Enabled = !this.fTimeline.Sorting && selectedPoint != null && this.fTimeline.Points.Count != 0 && selectedPoint != this.fTimeline.Points[0]; + this.MoveRightBtn.Enabled = !this.fTimeline.Sorting && selectedPoint != null && this.fTimeline.Points.Count != 0 && selectedPoint != this.fTimeline.Points[this.fTimeline.Points.Count - 1]; + this.MoveUpBtn.Enabled = selectedElement != null && this.fTimeline.ElementIDs.Count != 0 && selectedElement.ID != this.fTimeline.ElementIDs[0]; + this.MoveDownBtn.Enabled = selectedElement != null && this.fTimeline.ElementIDs.Count != 0 && selectedElement.ID != this.fTimeline.ElementIDs[this.fTimeline.ElementIDs.Count - 1]; + this.ExportBtn.Enabled = true; + this.ZoomInBtn.Enabled = true; + this.ZoomOutBtn.Enabled = this.fZoom != 0; + } + + public void UpdateData() + { + if (this.fTimeline.Sorting) + this.fTimeline.Points.Sort(); + this.TimelineGrid.Refresh(); + } + + public Timeline Timeline + { + get + { + return this.fTimeline; + } + } + + public Element SelectedElement + { + get + { + return this.TimelineGrid.SelectedElement; + } + } + + public TimelinePoint SelectedPoint + { + get + { + return this.TimelineGrid.SelectedPoint; + } + } + + public int Zoom + { + get + { + return this.fZoom; + } + set + { + if (this.fZoom == value) + return; + this.fZoom = value; + this.resize_grid(); + } + } + + public event TimelineEventHandler TimelineModified; + + public event ElementEventHandler ElementModified; + + public event ElementEventHandler ElementActivated; + + protected void OnTimelineModified(TimelineEventArgs e) + { + try + { + if (this.TimelineModified == null) + return; + this.TimelineModified((object)this, e); + } + catch (Exception ex) + { + LabyrinthData.Log((object)ex); + } + } + + protected void OnElementModified(ElementEventArgs e) + { + try + { + if (this.ElementModified == null) + return; + this.ElementModified((object)this, e); + } + catch (Exception ex) + { + LabyrinthData.Log((object)ex); + } + } + + protected void OnElementActivated(ElementEventArgs e) + { + try + { + if (this.ElementActivated == null) + return; + this.ElementActivated((object)this, e); + } + catch (Exception ex) + { + LabyrinthData.Log((object)ex); + } + } + + private void RowHdrPanel_DragOver(object sender, DragEventArgs e) + { + this.OnDragOver(e); + this.TimelineGrid.RecalculateHover(); + e.Effect = DragDropEffects.None; + string str = ""; + foreach (string format in e.Data.GetFormats()) + { + if (str != "") + str += "; "; + str += format; + } + Element data1 = e.Data.GetData(typeof(Element)) as Element; + Structure data2 = e.Data.GetData(typeof(Structure)) as Structure; + Timeline data3 = e.Data.GetData(typeof(Timeline)) as Timeline; + if (data1 != null || data2 != null || data3 != null && data3 != this.fTimeline) + { + e.Effect = DragDropEffects.Copy; + } + else + { + string[] data4 = e.Data.GetData(DataFormats.FileDrop) as string[]; + if (data4.Length == 0 || !File.Exists(data4[0]) || this.TimelineGrid.HoverElement == null || (this.TimelineGrid.HoverPoint == null || this.get_annotation(this.TimelineGrid.HoverElement, this.TimelineGrid.HoverPoint) != null)) + return; + e.Effect = DragDropEffects.Copy; + } + } + + private void RowHdrPanel_DragDrop(object sender, DragEventArgs e) + { + this.OnDragDrop(e); + bool flag = false; + Element data1 = e.Data.GetData(typeof(Element)) as Element; + if (data1 != null) + { + if (this.fTimeline.ElementIDs.Contains(data1.ID)) + { + int num = (int)MessageBox.Show("This element is already part of this timeline.", "Labyrinth", MessageBoxButtons.OK, MessageBoxIcon.Asterisk); + return; + } + this.fTimeline.ElementIDs.Add(data1.ID); + flag = true; + } + Structure data2 = e.Data.GetData(typeof(Structure)) as Structure; + if (data2 != null) + { + if (MessageBox.Show("Do you want to add all the elements from this structure?", "Labyrinth", MessageBoxButtons.YesNo, MessageBoxIcon.Question) != DialogResult.Yes) + return; + foreach (Node node in data2.Nodes) + { + if (!this.fTimeline.ElementIDs.Contains(node.ElementID)) + { + this.fTimeline.ElementIDs.Add(node.ElementID); + flag = true; + } + } + } + Timeline data3 = e.Data.GetData(typeof(Timeline)) as Timeline; + if (data3 != null) + { + if (MessageBox.Show("Do you want to add all the elements from this timeline?", "Labyrinth", MessageBoxButtons.YesNo, MessageBoxIcon.Question) != DialogResult.Yes) + return; + foreach (Guid elementId in data3.ElementIDs) + { + if (!this.fTimeline.ElementIDs.Contains(elementId)) + { + this.fTimeline.ElementIDs.Add(elementId); + flag = true; + } + } + } + string[] data4 = e.Data.GetData(DataFormats.FileDrop) as string[]; + if (data4.Length != 0 && this.get_annotation(this.TimelineGrid.HoverElement, this.TimelineGrid.HoverPoint) == null) + { + string str = data4[0]; + FileInfo fileInfo = new FileInfo(str); + if (fileInfo.Exists) + { + string end = new StreamReader(str).ReadToEnd(); + TimelineItem timelineItem = new TimelineItem(); + timelineItem.ElementID = this.TimelineGrid.HoverElement.ID; + timelineItem.Annotation.Title = fileInfo.Name; + timelineItem.Annotation.Content = end; + this.TimelineGrid.HoverPoint.Items.Add(timelineItem); + flag = true; + } + } + if (!flag) + return; + this.UpdateData(); + this.OnTimelineModified(new TimelineEventArgs(this.fTimeline)); + } + + private void TimelineAddAnnotation_Click(object sender, EventArgs e) + { + if (this.get_annotation(this.TimelineGrid.SelectedElement, this.TimelineGrid.SelectedPoint) != null) + return; + TextAnnotation textAnnotation = new TextAnnotation(); + textAnnotation.Title = "New Annotation"; + if (!Annotations.Open((Annotation)textAnnotation)) + return; + this.TimelineGrid.SelectedPoint.Items.Add(new TimelineItem() + { + ElementID = this.TimelineGrid.SelectedElement.ID, + Annotation = textAnnotation + }); + this.UpdateData(); + this.OnTimelineModified(new TimelineEventArgs(this.fTimeline)); + } + + private void TimelineDeleteAnnotation_Click(object sender, EventArgs e) + { + Annotation annotation = this.get_annotation(this.TimelineGrid.SelectedElement, this.TimelineGrid.SelectedPoint); + if (annotation == null || MessageBox.Show("Delete annotation '" + annotation.Title + "': are you sure?", "Labyrinth", MessageBoxButtons.YesNo, MessageBoxIcon.Question) != DialogResult.Yes) + return; + TimelineItem timelineItem1 = (TimelineItem)null; + foreach (TimelineItem timelineItem2 in this.TimelineGrid.SelectedPoint.Items) + { + if (timelineItem2.Annotation == annotation) + { + timelineItem1 = timelineItem2; + break; + } + } + if (timelineItem1 == null) + return; + this.TimelineGrid.SelectedPoint.Items.Remove(timelineItem1); + this.UpdateData(); + this.OnTimelineModified(new TimelineEventArgs(this.fTimeline)); + } + + private void TimelineAnnotationProperties_Click(object sender, EventArgs e) + { + Annotation annotation = this.get_annotation(this.TimelineGrid.SelectedElement, this.TimelineGrid.SelectedPoint); + if (annotation == null || !Annotations.Open(annotation)) + return; + this.UpdateData(); + this.OnTimelineModified(new TimelineEventArgs(this.fTimeline)); + } + + private void TimelineOpenElement_Click(object sender, EventArgs e) + { + if (this.TimelineGrid.SelectedElement == null) + return; + this.OnElementActivated(new ElementEventArgs(this.TimelineGrid.SelectedElement)); + } + + private void TimelineDeleteElement_Click(object sender, EventArgs e) + { + if (this.TimelineGrid.SelectedElement == null || MessageBox.Show("Delete element reference: are you sure?" + "\n" + "The element itself will not be deleted.", "Labyrinth", MessageBoxButtons.YesNo, MessageBoxIcon.Question) != DialogResult.Yes) + return; + this.fTimeline.RemoveElement(this.TimelineGrid.SelectedElement.ID); + this.UpdateData(); + this.OnTimelineModified(new TimelineEventArgs(this.fTimeline)); + } + + private void TimelineElementProperties_Click(object sender, EventArgs e) + { + if (this.TimelineGrid.SelectedElement == null) + return; + Element selectedElement = this.TimelineGrid.SelectedElement; + if (new ElementDlg(selectedElement).ShowDialog() != DialogResult.OK) + return; + this.UpdateData(); + this.OnElementModified(new ElementEventArgs(selectedElement)); + } + + private void TimelineAddPoint_Click(object sender, EventArgs e) + { + string str = "New Timeline Point"; + string name = str; + int num = 1; + for (; this.fTimeline.Points.IndexOf(name) != -1; name = str + " " + (object)num) + ++num; + TimelinePoint tlp = new TimelinePoint(); + tlp.Name = name; + if (new TimelinePointDlg(tlp).ShowDialog() != DialogResult.OK) + return; + this.fTimeline.Points.Add(tlp); + this.UpdateData(); + this.OnTimelineModified(new TimelineEventArgs(this.fTimeline)); + } + + private void TimelineDeletePoint_Click(object sender, EventArgs e) + { + if (this.TimelineGrid.SelectedPoint == null || MessageBox.Show("Delete point '" + this.TimelineGrid.SelectedPoint.Name + "': are you sure?", "Labyrinth", MessageBoxButtons.YesNo, MessageBoxIcon.Question) != DialogResult.Yes) + return; + this.fTimeline.Points.Remove(this.TimelineGrid.SelectedPoint); + this.UpdateData(); + this.OnTimelineModified(new TimelineEventArgs(this.fTimeline)); + } + + private void TimelinePointProperties_Click(object sender, EventArgs e) + { + if (this.TimelineGrid.SelectedPoint == null || new TimelinePointDlg(this.TimelineGrid.SelectedPoint).ShowDialog() != DialogResult.OK) + return; + this.UpdateData(); + this.OnTimelineModified(new TimelineEventArgs(this.fTimeline)); + } + + private void ToolBar_ButtonClick(object sender, ToolBarButtonClickEventArgs e) + { + try + { + if (e.Button == this.PropertiesBtn) + { + if (new TimelineDlg(this.fTimeline).ShowDialog() != DialogResult.OK) + return; + this.UpdateData(); + this.OnTimelineModified(new TimelineEventArgs(this.fTimeline)); + } + else if (e.Button == this.MoveLeftBtn) + { + TimelinePoint selectedPoint = this.TimelineGrid.SelectedPoint; + if (selectedPoint == null) + return; + int index = this.Timeline.Points.IndexOf(selectedPoint); + if (index == 0) + return; + TimelinePoint point = this.Timeline.Points[index - 1]; + this.Timeline.Points[index - 1] = selectedPoint; + this.Timeline.Points[index] = point; + this.UpdateData(); + this.OnTimelineModified(new TimelineEventArgs(this.fTimeline)); + } + else if (e.Button == this.MoveRightBtn) + { + TimelinePoint selectedPoint = this.TimelineGrid.SelectedPoint; + if (selectedPoint == null) + return; + int index = this.Timeline.Points.IndexOf(selectedPoint); + if (index == this.Timeline.Points.Count - 1) + return; + TimelinePoint point = this.Timeline.Points[index + 1]; + this.Timeline.Points[index + 1] = selectedPoint; + this.Timeline.Points[index] = point; + this.UpdateData(); + this.OnTimelineModified(new TimelineEventArgs(this.fTimeline)); + } + else if (e.Button == this.MoveUpBtn) + { + Element selectedElement = this.TimelineGrid.SelectedElement; + if (selectedElement == null) + return; + int index = this.Timeline.ElementIDs.IndexOf(selectedElement.ID); + if (index == 0) + return; + Guid elementId = this.Timeline.ElementIDs[index - 1]; + this.Timeline.ElementIDs[index - 1] = selectedElement.ID; + this.Timeline.ElementIDs[index] = elementId; + this.UpdateData(); + this.OnTimelineModified(new TimelineEventArgs(this.fTimeline)); + } + else if (e.Button == this.MoveDownBtn) + { + Element selectedElement = this.TimelineGrid.SelectedElement; + if (selectedElement == null) + return; + int index = this.Timeline.ElementIDs.IndexOf(selectedElement.ID); + if (index == this.Timeline.ElementIDs.Count - 1) + return; + Guid elementId = this.Timeline.ElementIDs[index + 1]; + this.Timeline.ElementIDs[index + 1] = selectedElement.ID; + this.Timeline.ElementIDs[index] = elementId; + this.UpdateData(); + this.OnTimelineModified(new TimelineEventArgs(this.fTimeline)); + } + else if (e.Button == this.ExportBtn) + { + string str = "HTML Table Pages|*.html|HTML Diary Pages|*.html|JPG Images|*.jpg|GIF Images|*.gif|Bitmaps|*.bmp"; + try + { + SaveFileDialog saveFileDialog = new SaveFileDialog(); + saveFileDialog.FileName = this.fTimeline.Name; + saveFileDialog.Filter = str; + if (saveFileDialog.ShowDialog() != DialogResult.OK) + return; + switch (saveFileDialog.FilterIndex) + { + case 1: + string htmlTable = this.export_to_html_table(); + StreamWriter text1 = File.CreateText(saveFileDialog.FileName); + text1.WriteLine(htmlTable); + text1.Close(); + break; + + case 2: + string htmlDiary = this.export_to_html_diary(); + StreamWriter text2 = File.CreateText(saveFileDialog.FileName); + text2.WriteLine(htmlDiary); + text2.Close(); + break; + + case 3: + this.TimelineGrid.CreateImage().Save(saveFileDialog.FileName, ImageFormat.Jpeg); + break; + + case 4: + this.TimelineGrid.CreateImage().Save(saveFileDialog.FileName, ImageFormat.Gif); + break; + + case 5: + this.TimelineGrid.CreateImage().Save(saveFileDialog.FileName, ImageFormat.Bmp); + break; + } + } + catch (Exception ex) + { + LabyrinthData.Log((object)ex); + } + } + else if (e.Button == this.PrintBtn) + { + PrintDialog printDialog = new PrintDialog(); + printDialog.Document = this.create_print_doc(); + if (printDialog.ShowDialog() != DialogResult.OK) + return; + for (int index = 0; index != (int)printDialog.PrinterSettings.Copies; ++index) + printDialog.Document.Print(); + } + else if (e.Button == this.PrintPreviewBtn) + { + int num = (int)new PrintPreviewDialog() + { + Document = this.create_print_doc() + }.ShowDialog(); + } + else if (e.Button == this.ZoomInBtn) + { + ++this.fZoom; + this.resize_grid(); + } + else + { + if (e.Button != this.ZoomOutBtn) + return; + --this.fZoom; + if (this.fZoom < 0) + this.fZoom = 0; + this.resize_grid(); + } + } + catch (Exception ex) + { + LabyrinthData.Log((object)ex); + } + } + + private PrintDocument create_print_doc() + { + PrintDocument printDocument = new PrintDocument(); + printDocument.DocumentName = LabyrinthData.Project.Name + ": " + this.fTimeline.Name; + printDocument.PrintController = (PrintController)new StandardPrintController(); + printDocument.DefaultPageSettings = LabyrinthData.PageSettings; + printDocument.PrinterSettings = LabyrinthData.PrinterSettings; + printDocument.PrintPage += new PrintPageEventHandler(this.PrintPage); + return printDocument; + } + + private void PrintPage(object sender, PrintPageEventArgs e) + { + StringFormat format = new StringFormat(); + format.Alignment = StringAlignment.Center; + format.LineAlignment = StringAlignment.Center; + format.Trimming = StringTrimming.EllipsisCharacter; + string str = LabyrinthData.Project.Name + ": " + this.fTimeline.Name; + int height = (int)e.Graphics.MeasureString(str, this.Font, e.MarginBounds.Width).Height; + RectangleF layoutRectangle; + Rectangle marginBounds1 = e.MarginBounds; + double x = (double)marginBounds1.X; + marginBounds1 = e.MarginBounds; + double y = (double)marginBounds1.Y; + marginBounds1 = e.MarginBounds; + double width = (double)marginBounds1.Width; + double num = (double)height; + layoutRectangle = new RectangleF((float)x, (float)y, (float)width, (float)num); + e.Graphics.DrawString(str, this.Font, SystemBrushes.WindowText, layoutRectangle, format); + Rectangle marginBounds2 = e.MarginBounds; + marginBounds2.Y += height; + marginBounds2.Height -= height; + this.TimelineGrid.Render(e.Graphics, marginBounds2); + } + + private void TimelineGrid_DoubleClick(object sender, EventArgs e) + { + Element selectedElement = this.TimelineGrid.SelectedElement; + TimelinePoint selectedPoint = this.TimelineGrid.SelectedPoint; + if (selectedElement != null && selectedPoint != null) + { + if (this.get_annotation(selectedElement, selectedPoint) != null) + this.TimelineAnnotationProperties_Click(sender, e); + else + this.TimelineAddAnnotation_Click(sender, e); + } + else if (selectedElement != null && selectedPoint == null) + this.TimelineOpenElement_Click(sender, e); + else if (selectedElement == null && selectedPoint != null) + this.TimelinePointProperties_Click(sender, e); + else + this.TimelineAddPoint_Click(sender, e); + } + + private Annotation get_annotation(Element e, TimelinePoint tlp) + { + if (e != null && tlp != null) + { + foreach (TimelineItem timelineItem in tlp.Items) + { + if (timelineItem.ElementID == e.ID) + return (Annotation)timelineItem.Annotation; + } + } + return (Annotation)null; + } + + private Element get_element(Guid id) + { + int index = LabyrinthData.Project.Elements.IndexOf(id); + if (index != -1) + return LabyrinthData.Project.Elements[index]; + return (Element)null; + } + + private string export_to_html_table() + { + string str1 = "" + Environment.NewLine + LabyrinthData.HTMLHeader(this.fTimeline.Name) + Environment.NewLine + "" + Environment.NewLine + "

" + this.fTimeline.Name + "

" + Environment.NewLine + "
" + Environment.NewLine + "

" + Environment.NewLine + "Element" + Environment.NewLine + "

" + Environment.NewLine + "
" + Environment.NewLine + "

" + Environment.NewLine + "Link Text" + Environment.NewLine + "

" + Environment.NewLine + "
" + Environment.NewLine + "

" + Environment.NewLine + "Structure" + Environment.NewLine + "

" + Environment.NewLine + "
" + Environment.NewLine; + str3 = str3 + "

" + Environment.NewLine; + str3 = str3 + element.Name + Environment.NewLine; + str3 = str3 + "

" + Environment.NewLine; + str3 = str3 + "
" + Environment.NewLine; + str3 = str3 + "

" + Environment.NewLine; + str3 = str3 + tag.Description + Environment.NewLine; + str3 = str3 + "

" + Environment.NewLine; + str3 = str3 + "
" + Environment.NewLine; + str3 = str3 + "

" + Environment.NewLine; + str3 = str3 + structure1.Name + Environment.NewLine; + str3 = str3 + "

" + Environment.NewLine; + str3 = str3 + "
" + Environment.NewLine + "" + Environment.NewLine + "" + Environment.NewLine; + foreach (TimelinePoint point in this.fTimeline.Points) + { + str1 = str1 + "" + Environment.NewLine; + } + string str4 = str1 + "" + Environment.NewLine; + foreach (Guid elementId in this.fTimeline.ElementIDs) + { + str4 = str4 + "" + Environment.NewLine; + Element element = this.get_element(elementId); + str4 = str4 + "" + Environment.NewLine; + foreach (TimelinePoint point in this.fTimeline.Points) + { + str4 = str4 + "" + Environment.NewLine; + } + str4 = str4 + "" + Environment.NewLine; + } + return str4 + "
" + Environment.NewLine; + str1 = str1 + "

" + Environment.NewLine; + str1 = str1 + point.Name + Environment.NewLine; + str1 = str1 + "

" + Environment.NewLine; + DateTime schedule; + switch (point.UseSchedule) + { + case ScheduleType.Date: + string[] strArray1 = new string[5] + { + str1, + "

", + null, + null, + null + }; + string[] strArray2 = strArray1; + int index1 = 2; + schedule = point.Schedule; + string shortDateString1 = schedule.ToShortDateString(); + strArray2[index1] = shortDateString1; + strArray1[3] = "

"; + strArray1[4] = Environment.NewLine; + str1 = string.Concat(strArray1); + break; + + case ScheduleType.DateTime: + string str2 = str1; + string[] strArray3 = new string[7]; + strArray3[0] = str2; + strArray3[1] = "

"; + string[] strArray4 = strArray3; + int index2 = 2; + schedule = point.Schedule; + string shortDateString2 = schedule.ToShortDateString(); + strArray4[index2] = shortDateString2; + strArray3[3] = " "; + string[] strArray5 = strArray3; + int index3 = 4; + schedule = point.Schedule; + string str3 = schedule.ToString("HH:mm"); + strArray5[index3] = str3; + strArray3[5] = "

"; + strArray3[6] = Environment.NewLine; + str1 = string.Concat(strArray3); + break; + } + str1 = str1 + "
" + Environment.NewLine; + str4 = str4 + "

" + Environment.NewLine; + str4 = str4 + element.Name + Environment.NewLine; + str4 = str4 + "

" + Environment.NewLine; + str4 = str4 + "
" + Environment.NewLine; + ArrayList arrayList = new ArrayList(); + foreach (TimelineItem timelineItem in point.Items) + { + if (timelineItem.ElementID == elementId) + arrayList.Add((object)timelineItem.Annotation); + } + foreach (Annotation annotation in arrayList) + { + str4 = str4 + "

" + Environment.NewLine; + str4 = str4 + annotation.Title + Environment.NewLine; + str4 = str4 + "

" + Environment.NewLine; + str4 = str4 + "

" + Environment.NewLine; + str4 = str4 + annotation.Content.Replace("\n", "
") + Environment.NewLine; + str4 = str4 + "

" + Environment.NewLine; + } + str4 = str4 + "
" + Environment.NewLine + "" + Environment.NewLine + ""; + } + + private string export_to_html_diary() + { + string str1 = "" + Environment.NewLine + LabyrinthData.HTMLHeader(this.fTimeline.Name) + Environment.NewLine + "" + Environment.NewLine + "

" + this.fTimeline.Name + "

" + Environment.NewLine; + foreach (TimelinePoint point in this.fTimeline.Points) + { + str1 = str1 + "

" + point.Name + "

" + Environment.NewLine; + switch (point.UseSchedule) + { + case ScheduleType.Date: + str1 = str1 + "

" + point.Schedule.ToShortDateString() + "

" + Environment.NewLine; + break; + + case ScheduleType.DateTime: + string str2 = str1; + string[] strArray1 = new string[7]; + strArray1[0] = str2; + strArray1[1] = "

"; + string[] strArray2 = strArray1; + int index1 = 2; + DateTime schedule = point.Schedule; + string shortDateString = schedule.ToShortDateString(); + strArray2[index1] = shortDateString; + strArray1[3] = " "; + string[] strArray3 = strArray1; + int index2 = 4; + schedule = point.Schedule; + string str3 = schedule.ToString("HH:mm"); + strArray3[index2] = str3; + strArray1[5] = "

"; + strArray1[6] = Environment.NewLine; + str1 = string.Concat(strArray1); + break; + } + foreach (TimelineItem timelineItem in point.Items) + { + Element element = this.get_element(timelineItem.ElementID); + str1 = str1 + "

" + Environment.NewLine; + if (element != null) + str1 = str1 + element.Name + ": "; + str1 = str1 + timelineItem.Annotation.Title + Environment.NewLine; + str1 = str1 + "

" + Environment.NewLine; + str1 = str1 + "

" + Environment.NewLine; + str1 = str1 + timelineItem.Annotation.Content.Replace("\n", "
") + Environment.NewLine; + str1 = str1 + "

" + Environment.NewLine; + } + } + return str1 + "" + Environment.NewLine + ""; + } + + private void TimelinePanel_Layout(object sender, LayoutEventArgs e) + { + this.resize_grid(); + } + + private void resize_grid() + { + this.TimelineGrid.Size = new Size((int)((double)this.TimelineGrid.Parent.Width * Math.Pow(1.1, (double)this.fZoom)), (int)((double)this.TimelineGrid.Parent.Height * Math.Pow(1.1, (double)this.fZoom))); + } + } +} \ No newline at end of file diff --git a/Labyrinth3/IDE/Pages/TimelinePage.resx b/Labyrinth3/IDE/Pages/TimelinePage.resx new file mode 100644 index 0000000..e812521 --- /dev/null +++ b/Labyrinth3/IDE/Pages/TimelinePage.resx @@ -0,0 +1,194 @@ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + text/microsoft-resx + + + 2.0 + + + System.Resources.ResXResourceReader, System.Windows.Forms, Version=4.0.0.0, Culture=neutral, PublicKeyToken=b77a5c561934e089 + + + System.Resources.ResXResourceWriter, System.Windows.Forms, Version=4.0.0.0, Culture=neutral, PublicKeyToken=b77a5c561934e089 + + + TimelinePage + + + + 17, 17 + + + + 57 + + + 143, 17 + + + + AAEAAAD/////AQAAAAAAAAAMAgAAAFdTeXN0ZW0uV2luZG93cy5Gb3JtcywgVmVyc2lvbj00LjAuMC4w + LCBDdWx0dXJlPW5ldXRyYWwsIFB1YmxpY0tleVRva2VuPWI3N2E1YzU2MTkzNGUwODkFAQAAACZTeXN0 + ZW0uV2luZG93cy5Gb3Jtcy5JbWFnZUxpc3RTdHJlYW1lcgEAAAAERGF0YQcCAgAAAAkDAAAADwMAAABC + DAAAAk1TRnQBSQFMAgEBCgEAAQ4BAAEIAQABEAEAARABAAT/AQkBEAj/AUIBTQE2AQQGAAE2AQQCAAEo + AwABQAMAATADAAEBAQABCAYAAQwYAAGAAgABgAMAAoABAAGAAwABgAEAAYABAAKAAgADwAEAAcAB3AHA + AQAB8AHKAaYBAAEzBQABMwEAATMBAAEzAQACMwIAAxYBAAMcAQADIgEAAykBAANVAQADTQEAA0IBAAM5 + AQABgAF8Af8BAAJQAf8BAAGTAQAB1gEAAf8B7AHMAQABxgHWAe8BAAHWAucBAAGQAakBrQIAAf8BMwMA + AWYDAAGZAwABzAIAATMDAAIzAgABMwFmAgABMwGZAgABMwHMAgABMwH/AgABZgMAAWYBMwIAAmYCAAFm + AZkCAAFmAcwCAAFmAf8CAAGZAwABmQEzAgABmQFmAgACmQIAAZkBzAIAAZkB/wIAAcwDAAHMATMCAAHM + AWYCAAHMAZkCAALMAgABzAH/AgAB/wFmAgAB/wGZAgAB/wHMAQABMwH/AgAB/wEAATMBAAEzAQABZgEA + ATMBAAGZAQABMwEAAcwBAAEzAQAB/wEAAf8BMwIAAzMBAAIzAWYBAAIzAZkBAAIzAcwBAAIzAf8BAAEz + AWYCAAEzAWYBMwEAATMCZgEAATMBZgGZAQABMwFmAcwBAAEzAWYB/wEAATMBmQIAATMBmQEzAQABMwGZ + AWYBAAEzApkBAAEzAZkBzAEAATMBmQH/AQABMwHMAgABMwHMATMBAAEzAcwBZgEAATMBzAGZAQABMwLM + AQABMwHMAf8BAAEzAf8BMwEAATMB/wFmAQABMwH/AZkBAAEzAf8BzAEAATMC/wEAAWYDAAFmAQABMwEA + AWYBAAFmAQABZgEAAZkBAAFmAQABzAEAAWYBAAH/AQABZgEzAgABZgIzAQABZgEzAWYBAAFmATMBmQEA + AWYBMwHMAQABZgEzAf8BAAJmAgACZgEzAQADZgEAAmYBmQEAAmYBzAEAAWYBmQIAAWYBmQEzAQABZgGZ + AWYBAAFmApkBAAFmAZkBzAEAAWYBmQH/AQABZgHMAgABZgHMATMBAAFmAcwBmQEAAWYCzAEAAWYBzAH/ + AQABZgH/AgABZgH/ATMBAAFmAf8BmQEAAWYB/wHMAQABzAEAAf8BAAH/AQABzAEAApkCAAGZATMBmQEA + AZkBAAGZAQABmQEAAcwBAAGZAwABmQIzAQABmQEAAWYBAAGZATMBzAEAAZkBAAH/AQABmQFmAgABmQFm + ATMBAAGZATMBZgEAAZkBZgGZAQABmQFmAcwBAAGZATMB/wEAApkBMwEAApkBZgEAA5kBAAKZAcwBAAKZ + Af8BAAGZAcwCAAGZAcwBMwEAAWYBzAFmAQABmQHMAZkBAAGZAswBAAGZAcwB/wEAAZkB/wIAAZkB/wEz + AQABmQHMAWYBAAGZAf8BmQEAAZkB/wHMAQABmQL/AQABzAMAAZkBAAEzAQABzAEAAWYBAAHMAQABmQEA + AcwBAAHMAQABmQEzAgABzAIzAQABzAEzAWYBAAHMATMBmQEAAcwBMwHMAQABzAEzAf8BAAHMAWYCAAHM + AWYBMwEAAZkCZgEAAcwBZgGZAQABzAFmAcwBAAGZAWYB/wEAAcwBmQIAAcwBmQEzAQABzAGZAWYBAAHM + ApkBAAHMAZkBzAEAAcwBmQH/AQACzAIAAswBMwEAAswBZgEAAswBmQEAA8wBAALMAf8BAAHMAf8CAAHM + Af8BMwEAAZkB/wFmAQABzAH/AZkBAAHMAf8BzAEAAcwC/wEAAcwBAAEzAQAB/wEAAWYBAAH/AQABmQEA + AcwBMwIAAf8CMwEAAf8BMwFmAQAB/wEzAZkBAAH/ATMBzAEAAf8BMwH/AQAB/wFmAgAB/wFmATMBAAHM + AmYBAAH/AWYBmQEAAf8BZgHMAQABzAFmAf8BAAH/AZkCAAH/AZkBMwEAAf8BmQFmAQAB/wKZAQAB/wGZ + AcwBAAH/AZkB/wEAAf8BzAIAAf8BzAEzAQAB/wHMAWYBAAH/AcwBmQEAAf8CzAEAAf8BzAH/AQAC/wEz + AQABzAH/AWYBAAL/AZkBAAL/AcwBAAJmAf8BAAFmAf8BZgEAAWYC/wEAAf8CZgEAAf8BZgH/AQAC/wFm + AQABIQEAAaUBAANfAQADdwEAA4YBAAOWAQADywEAA7IBAAPXAQAD3QEAA+MBAAPqAQAD8QEAA/gBAAHw + AfsB/wEAAaQCoAEAA4ADAAH/AgAB/wMAAv8BAAH/AwAB/wEAAf8BAAL/AgAD/04AAgEOAAIBLQADAQ0A + AwEsAAMBDQADAScAA+wCAAMBCAAD7AIAAwEmAALsAwAC7AIBBwAC7AMAAuwCASYAAewCAAPsAgAB7AcA + AewHAAHsJwAB7AIAAewB/wHsAgAB7AcAAewHAAHsJgAB7AEAA+wB/wPsAQAB7AUAAewBAAfsAQAB7CUA + AewBAAHsBf8B7AEAAewFAAHsAQAB7AX/AewBAAHsJQAB7AEAA+wB/wPsAQAB7AUAAewBAAfsAQAB7CYA + AewCAAHsAf8B7AIAAewHAAHsBwAB7CcAAewCAAPsAgAB7AcAAewHAAHsKAAC7AMAAuwJAALsAwAC7CsA + A+wNAAPshAAB/CsAAuwSAAL8KQACAQLsDAAI/BIACv8LAAQBAuwLAAn8AgAJBwEAAQcEAAf/DQAGAQLs + CgAI/A4AAQcDAAb/AgACBwkACAEQAAL8AwAGBwP7AgcFAAX/AgACBwH+CwAEAQHsEQAB/AQABgcDAAIH + AQABBwMABf8BAAQHCwAEAQHsIgACBwIABf8BAAEHAf4CBwsABAEB7BYACgcBAAEHAQABBwIABf8CAAL+ + AQcLAAQBAewgAAEHAQABBwMABv8CAAIHCwAEAQHsGAAI/wEAAQcBAAEHAgAH/w4ABAEB7BkAAf8FAAH/ + BgAK/wsABAEB7BkACP8FAAf/DgAEARsAAf8FAAH/BQAH/wEAAQcrAAj/BAAH/78ABOwGAAr/KwAEAQHs + BgAB/wIAAf8FAAH/CwAB7BQAAewKAAQBAewGAAr/CgABAQHsEwABAQLsCQAEAQHsBgAB/wIAAf8FAAH/ + CQACAQnsBAAH7AIBAuwIAAQBAewGAAr/CAALAQHsAwALAQLsBwAEAQHsBgAH/wEAAv8HAAwBAewDAAwB + AewHAAQBAewGAAH/AgAD/wEAAQcBAAH/BwAMAQHsAwAMAQgABAEB7AYAAf8BAAEHAQAB/wEAAQcBAAEH + BAACBAMACwEEAAsBCQAEAQPsBAAC/wEAAQcBAAEHAQABBwEAAwcBAAIEBAACARQAAgEIAAgBCQABBwEA + AQcBAAUHAgQFAAEBFAABAQoABgELAAEHAQAGBwIEJgAEAQ0ABgcBAAIEJwACARUAAgRwAAFCAU0BPgcA + AT4DAAEoAwABQAMAATADAAEBAQABAQUAAYABARYAA/8BAAT/BAAB/wH5Af8B+QQAAf8B8QH/AfEEAAH/ + AeMB/wHjBAAB+AHHAfgBxwQAAecBDwHnAQ8EAAHYA98EAAHYA98EAAGgAS8BoAEvBAABoAEvAaABLwQA + AaABLwGgAS8EAAHYA98EAAHYA98EAAHnAT8B5wE/BAAB+AH/AfgB/wQABP8EAAP/AfcF/wE/Af8B8wL/ + AQABDAH+AR8B/gEBAcABBwEAAQgB/AEPAf4BAAGAAQMBAAEBAfgBBwH+AQEBAAEBAQABAwHwAQ8B/wHz + AQABAQEAAQMB/AEfAf8B9wEAAQEBAAELAfwBHwHfAf0DAAELAfwBHwHfAf0DAAEDAfwBHwHbAW0BgAIA + AQcB/AEfAdsBbQHAAgABDwH8AR8BwAEBAeABAQEAAQ8B/AEfAv8B4AEHAQABDwH8AT8C/wHwAQcBAAEf + BP8B8AEDAQABPwT/AfgBAwEAAX8I/wEAAQ8E/wH+AR8BAAEPBP8B/AEfAQABDwH9Av8B7wH8AR8BAAEP + AfkC/wHHAfwBHwEAAQ8B8AEBAeABAwH8AR8BAAEPAeABAQHAAQEB/AEfAQABDwHAAQEBwAEBAfwBHwEA + AQ8BwAEBAcABAwH8AR8BAAEEAeABAwHAAQcB/AEHAgAB8wL/Ac8B8AEPAgAB+wL/Ad8B+AEfAfgBAAT/ + AfwBPwH8AQAE/wH+AX8B/gEEDv8WAAs= + + + \ No newline at end of file diff --git a/Labyrinth3/IDE/StartupData.cs b/Labyrinth3/IDE/StartupData.cs new file mode 100644 index 0000000..590fba1 --- /dev/null +++ b/Labyrinth3/IDE/StartupData.cs @@ -0,0 +1,44 @@ +// Decompiled with JetBrains decompiler +// Type: Labyrinth.StartupData +// Assembly: Labyrinth, Version=3.6.1928.15690, Culture=neutral, PublicKeyToken=null +// MVID: 1462002E-0BD1-49D2-9B56-C22E66C903E7 +// Assembly location: C:\Dropbox\Workspace\Programs\Labyrinth\Labyrinth.exe + +using System.IO; + +namespace Labyrinth +{ + public class StartupData + { + private string fFileName = ""; + private string fAddInPath = ""; + + public string FileName + { + get + { + return this.fFileName; + } + set + { + if (!File.Exists(value)) + return; + this.fFileName = value; + } + } + + public string AddInPath + { + get + { + return this.fAddInPath; + } + set + { + if (!Directory.Exists(value)) + return; + this.fAddInPath = value; + } + } + } +} \ No newline at end of file diff --git a/Labyrinth3/Labyrinth3.csproj b/Labyrinth3/Labyrinth3.csproj new file mode 100644 index 0000000..a5d344f --- /dev/null +++ b/Labyrinth3/Labyrinth3.csproj @@ -0,0 +1,491 @@ + + + + + Debug + AnyCPU + {B4700781-94F1-41A2-BBD5-4E2E887C66B0} + WinExe + Labyrinth3 + Labyrinth3 + v4.0 + 512 + + + AnyCPU + true + full + false + bin\Debug\ + DEBUG;TRACE + prompt + 4 + true + + + AnyCPU + pdbonly + true + bin\Release\ + TRACE + prompt + 4 + true + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + Component + + + UserControl + + + Component + + + Component + + + UserControl + + + UserControl + + + UserControl + + + + + Form + + + Form + + + Form + + + Form + + + Form + + + Form + + + Form + + + Form + + + Form + + + Form + + + Form + + + Form + + + Form + + + Form + + + + + + Form + + + UserControl + + + UserControl + + + UserControl + + + UserControl + + + UserControl + + + UserControl + + + UserControl + + + UserControl + + + + + + + + + + + + + + + + + + + + + + + + UserControl + + + Component + + + Component + + + + UserControl + + + + + + + Component + + + + Component + + + UserControl + + + + Component + + + Component + + + + + + Form + + + + + + + + + + + + UserControl + + + Component + + + Component + + + Component + + + Component + + + Component + + + Component + + + + Component + + + Form + + + + Component + + + Component + + + + + + + + + + + AnnotationList.cs + + + AnnotationPanel.cs + + + ColorPanel.cs + + + ElementTypeBox.cs + + + RTFPanel.cs + + + StructureView.cs + + + TimelineGrid.cs + + + AboutDlg.cs + + + AddInDlg.cs + + + ElementDlg.cs + + + FileLinkAnnotationDlg.cs + + + LinkDlg.cs + + + MergeElementsDlg.cs + + + NoteDlg.cs + + + ProjectDlg.cs + + + SketchAnnotationDlg.cs + + + StructureDlg.cs + + + TaskDlg.cs + + + TextAnnotationDlg.cs + + + TimelineDlg.cs + + + TimelinePointDlg.cs + + + LabyrinthData.cs + + + MainForm.cs + + + AnnotationPage.cs + + + CalendarPage.cs + + + ElementPage.cs + + + NotePage.cs + + + SearchPage.cs + + + StructurePage.cs + + + TaskPage.cs + + + TimelinePage.cs + + + BorderForControl.cs + + + InertButton.cs + + + ResizeBar.cs + + + TabbedGroups.cs + + + TabControl.cs + + + TabPage.cs + + + WizardControl.cs + + + WizardPage.cs + + + AutoHidePanel.cs + + + FloatinglForm.cs + + + Window.cs + + + WindowDetail.cs + + + WindowDetailCaption.cs + + + Zone.cs + + + WizardDialog.cs + + + MenuCommand.cs + + + MenuControl.cs + + + ResXFileCodeGenerator + Resources.Designer.cs + Designer + + + True + Resources.resx + + + SettingsSingleFileGenerator + Settings.Designer.cs + + + True + Settings.settings + True + + + + + + + + + + + + + + + + + + + + + + \ No newline at end of file diff --git a/Labyrinth3/Program.cs b/Labyrinth3/Program.cs new file mode 100644 index 0000000..89af5b1 --- /dev/null +++ b/Labyrinth3/Program.cs @@ -0,0 +1,8 @@ +namespace Labyrinth3 +{ + internal static class Program + { + // Enable to ex. disable the fonts menu so that copypasting won't change the font + public const bool ZEKKA_WORKAROUNDS = false; + } +} \ No newline at end of file diff --git a/Labyrinth3/Properties/AssemblyInfo.cs b/Labyrinth3/Properties/AssemblyInfo.cs new file mode 100644 index 0000000..7b25cb3 --- /dev/null +++ b/Labyrinth3/Properties/AssemblyInfo.cs @@ -0,0 +1,35 @@ +using System.Reflection; +using System.Runtime.InteropServices; + +// General Information about an assembly is controlled through the following +// set of attributes. Change these attribute values to modify the information +// associated with an assembly. +[assembly: AssemblyTitle("Labyrinth")] +[assembly: AssemblyDescription("Labyrinth Plot Development Enviromnent")] +[assembly: AssemblyConfiguration("")] +[assembly: AssemblyCompany("")] +[assembly: AssemblyProduct("Labyrinth3")] +[assembly: AssemblyCopyright("Karetao 2004 [ported by Zekka]")] +[assembly: AssemblyTrademark("")] +[assembly: AssemblyCulture("")] + +// Setting ComVisible to false makes the types in this assembly not visible +// to COM components. If you need to access a type in this assembly from +// COM, set the ComVisible attribute to true on that type. +[assembly: ComVisible(false)] + +// The following GUID is for the ID of the typelib if this project is exposed to COM +[assembly: Guid("b4700781-94f1-41a2-bbd5-4e2e887c66b0")] + +// Version information for an assembly consists of the following four values: +// +// Major Version +// Minor Version +// Build Number +// Revision +// +// You can specify all the values or you can default the Build and Revision Numbers +// by using the '*' as shown below: +// [assembly: AssemblyVersion("1.0.*")] +[assembly: AssemblyVersion("1.0.0.0")] +[assembly: AssemblyFileVersion("1.0.0.0")] \ No newline at end of file diff --git a/Labyrinth3/Properties/Resources.Designer.cs b/Labyrinth3/Properties/Resources.Designer.cs new file mode 100644 index 0000000..01a2a6e --- /dev/null +++ b/Labyrinth3/Properties/Resources.Designer.cs @@ -0,0 +1,71 @@ +//------------------------------------------------------------------------------ +// +// This code was generated by a tool. +// Runtime Version:4.0.30319.42000 +// +// Changes to this file may cause incorrect behavior and will be lost if +// the code is regenerated. +// +//------------------------------------------------------------------------------ + +namespace Labyrinth3.Properties +{ + + + /// + /// A strongly-typed resource class, for looking up localized strings, etc. + /// + // This class was auto-generated by the StronglyTypedResourceBuilder + // class via a tool like ResGen or Visual Studio. + // To add or remove a member, edit your .ResX file then rerun ResGen + // with the /str option, or rebuild your VS project. + [global::System.CodeDom.Compiler.GeneratedCodeAttribute("System.Resources.Tools.StronglyTypedResourceBuilder", "4.0.0.0")] + [global::System.Diagnostics.DebuggerNonUserCodeAttribute()] + [global::System.Runtime.CompilerServices.CompilerGeneratedAttribute()] + internal class Resources + { + + private static global::System.Resources.ResourceManager resourceMan; + + private static global::System.Globalization.CultureInfo resourceCulture; + + [global::System.Diagnostics.CodeAnalysis.SuppressMessageAttribute("Microsoft.Performance", "CA1811:AvoidUncalledPrivateCode")] + internal Resources() + { + } + + /// + /// Returns the cached ResourceManager instance used by this class. + /// + [global::System.ComponentModel.EditorBrowsableAttribute(global::System.ComponentModel.EditorBrowsableState.Advanced)] + internal static global::System.Resources.ResourceManager ResourceManager + { + get + { + if ((resourceMan == null)) + { + global::System.Resources.ResourceManager temp = new global::System.Resources.ResourceManager("Labyrinth3.Properties.Resources", typeof(Resources).Assembly); + resourceMan = temp; + } + return resourceMan; + } + } + + /// + /// Overrides the current thread's CurrentUICulture property for all + /// resource lookups using this strongly typed resource class. + /// + [global::System.ComponentModel.EditorBrowsableAttribute(global::System.ComponentModel.EditorBrowsableState.Advanced)] + internal static global::System.Globalization.CultureInfo Culture + { + get + { + return resourceCulture; + } + set + { + resourceCulture = value; + } + } + } +} diff --git a/Labyrinth3/Properties/Resources.resx b/Labyrinth3/Properties/Resources.resx new file mode 100644 index 0000000..af7dbeb --- /dev/null +++ b/Labyrinth3/Properties/Resources.resx @@ -0,0 +1,117 @@ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + text/microsoft-resx + + + 2.0 + + + System.Resources.ResXResourceReader, System.Windows.Forms, Version=2.0.0.0, Culture=neutral, PublicKeyToken=b77a5c561934e089 + + + System.Resources.ResXResourceWriter, System.Windows.Forms, Version=2.0.0.0, Culture=neutral, PublicKeyToken=b77a5c561934e089 + + \ No newline at end of file diff --git a/Labyrinth3/Properties/Settings.Designer.cs b/Labyrinth3/Properties/Settings.Designer.cs new file mode 100644 index 0000000..63e5ee4 --- /dev/null +++ b/Labyrinth3/Properties/Settings.Designer.cs @@ -0,0 +1,30 @@ +//------------------------------------------------------------------------------ +// +// This code was generated by a tool. +// Runtime Version:4.0.30319.42000 +// +// Changes to this file may cause incorrect behavior and will be lost if +// the code is regenerated. +// +//------------------------------------------------------------------------------ + +namespace Labyrinth3.Properties +{ + + + [global::System.Runtime.CompilerServices.CompilerGeneratedAttribute()] + [global::System.CodeDom.Compiler.GeneratedCodeAttribute("Microsoft.VisualStudio.Editors.SettingsDesigner.SettingsSingleFileGenerator", "11.0.0.0")] + internal sealed partial class Settings : global::System.Configuration.ApplicationSettingsBase + { + + private static Settings defaultInstance = ((Settings)(global::System.Configuration.ApplicationSettingsBase.Synchronized(new Settings()))); + + public static Settings Default + { + get + { + return defaultInstance; + } + } + } +} diff --git a/Labyrinth3/Properties/Settings.settings b/Labyrinth3/Properties/Settings.settings new file mode 100644 index 0000000..3964565 --- /dev/null +++ b/Labyrinth3/Properties/Settings.settings @@ -0,0 +1,7 @@ + + + + + + +