aboutsummaryrefslogtreecommitdiff
path: root/source/ShiftUI/Design
diff options
context:
space:
mode:
Diffstat (limited to 'source/ShiftUI/Design')
-rw-r--r--source/ShiftUI/Design/Behavior/Adorner.cs81
-rw-r--r--source/ShiftUI/Design/Behavior/Behavior.cs155
-rw-r--r--source/ShiftUI/Design/Behavior/BehaviorDragDropEventArgs.cs50
-rw-r--r--source/ShiftUI/Design/Behavior/BehaviorDragDropEventHandler.cs36
-rw-r--r--source/ShiftUI/Design/Behavior/BehaviorService.cs154
-rw-r--r--source/ShiftUI/Design/Behavior/BehaviorServiceAdornerCollection.cs128
-rw-r--r--source/ShiftUI/Design/Behavior/BehaviorServiceAdornerCollectionEnumerator.cs90
-rw-r--r--source/ShiftUI/Design/Behavior/ComponentGlyph.cs73
-rw-r--r--source/ShiftUI/Design/Behavior/ControlBodyGlyph.cs70
-rw-r--r--source/ShiftUI/Design/Behavior/Glyph.cs70
-rw-r--r--source/ShiftUI/Design/Behavior/GlyphCollection.cs111
-rw-r--r--source/ShiftUI/Design/Behavior/GlyphSelectionType.cs41
-rw-r--r--source/ShiftUI/Design/Behavior/SnapLine.cs133
-rw-r--r--source/ShiftUI/Design/Behavior/SnapLinePriority.cs42
-rw-r--r--source/ShiftUI/Design/Behavior/SnapLineType.cs45
-rw-r--r--source/ShiftUI/Design/ComponentDesigner.cs438
-rw-r--r--source/ShiftUI/Design/ComponentEditorForm.cs96
-rw-r--r--source/ShiftUI/Design/ComponentEditorPage.cs210
-rw-r--r--source/ShiftUI/Design/ComponentTray.cs247
-rw-r--r--source/ShiftUI/Design/Consts.cs100
-rw-r--r--source/ShiftUI/Design/ControlDataObject.cs120
-rw-r--r--source/ShiftUI/Design/ControlDesigner.cs974
-rw-r--r--source/ShiftUI/Design/DefaultMenuCommands.cs274
-rw-r--r--source/ShiftUI/Design/DocumentDesigner.cs485
-rw-r--r--source/ShiftUI/Design/EventsTab.cs101
-rw-r--r--source/ShiftUI/Design/FormDocumentDesigner.cs86
-rw-r--r--source/ShiftUI/Design/IMenuEditorService.cs34
-rw-r--r--source/ShiftUI/Design/IMessageReceiver.cs39
-rw-r--r--source/ShiftUI/Design/IUISelectionService.cs71
-rw-r--r--source/ShiftUI/Design/IUIService.cs52
-rw-r--r--source/ShiftUI/Design/IWindowsFormsEditorService.cs35
-rw-r--r--source/ShiftUI/Design/Native.cs216
-rw-r--r--source/ShiftUI/Design/ParentControlDesigner.cs726
-rw-r--r--source/ShiftUI/Design/PropertyTab.cs102
-rw-r--r--source/ShiftUI/Design/ScrollableControlDesigner.cs83
-rw-r--r--source/ShiftUI/Design/SelectionFrame.cs481
-rw-r--r--source/ShiftUI/Design/SelectionRules.cs47
-rw-r--r--source/ShiftUI/Design/ToolStripItemDesignerAvailability.cs43
-rw-r--r--source/ShiftUI/Design/ToolStripItemDesignerAvailabilityAttribute.cs81
-rw-r--r--source/ShiftUI/Design/UISelectionService.cs532
-rw-r--r--source/ShiftUI/Design/WindowsFormsComponentEditor.cs65
-rw-r--r--source/ShiftUI/Design/WndProcRouter.cs117
42 files changed, 7134 insertions, 0 deletions
diff --git a/source/ShiftUI/Design/Behavior/Adorner.cs b/source/ShiftUI/Design/Behavior/Adorner.cs
new file mode 100644
index 0000000..f67c6af
--- /dev/null
+++ b/source/ShiftUI/Design/Behavior/Adorner.cs
@@ -0,0 +1,81 @@
+//
+// ShiftUI.Design.Behavior.Adorner
+//
+// Author:
+// Atsushi Enomoto ([email protected])
+//
+// Copyright (C) 2007 Novell, Inc.
+//
+
+//
+// Permission is hereby granted, free of charge, to any person obtaining
+// a copy of this software and associated documentation files (the
+// "Software"), to deal in the Software without restriction, including
+// without limitation the rights to use, copy, modify, merge, publish,
+// distribute, sublicense, and/or sell copies of the Software, and to
+// permit persons to whom the Software is furnished to do so, subject to
+// the following conditions:
+//
+// The above copyright notice and this permission notice shall be
+// included in all copies or substantial portions of the Software.
+//
+// THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND,
+// EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF
+// MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND
+// NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE
+// LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION
+// OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION
+// WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
+//
+
+
+using System;
+using System.Drawing;
+using System.Drawing.Design;
+using System.Drawing.Drawing2D;
+
+namespace ShiftUI.Design.Behavior
+{
+ public sealed class Adorner
+ {
+ public Adorner ()
+ {
+ }
+
+ [MonoTODO]
+ public void Invalidate ()
+ {
+ throw new NotImplementedException ();
+ }
+
+ [MonoTODO]
+ public void Invalidate (Rectangle rectangle)
+ {
+ throw new NotImplementedException ();
+ }
+
+ [MonoTODO]
+ public void Invalidate (Region region)
+ {
+ throw new NotImplementedException ();
+ }
+
+ [MonoTODO]
+ public BehaviorService BehaviorService {
+ get { throw new NotImplementedException (); }
+ set { throw new NotImplementedException (); }
+ }
+
+ [MonoTODO]
+ public bool Enabled {
+ get { throw new NotImplementedException (); }
+ set { throw new NotImplementedException (); }
+ }
+
+ [MonoTODO]
+ public GlyphCollection Glyphs {
+ get { throw new NotImplementedException (); }
+ }
+ }
+}
+
diff --git a/source/ShiftUI/Design/Behavior/Behavior.cs b/source/ShiftUI/Design/Behavior/Behavior.cs
new file mode 100644
index 0000000..df6185a
--- /dev/null
+++ b/source/ShiftUI/Design/Behavior/Behavior.cs
@@ -0,0 +1,155 @@
+//
+// ShiftUI.Design.Behavior.Behavior
+//
+// Author:
+// Atsushi Enomoto ([email protected])
+//
+// Copyright (C) 2007 Novell, Inc.
+//
+
+//
+// Permission is hereby granted, free of charge, to any person obtaining
+// a copy of this software and associated documentation files (the
+// "Software"), to deal in the Software without restriction, including
+// without limitation the rights to use, copy, modify, merge, publish,
+// distribute, sublicense, and/or sell copies of the Software, and to
+// permit persons to whom the Software is furnished to do so, subject to
+// the following conditions:
+//
+// The above copyright notice and this permission notice shall be
+// included in all copies or substantial portions of the Software.
+//
+// THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND,
+// EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF
+// MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND
+// NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE
+// LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION
+// OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION
+// WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
+//
+
+
+using System;
+using System.ComponentModel.Design;
+using System.Drawing;
+using System.Drawing.Design;
+using System.Drawing.Drawing2D;
+
+namespace ShiftUI.Design.Behavior
+{
+ public abstract class Behavior
+ {
+ [MonoTODO]
+ protected Behavior ()
+ {
+ throw new NotImplementedException ();
+ }
+
+ [MonoTODO]
+ protected Behavior (bool callParentBehavior, BehaviorService behaviorService)
+ {
+ throw new NotImplementedException ();
+ }
+
+ [MonoTODO]
+ public virtual Cursor Cursor {
+ get { throw new NotImplementedException (); }
+ }
+
+ [MonoTODO]
+ public virtual bool DisableAllCommands {
+ get { throw new NotImplementedException (); }
+ }
+
+ [MonoTODO]
+ public virtual MenuCommand FindCommand (CommandID commandId)
+ {
+ throw new NotImplementedException ();
+ }
+
+ [MonoTODO]
+ public virtual void OnDragDrop (Glyph g, DragEventArgs e)
+ {
+ throw new NotImplementedException ();
+ }
+
+ [MonoTODO]
+ public virtual void OnDragEnter (Glyph g, DragEventArgs e)
+ {
+ throw new NotImplementedException ();
+ }
+
+ [MonoTODO]
+ public virtual void OnDragLeave (Glyph g, EventArgs e)
+ {
+ throw new NotImplementedException ();
+ }
+
+ [MonoTODO]
+ public virtual void OnDragOver (Glyph g, DragEventArgs e)
+ {
+ throw new NotImplementedException ();
+ }
+
+ [MonoTODO]
+ public virtual void OnGiveFeedback (Glyph g, GiveFeedbackEventArgs e)
+ {
+ throw new NotImplementedException ();
+ }
+
+ [MonoTODO]
+ public virtual void OnLoseCapture (Glyph g, EventArgs e)
+ {
+ throw new NotImplementedException ();
+ }
+
+ [MonoTODO]
+ public virtual bool OnMouseDoubleClick (Glyph g, MouseButtons button, Point mouseLoc)
+ {
+ throw new NotImplementedException ();
+ }
+
+ [MonoTODO]
+ public virtual bool OnMouseDown (Glyph g, MouseButtons button, Point mouseLoc)
+ {
+ throw new NotImplementedException ();
+ }
+
+ [MonoTODO]
+ public virtual bool OnMouseEnter (Glyph g)
+ {
+ throw new NotImplementedException ();
+ }
+
+ [MonoTODO]
+ public virtual bool OnMouseHover (Glyph g, Point mouseLoc)
+ {
+ throw new NotImplementedException ();
+ }
+
+ [MonoTODO]
+ public virtual bool OnMouseLeave (Glyph g)
+ {
+ throw new NotImplementedException ();
+ }
+
+ [MonoTODO]
+ public virtual bool OnMouseMove (Glyph g, MouseButtons button, Point mouseLoc)
+ {
+ throw new NotImplementedException ();
+ }
+
+ [MonoTODO]
+ public virtual bool OnMouseUp (Glyph g, MouseButtons button)
+ {
+ throw new NotImplementedException ();
+ }
+
+ [MonoTODO]
+ public virtual void OnQueryContinueDrag (Glyph g, QueryContinueDragEventArgs e)
+ {
+ throw new NotImplementedException ();
+ }
+ }
+}
+
diff --git a/source/ShiftUI/Design/Behavior/BehaviorDragDropEventArgs.cs b/source/ShiftUI/Design/Behavior/BehaviorDragDropEventArgs.cs
new file mode 100644
index 0000000..9a22361
--- /dev/null
+++ b/source/ShiftUI/Design/Behavior/BehaviorDragDropEventArgs.cs
@@ -0,0 +1,50 @@
+//
+// ShiftUI.Design.Behavior.BehaviorDragDropEventArgs
+//
+// Author:
+// Atsushi Enomoto ([email protected])
+//
+// Copyright (C) 2007 Novell, Inc.
+//
+
+//
+// Permission is hereby granted, free of charge, to any person obtaining
+// a copy of this software and associated documentation files (the
+// "Software"), to deal in the Software without restriction, including
+// without limitation the rights to use, copy, modify, merge, publish,
+// distribute, sublicense, and/or sell copies of the Software, and to
+// permit persons to whom the Software is furnished to do so, subject to
+// the following conditions:
+//
+// The above copyright notice and this permission notice shall be
+// included in all copies or substantial portions of the Software.
+//
+// THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND,
+// EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF
+// MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND
+// NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE
+// LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION
+// OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION
+// WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
+//
+
+using System;
+using System.Collections;
+
+namespace ShiftUI.Design.Behavior
+{
+ public class BehaviorDragDropEventArgs : EventArgs
+ {
+ ICollection components;
+
+ public BehaviorDragDropEventArgs (ICollection dragComponents)
+ {
+ this.components = dragComponents;
+ }
+
+ public ICollection DragComponents {
+ get { return components; }
+ }
+ }
+}
+
diff --git a/source/ShiftUI/Design/Behavior/BehaviorDragDropEventHandler.cs b/source/ShiftUI/Design/Behavior/BehaviorDragDropEventHandler.cs
new file mode 100644
index 0000000..83c1ef3
--- /dev/null
+++ b/source/ShiftUI/Design/Behavior/BehaviorDragDropEventHandler.cs
@@ -0,0 +1,36 @@
+//
+// ShiftUI.Design.Behavior.BehaviorDragDropEventHandler
+//
+// Author:
+// Atsushi Enomoto ([email protected])
+//
+// Copyright (C) 2007 Novell, Inc.
+//
+
+//
+// Permission is hereby granted, free of charge, to any person obtaining
+// a copy of this software and associated documentation files (the
+// "Software"), to deal in the Software without restriction, including
+// without limitation the rights to use, copy, modify, merge, publish,
+// distribute, sublicense, and/or sell copies of the Software, and to
+// permit persons to whom the Software is furnished to do so, subject to
+// the following conditions:
+//
+// The above copyright notice and this permission notice shall be
+// included in all copies or substantial portions of the Software.
+//
+// THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND,
+// EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF
+// MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND
+// NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE
+// LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION
+// OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION
+// WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
+//
+
+
+namespace ShiftUI.Design.Behavior
+{
+ public delegate void BehaviorDragDropEventHandler (object sender, BehaviorDragDropEventArgs e);
+}
+
diff --git a/source/ShiftUI/Design/Behavior/BehaviorService.cs b/source/ShiftUI/Design/Behavior/BehaviorService.cs
new file mode 100644
index 0000000..cc741b1
--- /dev/null
+++ b/source/ShiftUI/Design/Behavior/BehaviorService.cs
@@ -0,0 +1,154 @@
+//
+// ShiftUI.Design.Behavior.BehaviorService
+//
+// Author:
+// Atsushi Enomoto ([email protected])
+//
+// Copyright (C) 2007 Novell, Inc.
+//
+
+//
+// Permission is hereby granted, free of charge, to any person obtaining
+// a copy of this software and associated documentation files (the
+// "Software"), to deal in the Software without restriction, including
+// without limitation the rights to use, copy, modify, merge, publish,
+// distribute, sublicense, and/or sell copies of the Software, and to
+// permit persons to whom the Software is furnished to do so, subject to
+// the following conditions:
+//
+// The above copyright notice and this permission notice shall be
+// included in all copies or substantial portions of the Software.
+//
+// THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND,
+// EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF
+// MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND
+// NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE
+// LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION
+// OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION
+// WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
+//
+
+
+using System;
+using System.Drawing;
+using System.Drawing.Drawing2D;
+
+namespace ShiftUI.Design.Behavior
+{
+ public sealed class BehaviorService : IDisposable
+ {
+ internal BehaviorService ()
+ {
+ }
+
+ public event BehaviorDragDropEventHandler BeginDrag;
+ public event BehaviorDragDropEventHandler EndDrag;
+ public event EventHandler Synchronize;
+
+ [MonoTODO]
+ public BehaviorServiceAdornerCollection Adorners {
+ get { throw new NotImplementedException (); }
+ }
+
+ [MonoTODO]
+ public Graphics AdornerWindowGraphics {
+ get { throw new NotImplementedException (); }
+ }
+
+ [MonoTODO]
+ public Behavior CurrentBehavior {
+ get { throw new NotImplementedException (); }
+ }
+
+ [MonoTODO]
+ public Point AdornerWindowPointToScreen (Point p)
+ {
+ throw new NotImplementedException ();
+ }
+
+ [MonoTODO]
+ public Point AdornerWindowToScreen ()
+ {
+ throw new NotImplementedException ();
+ }
+
+ [MonoTODO]
+ public Rectangle WidgetRectInAdornerWindow (Widget c)
+ {
+ throw new NotImplementedException ();
+ }
+
+ [MonoTODO]
+ public Point WidgetToAdornerWindow (Widget c)
+ {
+ throw new NotImplementedException ();
+ }
+
+ [MonoTODO]
+ public void Dispose ()
+ {
+ throw new NotImplementedException ();
+ }
+
+ [MonoTODO]
+ public Behavior GetNextBehavior (Behavior behavior)
+ {
+ throw new NotImplementedException ();
+ }
+
+ [MonoTODO]
+ public void Invalidate ()
+ {
+ throw new NotImplementedException ();
+ }
+
+ [MonoTODO]
+ public void Invalidate (Rectangle rect)
+ {
+ throw new NotImplementedException ();
+ }
+
+ [MonoTODO]
+ public void Invalidate (Region r)
+ {
+ throw new NotImplementedException ();
+ }
+
+ [MonoTODO]
+ public Point MapAdornerWindowPoint (IntPtr handle, Point pt)
+ {
+ throw new NotImplementedException ();
+ }
+
+ [MonoTODO]
+ public Behavior PopBehavior (Behavior behavior)
+ {
+ throw new NotImplementedException ();
+ }
+
+ [MonoTODO]
+ public void PushBehavior (Behavior behavior)
+ {
+ throw new NotImplementedException ();
+ }
+
+ [MonoTODO]
+ public void PushCaptureBehavior (Behavior behavior)
+ {
+ throw new NotImplementedException ();
+ }
+
+ [MonoTODO]
+ public Point ScreenToAdornerWindow (Point p)
+ {
+ throw new NotImplementedException ();
+ }
+
+ [MonoTODO]
+ public void SyncSelection ()
+ {
+ throw new NotImplementedException ();
+ }
+ }
+}
+
diff --git a/source/ShiftUI/Design/Behavior/BehaviorServiceAdornerCollection.cs b/source/ShiftUI/Design/Behavior/BehaviorServiceAdornerCollection.cs
new file mode 100644
index 0000000..2850cd4
--- /dev/null
+++ b/source/ShiftUI/Design/Behavior/BehaviorServiceAdornerCollection.cs
@@ -0,0 +1,128 @@
+//
+// ShiftUI.Design.Behavior.BehaviorServiceAdornerCollection
+//
+// Author:
+// Atsushi Enomoto ([email protected])
+//
+// Copyright (C) 2007 Novell, Inc.
+//
+
+//
+// Permission is hereby granted, free of charge, to any person obtaining
+// a copy of this software and associated documentation files (the
+// "Software"), to deal in the Software without restriction, including
+// without limitation the rights to use, copy, modify, merge, publish,
+// distribute, sublicense, and/or sell copies of the Software, and to
+// permit persons to whom the Software is furnished to do so, subject to
+// the following conditions:
+//
+// The above copyright notice and this permission notice shall be
+// included in all copies or substantial portions of the Software.
+//
+// THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND,
+// EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF
+// MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND
+// NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE
+// LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION
+// OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION
+// WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
+//
+
+
+using System;
+using System.Collections;
+
+namespace ShiftUI.Design.Behavior
+{
+ public sealed class BehaviorServiceAdornerCollection : CollectionBase
+ {
+ int state;
+
+ public BehaviorServiceAdornerCollection (BehaviorService behaviorService)
+ : this (behaviorService.Adorners)
+ {
+ }
+
+ public BehaviorServiceAdornerCollection (Adorner [] value)
+ {
+ if (value == null)
+ throw new ArgumentNullException ("value");
+ InnerList.AddRange (value);
+ }
+
+ public BehaviorServiceAdornerCollection (BehaviorServiceAdornerCollection value)
+ {
+ if (value == null)
+ throw new ArgumentNullException ("value");
+ InnerList.AddRange (value);
+ }
+
+ internal int State {
+ get { return state; }
+ }
+
+ public Adorner this [int index] {
+ get { return (Adorner) InnerList [index]; }
+ set {
+ if (value == null)
+ throw new ArgumentNullException ("value");
+ InnerList [index] = value;
+ }
+ }
+
+ public int Add (Adorner value)
+ {
+ state++;
+ return InnerList.Add (value);
+ }
+
+ public void AddRange (Adorner [] value)
+ {
+ state++;
+ if (value == null)
+ throw new ArgumentNullException ("value");
+ InnerList.AddRange (value);
+ }
+
+ public void AddRange (BehaviorServiceAdornerCollection value)
+ {
+ state++;
+ if (value == null)
+ throw new ArgumentNullException ("value");
+ InnerList.AddRange (value);
+ }
+
+ public bool Contains (Adorner value)
+ {
+ return InnerList.Contains (value);
+ }
+
+ public void CopyTo (Adorner [] array, int index)
+ {
+ InnerList.CopyTo (array, index);
+ }
+
+ public int IndexOf (Adorner value)
+ {
+ return InnerList.IndexOf (value);
+ }
+
+ public BehaviorServiceAdornerCollectionEnumerator GetEnumerator ()
+ {
+ return new BehaviorServiceAdornerCollectionEnumerator (this);
+ }
+
+ public void Insert (int index, Adorner value)
+ {
+ state++;
+ InnerList.Insert (index, value);
+ }
+
+ public void Remove (Adorner value)
+ {
+ state++;
+ InnerList.Remove (value);
+ }
+ }
+}
+
diff --git a/source/ShiftUI/Design/Behavior/BehaviorServiceAdornerCollectionEnumerator.cs b/source/ShiftUI/Design/Behavior/BehaviorServiceAdornerCollectionEnumerator.cs
new file mode 100644
index 0000000..a4e9138
--- /dev/null
+++ b/source/ShiftUI/Design/Behavior/BehaviorServiceAdornerCollectionEnumerator.cs
@@ -0,0 +1,90 @@
+//
+// ShiftUI.Design.Behavior.BehaviorServiceAdornerCollectionEnumerator
+//
+// Author:
+// Atsushi Enomoto ([email protected])
+//
+// Copyright (C) 2007 Novell, Inc.
+//
+
+//
+// Permission is hereby granted, free of charge, to any person obtaining
+// a copy of this software and associated documentation files (the
+// "Software"), to deal in the Software without restriction, including
+// without limitation the rights to use, copy, modify, merge, publish,
+// distribute, sublicense, and/or sell copies of the Software, and to
+// permit persons to whom the Software is furnished to do so, subject to
+// the following conditions:
+//
+// The above copyright notice and this permission notice shall be
+// included in all copies or substantial portions of the Software.
+//
+// THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND,
+// EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF
+// MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND
+// NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE
+// LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION
+// OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION
+// WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
+//
+
+
+using System;
+using System.Collections;
+
+namespace ShiftUI.Design.Behavior
+{
+ public class BehaviorServiceAdornerCollectionEnumerator : IEnumerator
+ {
+ BehaviorServiceAdornerCollection mappings;
+ int index, state;
+
+ public BehaviorServiceAdornerCollectionEnumerator (BehaviorServiceAdornerCollection mappings)
+ {
+ if (mappings == null)
+ throw new ArgumentNullException ("mappings");
+ this.mappings = mappings;
+
+ Reset ();
+ }
+
+ public Adorner Current {
+ get { return index < 0 ? null : mappings [index]; }
+ }
+
+ void CheckState ()
+ {
+ if (mappings.State != state)
+ throw new InvalidOperationException ("Collection has changed");
+ }
+
+ public bool MoveNext ()
+ {
+ CheckState ();
+ if (index++ < mappings.Count)
+ return true;
+ index--;
+ return false;
+ }
+
+ public void Reset ()
+ {
+ index = -1;
+ }
+
+ object IEnumerator.Current {
+ get { return Current; }
+ }
+
+ bool IEnumerator.MoveNext ()
+ {
+ return MoveNext ();
+ }
+
+ void IEnumerator.Reset ()
+ {
+ Reset ();
+ }
+ }
+}
+
diff --git a/source/ShiftUI/Design/Behavior/ComponentGlyph.cs b/source/ShiftUI/Design/Behavior/ComponentGlyph.cs
new file mode 100644
index 0000000..0f8c53b
--- /dev/null
+++ b/source/ShiftUI/Design/Behavior/ComponentGlyph.cs
@@ -0,0 +1,73 @@
+//
+// ShiftUI.Design.Behavior.ComponentGlyph
+//
+// Author:
+// Atsushi Enomoto ([email protected])
+//
+// Copyright (C) 2007 Novell, Inc.
+//
+
+//
+// Permission is hereby granted, free of charge, to any person obtaining
+// a copy of this software and associated documentation files (the
+// "Software"), to deal in the Software without restriction, including
+// without limitation the rights to use, copy, modify, merge, publish,
+// distribute, sublicense, and/or sell copies of the Software, and to
+// permit persons to whom the Software is furnished to do so, subject to
+// the following conditions:
+//
+// The above copyright notice and this permission notice shall be
+// included in all copies or substantial portions of the Software.
+//
+// THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND,
+// EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF
+// MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND
+// NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE
+// LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION
+// OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION
+// WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
+//
+
+
+using System;
+using System.ComponentModel;
+using System.Drawing;
+using System.Drawing.Design;
+using System.Drawing.Drawing2D;
+
+namespace ShiftUI.Design.Behavior
+{
+ public class ComponentGlyph : Glyph
+ {
+ IComponent component;
+
+ public ComponentGlyph (IComponent relatedComponent)
+ : this (relatedComponent, null)
+ {
+ }
+
+ public ComponentGlyph (IComponent relatedComponent, Behavior behavior)
+ : base (behavior)
+ {
+ this.component = relatedComponent;
+ }
+
+ [MonoTODO]
+ public IComponent RelatedComponent {
+ get { return component; }
+ }
+
+ [MonoTODO]
+ public override Cursor GetHitTest (Point p)
+ {
+ throw new NotImplementedException ();
+ }
+
+ [MonoTODO]
+ public override void Paint (PaintEventArgs pe)
+ {
+ throw new NotImplementedException ();
+ }
+ }
+}
+
diff --git a/source/ShiftUI/Design/Behavior/ControlBodyGlyph.cs b/source/ShiftUI/Design/Behavior/ControlBodyGlyph.cs
new file mode 100644
index 0000000..547eea1
--- /dev/null
+++ b/source/ShiftUI/Design/Behavior/ControlBodyGlyph.cs
@@ -0,0 +1,70 @@
+//
+// ShiftUI.Design.Behavior.WidgetBodyGlyph
+//
+// Author:
+// Atsushi Enomoto ([email protected])
+//
+// Copyright (C) 2007 Novell, Inc.
+//
+
+//
+// Permission is hereby granted, free of charge, to any person obtaining
+// a copy of this software and associated documentation files (the
+// "Software"), to deal in the Software without restriction, including
+// without limitation the rights to use, copy, modify, merge, publish,
+// distribute, sublicense, and/or sell copies of the Software, and to
+// permit persons to whom the Software is furnished to do so, subject to
+// the following conditions:
+//
+// The above copyright notice and this permission notice shall be
+// included in all copies or substantial portions of the Software.
+//
+// THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND,
+// EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF
+// MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND
+// NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE
+// LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION
+// OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION
+// WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
+//
+
+
+using System;
+using System.ComponentModel;
+using System.Drawing;
+using System.Drawing.Design;
+using System.Drawing.Drawing2D;
+
+namespace ShiftUI.Design.Behavior
+{
+ public class WidgetBodyGlyph : ComponentGlyph
+ {
+ Rectangle bounds;
+
+ [MonoTODO]
+ public WidgetBodyGlyph (Rectangle bounds, Cursor cursor, IComponent relatedComponent, Behavior behavior)
+ : base (relatedComponent, behavior)
+ {
+ this.bounds = bounds;
+ throw new NotImplementedException ();
+ }
+
+ [MonoTODO]
+ public WidgetBodyGlyph (Rectangle bounds, Cursor cursor, IComponent relatedComponent, WidgetDesigner designer)
+ : this (bounds, cursor, relatedComponent, designer.BehaviorService.CurrentBehavior)
+ {
+ }
+
+ [MonoTODO]
+ public override Rectangle Bounds {
+ get { return bounds; }
+ }
+
+ [MonoTODO]
+ public override Cursor GetHitTest (Point p)
+ {
+ throw new NotImplementedException ();
+ }
+ }
+}
+
diff --git a/source/ShiftUI/Design/Behavior/Glyph.cs b/source/ShiftUI/Design/Behavior/Glyph.cs
new file mode 100644
index 0000000..3452627
--- /dev/null
+++ b/source/ShiftUI/Design/Behavior/Glyph.cs
@@ -0,0 +1,70 @@
+//
+// ShiftUI.Design.Behavior.Glyph
+//
+// Author:
+// Atsushi Enomoto ([email protected])
+//
+// Copyright (C) 2007 Novell, Inc.
+//
+
+//
+// Permission is hereby granted, free of charge, to any person obtaining
+// a copy of this software and associated documentation files (the
+// "Software"), to deal in the Software without restriction, including
+// without limitation the rights to use, copy, modify, merge, publish,
+// distribute, sublicense, and/or sell copies of the Software, and to
+// permit persons to whom the Software is furnished to do so, subject to
+// the following conditions:
+//
+// The above copyright notice and this permission notice shall be
+// included in all copies or substantial portions of the Software.
+//
+// THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND,
+// EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF
+// MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND
+// NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE
+// LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION
+// OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION
+// WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
+//
+
+
+using System;
+using System.Drawing;
+using System.Drawing.Design;
+using System.Drawing.Drawing2D;
+
+namespace ShiftUI.Design.Behavior
+{
+ public abstract class Glyph
+ {
+ Behavior behavior;
+
+ [MonoTODO]
+ protected Glyph (Behavior behavior)
+ {
+ SetBehavior (behavior);
+ }
+
+ [MonoTODO]
+ public virtual Behavior Behavior {
+ get { return behavior; }
+ }
+
+ [MonoTODO]
+ public virtual Rectangle Bounds {
+ get { throw new NotImplementedException (); }
+ }
+
+ public abstract Cursor GetHitTest (Point p);
+
+ public abstract void Paint (PaintEventArgs pe);
+
+ [MonoTODO]
+ protected void SetBehavior (Behavior behavior)
+ {
+ throw new NotImplementedException ();
+ }
+ }
+}
+
diff --git a/source/ShiftUI/Design/Behavior/GlyphCollection.cs b/source/ShiftUI/Design/Behavior/GlyphCollection.cs
new file mode 100644
index 0000000..d19e689
--- /dev/null
+++ b/source/ShiftUI/Design/Behavior/GlyphCollection.cs
@@ -0,0 +1,111 @@
+//
+// ShiftUI.Design.Behavior.GlyphCollection
+//
+// Author:
+// Atsushi Enomoto ([email protected])
+//
+// Copyright (C) 2007 Novell, Inc.
+//
+
+//
+// Permission is hereby granted, free of charge, to any person obtaining
+// a copy of this software and associated documentation files (the
+// "Software"), to deal in the Software without restriction, including
+// without limitation the rights to use, copy, modify, merge, publish,
+// distribute, sublicense, and/or sell copies of the Software, and to
+// permit persons to whom the Software is furnished to do so, subject to
+// the following conditions:
+//
+// The above copyright notice and this permission notice shall be
+// included in all copies or substantial portions of the Software.
+//
+// THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND,
+// EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF
+// MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND
+// NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE
+// LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION
+// OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION
+// WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
+//
+
+
+using System;
+using System.Collections;
+
+namespace ShiftUI.Design.Behavior
+{
+ public class GlyphCollection : CollectionBase
+ {
+ public GlyphCollection ()
+ {
+ }
+
+ public GlyphCollection (Glyph [] value)
+ {
+ if (value == null)
+ throw new ArgumentNullException ("value");
+ InnerList.AddRange (value);
+ }
+
+ public GlyphCollection (GlyphCollection value)
+ {
+ if (value == null)
+ throw new ArgumentNullException ("value");
+ InnerList.AddRange (value);
+ }
+
+ public Glyph this [int index] {
+ get { return (Glyph) InnerList [index]; }
+ set {
+ if (value == null)
+ throw new ArgumentNullException ("value");
+ InnerList [index] = value;
+ }
+ }
+
+ public int Add (Glyph value)
+ {
+ return InnerList.Add (value);
+ }
+
+ public void AddRange (Glyph [] value)
+ {
+ if (value == null)
+ throw new ArgumentNullException ("value");
+ InnerList.AddRange (value);
+ }
+
+ public void AddRange (GlyphCollection value)
+ {
+ if (value == null)
+ throw new ArgumentNullException ("value");
+ InnerList.AddRange (value);
+ }
+
+ public bool Contains (Glyph value)
+ {
+ return InnerList.Contains (value);
+ }
+
+ public void CopyTo (Glyph [] array, int index)
+ {
+ InnerList.CopyTo (array, index);
+ }
+
+ public int IndexOf (Glyph value)
+ {
+ return InnerList.IndexOf (value);
+ }
+
+ public void Insert (int index, Glyph value)
+ {
+ InnerList.Insert (index, value);
+ }
+
+ public void Remove (Glyph value)
+ {
+ InnerList.Remove (value);
+ }
+ }
+}
+
diff --git a/source/ShiftUI/Design/Behavior/GlyphSelectionType.cs b/source/ShiftUI/Design/Behavior/GlyphSelectionType.cs
new file mode 100644
index 0000000..6220c03
--- /dev/null
+++ b/source/ShiftUI/Design/Behavior/GlyphSelectionType.cs
@@ -0,0 +1,41 @@
+//
+// ShiftUI.Design.Behavior.GlyphSelectionType
+//
+// Author:
+// Atsushi Enomoto ([email protected])
+//
+// Copyright (C) 2007 Novell, Inc.
+//
+
+//
+// Permission is hereby granted, free of charge, to any person obtaining
+// a copy of this software and associated documentation files (the
+// "Software"), to deal in the Software without restriction, including
+// without limitation the rights to use, copy, modify, merge, publish,
+// distribute, sublicense, and/or sell copies of the Software, and to
+// permit persons to whom the Software is furnished to do so, subject to
+// the following conditions:
+//
+// The above copyright notice and this permission notice shall be
+// included in all copies or substantial portions of the Software.
+//
+// THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND,
+// EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF
+// MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND
+// NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE
+// LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION
+// OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION
+// WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
+//
+
+
+namespace ShiftUI.Design.Behavior
+{
+ public enum GlyphSelectionType
+ {
+ NotSelected,
+ Selected,
+ SelectedPrimary
+ }
+}
+
diff --git a/source/ShiftUI/Design/Behavior/SnapLine.cs b/source/ShiftUI/Design/Behavior/SnapLine.cs
new file mode 100644
index 0000000..3b7da92
--- /dev/null
+++ b/source/ShiftUI/Design/Behavior/SnapLine.cs
@@ -0,0 +1,133 @@
+//
+// ShiftUI.Design.Behavior.SnapLine
+//
+// Author:
+// Atsushi Enomoto ([email protected])
+//
+// Copyright (C) 2007 Novell, Inc.
+//
+
+//
+// Permission is hereby granted, free of charge, to any person obtaining
+// a copy of this software and associated documentation files (the
+// "Software"), to deal in the Software without restriction, including
+// without limitation the rights to use, copy, modify, merge, publish,
+// distribute, sublicense, and/or sell copies of the Software, and to
+// permit persons to whom the Software is furnished to do so, subject to
+// the following conditions:
+//
+// The above copyright notice and this permission notice shall be
+// included in all copies or substantial portions of the Software.
+//
+// THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND,
+// EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF
+// MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND
+// NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE
+// LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION
+// OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION
+// WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
+//
+
+
+
+using System;
+
+namespace ShiftUI.Design.Behavior
+{
+ public sealed class SnapLine
+ {
+ [MonoTODO]
+ public static bool ShouldSnap (SnapLine line1, SnapLine line2)
+ {
+ throw new NotImplementedException ();
+ }
+
+ SnapLineType type;
+ int offset;
+ string filter;
+ SnapLinePriority priority;
+
+ [MonoTODO]
+ public SnapLine (SnapLineType type, int offset)
+ : this (type, offset, null)
+ {
+ }
+
+ [MonoTODO]
+ public SnapLine (SnapLineType type, int offset, string filter)
+ : this (type, offset, filter, default (SnapLinePriority))
+ {
+ }
+
+ [MonoTODO]
+ public SnapLine (SnapLineType type, int offset, SnapLinePriority priority)
+ : this (type, offset, null, priority)
+ {
+ }
+
+ [MonoTODO]
+ public SnapLine (SnapLineType type, int offset, string filter, SnapLinePriority priority)
+ {
+ this.type =type;
+ this.offset = offset;
+ this.filter = filter;
+ this.priority = priority;
+ }
+
+ public string Filter {
+ get { return filter; }
+ }
+
+ public bool IsHorizontal {
+ get {
+ switch (SnapLineType) {
+ case SnapLineType.Top:
+ case SnapLineType.Bottom:
+ case SnapLineType.Horizontal:
+ case SnapLineType.Baseline:
+ return true;
+ default:
+ return false;
+ }
+ }
+ }
+
+ public bool IsVertical {
+ get {
+ switch (SnapLineType) {
+ case SnapLineType.Left:
+ case SnapLineType.Right:
+ case SnapLineType.Vertical:
+ return true;
+ default:
+ return false;
+ }
+ }
+ }
+
+ public int Offset {
+ get { return offset; }
+ }
+
+ public SnapLinePriority Priority {
+ get { return priority; }
+ }
+
+ public SnapLineType SnapLineType {
+ get { return type; }
+ }
+
+ [MonoTODO]
+ public void AdjustOffset (int adjustment)
+ {
+ throw new NotImplementedException ();
+ }
+
+ [MonoTODO]
+ public override string ToString ()
+ {
+ return base.ToString ();
+ }
+ }
+}
+
diff --git a/source/ShiftUI/Design/Behavior/SnapLinePriority.cs b/source/ShiftUI/Design/Behavior/SnapLinePriority.cs
new file mode 100644
index 0000000..b0dff04
--- /dev/null
+++ b/source/ShiftUI/Design/Behavior/SnapLinePriority.cs
@@ -0,0 +1,42 @@
+//
+// ShiftUI.Design.Behavior.SnapLinePriority
+//
+// Author:
+// Atsushi Enomoto ([email protected])
+//
+// Copyright (C) 2007 Novell, Inc.
+//
+
+//
+// Permission is hereby granted, free of charge, to any person obtaining
+// a copy of this software and associated documentation files (the
+// "Software"), to deal in the Software without restriction, including
+// without limitation the rights to use, copy, modify, merge, publish,
+// distribute, sublicense, and/or sell copies of the Software, and to
+// permit persons to whom the Software is furnished to do so, subject to
+// the following conditions:
+//
+// The above copyright notice and this permission notice shall be
+// included in all copies or substantial portions of the Software.
+//
+// THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND,
+// EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF
+// MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND
+// NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE
+// LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION
+// OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION
+// WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
+//
+
+
+namespace ShiftUI.Design.Behavior
+{
+ public enum SnapLinePriority
+ {
+ Low = 1,
+ Medium,
+ High,
+ Always
+ }
+}
+
diff --git a/source/ShiftUI/Design/Behavior/SnapLineType.cs b/source/ShiftUI/Design/Behavior/SnapLineType.cs
new file mode 100644
index 0000000..a0b294b
--- /dev/null
+++ b/source/ShiftUI/Design/Behavior/SnapLineType.cs
@@ -0,0 +1,45 @@
+//
+// ShiftUI.Design.Behavior.SnapLineType
+//
+// Author:
+// Atsushi Enomoto ([email protected])
+//
+// Copyright (C) 2007 Novell, Inc.
+//
+
+//
+// Permission is hereby granted, free of charge, to any person obtaining
+// a copy of this software and associated documentation files (the
+// "Software"), to deal in the Software without restriction, including
+// without limitation the rights to use, copy, modify, merge, publish,
+// distribute, sublicense, and/or sell copies of the Software, and to
+// permit persons to whom the Software is furnished to do so, subject to
+// the following conditions:
+//
+// The above copyright notice and this permission notice shall be
+// included in all copies or substantial portions of the Software.
+//
+// THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND,
+// EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF
+// MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND
+// NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE
+// LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION
+// OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION
+// WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
+//
+
+
+namespace ShiftUI.Design.Behavior
+{
+ public enum SnapLineType
+ {
+ Top,
+ Bottom,
+ Left,
+ Right,
+ Horizontal,
+ Vertical,
+ Baseline
+ }
+}
+
diff --git a/source/ShiftUI/Design/ComponentDesigner.cs b/source/ShiftUI/Design/ComponentDesigner.cs
new file mode 100644
index 0000000..f0034b6
--- /dev/null
+++ b/source/ShiftUI/Design/ComponentDesigner.cs
@@ -0,0 +1,438 @@
+//
+// System.ComponentModel.Design.ComponentDesigner
+//
+// Authors:
+// Ivan N. Zlatev (contact i-nZ.net)
+//
+// (C) 2006-2007 Ivan N. Zlatev
+
+//
+// Permission is hereby granted, free of charge, to any person obtaining
+// a copy of this software and associated documentation files (the
+// "Software"), to deal in the Software without restriction, including
+// without limitation the rights to use, copy, modify, merge, publish,
+// distribute, sublicense, and/or sell copies of the Software, and to
+// permit persons to whom the Software is furnished to do so, subject to
+// the following conditions:
+//
+// The above copyright notice and this permission notice shall be
+// included in all copies or substantial portions of the Software.
+//
+// THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND,
+// EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF
+// MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND
+// NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE
+// LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION
+// OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION
+// WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
+//
+
+
+using System;
+using System.Collections;
+using System.ComponentModel;
+using System.ComponentModel.Design;
+
+namespace ShiftUI.Design
+{
+
+ public class ComponentDesigner : ITreeDesigner, IDesigner, IDisposable, IDesignerFilter, IComponentInitializer
+ {
+
+#region ShadowPropertyCollection
+
+ protected sealed class ShadowPropertyCollection
+ {
+
+ private Hashtable _properties = null;
+ private IComponent _component;
+
+ internal ShadowPropertyCollection (IComponent component)
+ {
+ _component = component;
+ }
+
+ // Returns Widget's property value (if available) if there is no shadowed one.
+ //
+ public object this[string propertyName]
+ {
+ get {
+ if (propertyName == null)
+ throw new System.ArgumentNullException("propertyName");
+
+ if (_properties != null && _properties.ContainsKey (propertyName))
+ return _properties[propertyName];
+
+ PropertyDescriptor property = TypeDescriptor.GetProperties (_component.GetType ())[propertyName];
+ if (property != null)
+ return property.GetValue (_component);
+ else
+ throw new System.Exception ("Propery not found!");
+ }
+ set {
+ if (_properties == null)
+ _properties = new Hashtable ();
+ _properties[propertyName] = value;
+ }
+ }
+
+ public bool Contains (string propertyName)
+ {
+ if (_properties != null)
+ return _properties.ContainsKey (propertyName);
+ else
+ return false;
+ }
+
+ } // ShadowPropertyCollection
+#endregion
+
+ public ComponentDesigner ()
+ {
+ }
+
+
+ private IComponent _component;
+ private DesignerVerbCollection _verbs;
+ private ShadowPropertyCollection _shadowPropertyCollection;
+ private DesignerActionListCollection _designerActionList;
+
+ // This property indicates any components to copy or move along with the component managed
+ // by the designer during a copy, drag, or move operation.
+ // If this collection contains references to other components in the current design mode document,
+ // those components will be copied along with the component managed by the designer during a copy operation.
+ // When the component managed by the designer is selected, this collection is filled with any nested controls.
+ // This collection can also include other components, such as the buttons of a toolbar.
+ //
+ // supposedly contains all the children of the component, thus used for ITreeDesigner.Children
+ //
+ public virtual ICollection AssociatedComponents {
+ get { return new IComponent[0]; }
+ }
+
+ public IComponent Component {
+ get { return _component; }
+ }
+
+ public virtual DesignerVerbCollection Verbs {
+ get {
+ if (_verbs == null)
+ _verbs = new DesignerVerbCollection ();
+
+ return _verbs;
+ }
+ }
+
+ protected virtual InheritanceAttribute InheritanceAttribute {
+ get {
+ IInheritanceService service = (IInheritanceService) this.GetService (typeof (IInheritanceService));
+ if (service != null)
+ return service.GetInheritanceAttribute (_component);
+ else
+ return InheritanceAttribute.Default;
+ }
+ }
+
+ protected bool Inherited {
+ get { return !this.InheritanceAttribute.Equals (InheritanceAttribute.NotInherited); }
+ }
+
+ //Gets a collection of property values that override user settings.
+ //
+ protected ShadowPropertyCollection ShadowProperties {
+ get {
+ if (_shadowPropertyCollection == null) {
+ _shadowPropertyCollection = new ShadowPropertyCollection(_component);
+ }
+ return _shadowPropertyCollection;
+ }
+ }
+
+ public virtual DesignerActionListCollection ActionLists {
+ get {
+ if (_designerActionList == null)
+ _designerActionList = new DesignerActionListCollection ();
+
+ return _designerActionList;
+ }
+ }
+
+ protected virtual IComponent ParentComponent {
+ get {
+ IDesignerHost host = GetService (typeof (IDesignerHost)) as IDesignerHost;
+ if (host != null) {
+ IComponent rootComponent = host.RootComponent;
+ if (rootComponent != _component)
+ return rootComponent;
+ }
+ return null;
+ }
+ }
+
+ public virtual void InitializeNewComponent (IDictionary defaultValues)
+ {
+ // Reset
+ //
+ OnSetComponentDefaults ();
+ }
+
+ // MSDN: The default implementation of this method does nothing.
+ //
+ public virtual void InitializeExistingComponent (IDictionary defaultValues)
+ {
+ InitializeNonDefault ();
+ }
+
+
+ public virtual void Initialize (IComponent component)
+ {
+ if (component == null)
+ throw new ArgumentNullException ("component");
+
+ _component = component;
+ }
+
+ [Obsolete ("This method has been deprecated. Use InitializeExistingComponent instead.")]
+ public virtual void InitializeNonDefault ()
+ {
+ }
+
+
+ // This method is called when a user double-clicks (the representation of) a component.
+ // Tries to bind the default event to a method or creates a new one.
+ //
+ public virtual void DoDefaultAction()
+ {
+ IDesignerHost host = (IDesignerHost) this.GetService(typeof(IDesignerHost));
+ DesignerTransaction transaction = null;
+ if (host != null)
+ transaction = host.CreateTransaction ("ComponentDesigner_AddEvent");
+
+ IEventBindingService eventBindingService = GetService (typeof(IEventBindingService)) as IEventBindingService;
+ EventDescriptor defaultEventDescriptor = null;
+
+ if (eventBindingService != null) {
+ ISelectionService selectionService = this.GetService (typeof (ISelectionService)) as ISelectionService;
+ try {
+ if (selectionService != null) {
+ ICollection selectedComponents = selectionService.GetSelectedComponents ();
+
+ foreach (IComponent component in selectedComponents) {
+ EventDescriptor eventDescriptor = TypeDescriptor.GetDefaultEvent (component);
+ if (eventDescriptor != null) {
+ PropertyDescriptor eventProperty = eventBindingService.GetEventProperty (eventDescriptor);
+ if (eventProperty != null && !eventProperty.IsReadOnly) {
+ string methodName = eventProperty.GetValue (component) as string;
+ bool newMethod = true;
+
+ if (methodName != null || methodName != String.Empty) {
+ ICollection compatibleMethods = eventBindingService.GetCompatibleMethods (eventDescriptor);
+ foreach (string signature in compatibleMethods) {
+ if (signature == methodName) {
+ newMethod = false;
+ break;
+ }
+ }
+ }
+ if (newMethod) {
+ if (methodName == null)
+ methodName = eventBindingService.CreateUniqueMethodName (component, eventDescriptor);
+
+ eventProperty.SetValue (component, methodName);
+ }
+
+ if (component == _component)
+ defaultEventDescriptor = eventDescriptor;
+ }
+ }
+ }
+
+ }
+ }
+ catch {
+ if (transaction != null) {
+ transaction.Cancel ();
+ transaction = null;
+ }
+ }
+ finally {
+ if (transaction != null)
+ transaction.Commit ();
+ }
+
+ if (defaultEventDescriptor != null)
+ eventBindingService.ShowCode (_component, defaultEventDescriptor);
+ }
+ }
+
+
+
+ [Obsolete ("This method has been deprecated. Use InitializeNewComponent instead.")]
+ // The default implementation of this method sets the default property of the component to
+ // the name of the component if the default property is a string and the property is not already set.
+ // This method can be implemented in a derived class to customize the initialization of the component
+ // that this designer is designing.
+ //
+ public virtual void OnSetComponentDefaults ()
+ {
+ if (_component != null && _component.Site != null) {
+ PropertyDescriptor property = TypeDescriptor.GetDefaultProperty (_component);
+ if (property != null && property.PropertyType.Equals (typeof (string))) {
+ string propertyValue = (string)property.GetValue (_component);
+ if (propertyValue != null && propertyValue.Length != 0)
+ property.SetValue (_component, _component.Site.Name);
+ }
+ }
+ }
+
+
+
+
+ protected InheritanceAttribute InvokeGetInheritanceAttribute (ComponentDesigner toInvoke)
+ {
+ return toInvoke.InheritanceAttribute;
+ }
+
+#region IDesignerFilter
+
+ // TypeDescriptor queries the component's site for ITypeDescriptorFilterService
+ // then invokes ITypeDescriptorFilterService.XXXX before retrieveing props/event/attributes,
+ // which then invokes the IDesignerFilter implementation of the component
+ //
+ protected virtual void PostFilterAttributes (IDictionary attributes)
+ {
+ }
+
+ protected virtual void PostFilterEvents (IDictionary events)
+ {
+ }
+
+ protected virtual void PostFilterProperties (IDictionary properties)
+ {
+ }
+
+ protected virtual void PreFilterAttributes (IDictionary attributes)
+ {
+ }
+
+ protected virtual void PreFilterEvents (IDictionary events)
+ {
+ }
+
+ protected virtual void PreFilterProperties (IDictionary properties)
+ {
+ }
+#endregion
+
+ protected void RaiseComponentChanged (MemberDescriptor member, object oldValue, object newValue)
+ {
+ IComponentChangeService service = GetService (typeof (IComponentChangeService)) as IComponentChangeService;
+ if (service != null)
+ service.OnComponentChanged (_component, member, oldValue, newValue);
+ }
+
+ protected void RaiseComponentChanging (MemberDescriptor member)
+ {
+ IComponentChangeService service = GetService (typeof (IComponentChangeService)) as IComponentChangeService;
+ if (service != null)
+ service.OnComponentChanging (_component, member);
+ }
+
+#region Implementation of IDesignerFilter
+
+ void IDesignerFilter.PostFilterAttributes (IDictionary attributes)
+ {
+ PostFilterAttributes (attributes);
+ }
+
+ void IDesignerFilter.PostFilterEvents (IDictionary events)
+ {
+ PostFilterEvents (events);
+ }
+
+ void IDesignerFilter.PostFilterProperties (IDictionary properties)
+ {
+ PostFilterProperties (properties);
+ }
+
+ void IDesignerFilter.PreFilterAttributes (IDictionary attributes)
+ {
+ PreFilterAttributes (attributes);
+ }
+
+ void IDesignerFilter.PreFilterEvents (IDictionary events)
+ {
+ PreFilterEvents (events);
+ }
+
+ void IDesignerFilter.PreFilterProperties (IDictionary properties)
+ {
+ PreFilterProperties (properties);
+ }
+
+#endregion
+
+
+#region ITreeDesigner
+ // Returns a collection of the designers of the associated components
+ //
+ ICollection ITreeDesigner.Children {
+ get {
+ ICollection components = this.AssociatedComponents;
+ IDesignerHost host = GetService (typeof (IDesignerHost)) as IDesignerHost;
+
+ if (host != null) {
+ ArrayList designers = new ArrayList ();
+ foreach (IComponent component in components) {
+ IDesigner designer = host.GetDesigner (component);
+ if (designer != null)
+ designers.Add (designer);
+ }
+ IDesigner[] result = new IDesigner[designers.Count];
+ designers.CopyTo (result);
+ return result;
+ }
+ return new IDesigner[0];
+ }
+ }
+
+ IDesigner ITreeDesigner.Parent {
+ get {
+ IDesignerHost host = GetService (typeof (IDesignerHost)) as IDesignerHost;
+ if (host != null && this.ParentComponent != null)
+ return host.GetDesigner (this.ParentComponent);
+
+ return null;
+ }
+ }
+#endregion
+
+ // Helper method - not an ISerivceProvider
+ //
+ protected virtual object GetService (Type service)
+ {
+ if (_component != null && _component.Site != null)
+ return _component.Site.GetService (service);
+
+ return null;
+ }
+
+ public void Dispose ()
+ {
+ this.Dispose (true);
+ GC.SuppressFinalize (this);
+ }
+
+
+ protected virtual void Dispose (bool disposing)
+ {
+ if (disposing)
+ _component = null;
+ }
+
+ ~ComponentDesigner ()
+ {
+ this.Dispose (false);
+ }
+ }
+}
diff --git a/source/ShiftUI/Design/ComponentEditorForm.cs b/source/ShiftUI/Design/ComponentEditorForm.cs
new file mode 100644
index 0000000..0cd0584
--- /dev/null
+++ b/source/ShiftUI/Design/ComponentEditorForm.cs
@@ -0,0 +1,96 @@
+// Permission is hereby granted, free of charge, to any person obtaining
+// a copy of this software and associated documentation files (the
+// "Software"), to deal in the Software without restriction, including
+// without limitation the rights to use, copy, modify, merge, publish,
+// distribute, sublicense, and/or sell copies of the Software, and to
+// permit persons to whom the Software is furnished to do so, subject to
+// the following conditions:
+//
+// The above copyright notice and this permission notice shall be
+// included in all copies or substantial portions of the Software.
+//
+// THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND,
+// EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF
+// MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND
+// NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE
+// LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION
+// OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION
+// WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
+//
+// Copyright (c) 2004 Novell, Inc.
+//
+// Authors:
+// Dennis Hayes ([email protected])
+
+using System;
+using System.ComponentModel;
+using ShiftUI;
+using System.Runtime.InteropServices;
+
+namespace ShiftUI.Design {
+ [ToolboxItem (false)]
+ [ClassInterfaceAttribute (ClassInterfaceType.AutoDispatch)]
+ [ComVisible (true)]
+ public class ComponentEditorForm : Form {
+
+ [MonoTODO]
+ public ComponentEditorForm(object component, Type[] pageTypes){
+ }
+
+ #region Public Properties
+ [Browsable (false)]
+ //[EditorBrowsable (EditorBrowsableState.Never)]
+ //[DesignerSerializationVisibility (DesignerSerializationVisibility.Hidden)]
+ new public virtual bool AutoSize {
+ get { return base.AutoSize; }
+ set { base.AutoSize = value; }
+ }
+ #endregion
+
+ [MonoTODO]
+ protected override void OnActivated(EventArgs e){
+ }
+
+ [MonoTODO]
+ protected virtual void OnSelChangeSelector(object source, TreeViewEventArgs e){
+ }
+
+ [MonoTODO]
+ public override bool PreProcessMessage(ref Message msg){
+ throw new NotImplementedException ();
+ }
+
+ [MonoTODO]
+ public virtual DialogResult ShowForm(){
+ throw new NotImplementedException ();
+ }
+
+ [MonoTODO]
+ public virtual DialogResult ShowForm(int page){
+ throw new NotImplementedException ();
+ }
+
+ [MonoTODO]
+ public virtual DialogResult ShowForm(IWin32Window owner){
+ throw new NotImplementedException ();
+ }
+
+ [MonoTODO]
+ public virtual DialogResult ShowForm(IWin32Window owner, int page){
+ throw new NotImplementedException ();
+ }
+ [MonoTODO]
+ // can't override the function in Widget. bug in compiler. Fixed?
+ protected override void OnHelpRequested(HelpEventArgs e){
+ }
+
+ #region Public Events
+ [Browsable (false)]
+ //[EditorBrowsable (EditorBrowsableState.Never)]
+ public new event EventHandler AutoSizeChanged {
+ add { base.AutoSizeChanged += value; }
+ remove { base.AutoSizeChanged -= value; }
+ }
+ #endregion
+ }
+}
diff --git a/source/ShiftUI/Design/ComponentEditorPage.cs b/source/ShiftUI/Design/ComponentEditorPage.cs
new file mode 100644
index 0000000..9b93b9a
--- /dev/null
+++ b/source/ShiftUI/Design/ComponentEditorPage.cs
@@ -0,0 +1,210 @@
+// Permission is hereby granted, free of charge, to any person obtaining
+// a copy of this software and associated documentation files (the
+// "Software"), to deal in the Software without restriction, including
+// without limitation the rights to use, copy, modify, merge, publish,
+// distribute, sublicense, and/or sell copies of the Software, and to
+// permit persons to whom the Software is furnished to do so, subject to
+// the following conditions:
+//
+// The above copyright notice and this permission notice shall be
+// included in all copies or substantial portions of the Software.
+//
+// THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND,
+// EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF
+// MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND
+// NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE
+// LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION
+// OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION
+// WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
+//
+// Copyright (c) 2004 Novell, Inc.
+//
+// Authors:
+// Andreas Nahr ([email protected])
+//
+
+using System.ComponentModel;
+using System.Drawing;
+using System.Runtime.InteropServices;
+using System;
+
+namespace ShiftUI.Design
+{
+ [ClassInterfaceAttribute (ClassInterfaceType.AutoDispatch)]
+ [ComVisible (true)]
+ public abstract class ComponentEditorPage : Panel
+ {
+ private bool commitOnDeactivate = false;
+ private IComponent component;
+ private bool firstActivate = true;
+ private Icon icon;
+ private int loading = 0;
+ private bool loadRequired = false;
+ private IComponentEditorPageSite pageSite;
+
+ public ComponentEditorPage ()
+ {
+ }
+
+ [Browsable (false)]
+ //[EditorBrowsable (EditorBrowsableState.Never)]
+ //[DesignerSerializationVisibility (DesignerSerializationVisibility.Hidden)]
+ new public virtual bool AutoSize {
+ get { return base.AutoSize; }
+ set { base.AutoSize = value; }
+ }
+
+ public bool CommitOnDeactivate
+ {
+ get { return commitOnDeactivate; }
+ set { commitOnDeactivate = value; }
+ }
+
+ protected IComponent Component {
+ get { return component; }
+ set { component = value; }
+ }
+
+ [MonoTODO ("Find out what this does.")]
+ protected override CreateParams CreateParams {
+ get {
+ throw new NotImplementedException ();
+ }
+ }
+
+ protected bool FirstActivate {
+ get { return firstActivate; }
+ set { firstActivate = value; }
+ }
+
+ public Icon Icon {
+ get { return icon; }
+ set { icon = value; }
+ }
+
+ protected int Loading {
+ get { return loading; }
+ set { loading = value; }
+ }
+
+ protected bool LoadRequired {
+ get { return loadRequired; }
+ set { loadRequired = value; }
+ }
+
+ protected IComponentEditorPageSite PageSite {
+ get { return pageSite; }
+ set { pageSite = value; }
+ }
+
+ public virtual string Title {
+ get { return base.Text; }
+ }
+
+ public virtual void Activate ()
+ {
+ Visible = true;
+ firstActivate = false;
+ if (loadRequired) {
+ EnterLoadingMode ();
+ LoadComponent ();
+ ExitLoadingMode ();
+ }
+ }
+
+ public virtual void ApplyChanges ()
+ {
+ SaveComponent ();
+ }
+
+ public virtual void Deactivate ()
+ {
+ Visible = false;
+ }
+
+ protected void EnterLoadingMode ()
+ {
+ loading++;
+ }
+
+ protected void ExitLoadingMode ()
+ {
+ loading--;
+ }
+
+ public virtual Widget GetWidget ()
+ {
+ return this;
+ }
+
+ protected IComponent GetSelectedComponent ()
+ {
+ return component;
+ }
+
+ protected bool IsFirstActivate ()
+ {
+ return firstActivate;
+ }
+
+ protected bool IsLoading ()
+ {
+ return (loading != 0);
+ }
+
+ public virtual bool IsPageMessage (ref Message msg)
+ {
+ return PreProcessMessage (ref msg);
+ }
+
+ protected abstract void LoadComponent ();
+
+ [MonoTODO ("Find out what this does.")]
+ public virtual void OnApplyComplete ()
+ {
+ }
+
+ protected virtual void ReloadComponent ()
+ {
+ loadRequired = true;
+ }
+
+ protected abstract void SaveComponent ();
+
+ public virtual void SetComponent (IComponent component)
+ {
+ this.component = component;
+ ReloadComponent ();
+ }
+
+ [MonoTODO ("Find out what this does.")]
+ protected virtual void SetDirty ()
+ {
+ }
+
+ public virtual void SetSite (IComponentEditorPageSite site)
+ {
+ pageSite = site;
+ pageSite.GetWidget ().Widgets.Add (this);
+
+ }
+
+ public virtual void ShowHelp ()
+ {
+ }
+
+ public virtual bool SupportsHelp ()
+ {
+ return false;
+ }
+
+ #region Public Events
+ [Browsable (false)]
+ //[EditorBrowsable (EditorBrowsableState.Never)]
+ public new event EventHandler AutoSizeChanged {
+ add { base.AutoSizeChanged += value; }
+ remove { base.AutoSizeChanged -= value; }
+ }
+ #endregion
+ }
+}
diff --git a/source/ShiftUI/Design/ComponentTray.cs b/source/ShiftUI/Design/ComponentTray.cs
new file mode 100644
index 0000000..d4c0f93
--- /dev/null
+++ b/source/ShiftUI/Design/ComponentTray.cs
@@ -0,0 +1,247 @@
+//
+// ShiftUI.Design.ComponentTray
+//
+// Authors:
+// Ivan N. Zlatev (contact i-nZ.net)
+//
+// (C) 2006-2007 Ivan N. Zlatev
+
+//
+// Permission is hereby granted, free of charge, to any person obtaining
+// a copy of this software and associated documentation files (the
+// "Software"), to deal in the Software without restriction, including
+// without limitation the rights to use, copy, modify, merge, publish,
+// distribute, sublicense, and/or sell copies of the Software, and to
+// permit persons to whom the Software is furnished to do so, subject to
+// the following conditions:
+//
+// The above copyright notice and this permission notice shall be
+// included in all copies or substantial portions of the Software.
+//
+// THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND,
+// EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF
+// MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND
+// NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE
+// LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION
+// OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION
+// WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
+//
+
+// STUBS ONLY!!!
+//
+//
+
+using System;
+using System.ComponentModel;
+using System.ComponentModel.Design;
+using ShiftUI;
+using System.Drawing;
+using System.Drawing.Design;
+using System.Collections;
+
+namespace ShiftUI.Design
+{
+ [DesignTimeVisible (false)]
+ [ToolboxItem (false)]
+ [ProvideProperty ("Location", typeof (IComponent))]
+ public class ComponentTray : ScrollableWidget, IExtenderProvider
+ {
+
+ private IServiceProvider _serviceProvider;
+ private IDesigner _mainDesigner = null;
+ private bool _showLargeIcons = false;
+ private bool _autoArrange = false;
+
+ public ComponentTray (IDesigner mainDesigner, IServiceProvider serviceProvider)
+ {
+ if (mainDesigner == null) {
+ throw new ArgumentNullException ("mainDesigner");
+ }
+ if (serviceProvider == null) {
+ throw new ArgumentNullException ("serviceProvider");
+ }
+
+ _mainDesigner = mainDesigner;
+ _serviceProvider = serviceProvider;
+ }
+
+ public bool AutoArrange {
+ get { return _autoArrange; }
+ set { _autoArrange = value; }
+ }
+
+ [MonoTODO]
+ public int ComponentCount {
+ get { return 0; }
+ }
+
+ public bool ShowLargeIcons {
+ get { return _showLargeIcons; }
+ set { _showLargeIcons = value; }
+ }
+
+
+ [MonoTODO]
+ public virtual void AddComponent (IComponent component)
+ {
+ }
+
+ protected virtual bool CanCreateComponentFromTool (ToolboxItem tool)
+ {
+ return true;
+ }
+
+ protected virtual bool CanDisplayComponent (IComponent component)
+ {
+ return false;
+ }
+
+ [MonoTODO]
+ public void CreateComponentFromTool (ToolboxItem tool)
+ {
+ }
+
+ [MonoTODO]
+ protected void DisplayError (Exception e)
+ {
+ }
+
+ protected override void Dispose (bool disposing)
+ {
+ }
+
+ [Browsable (false)]
+ [Category ("Layout")]
+ [DesignerSerializationVisibility (DesignerSerializationVisibility.Hidden)]
+ [DesignOnly (true)]
+ [Localizable (false)]
+ [MonoTODO]
+ public Point GetLocation (IComponent receiver)
+ {
+ return new Point (0,0);
+ }
+
+ [MonoTODO]
+ public void SetLocation (IComponent receiver, Point location)
+ {
+ }
+
+ [MonoTODO]
+ public IComponent GetNextComponent (IComponent component, bool forward)
+ {
+ throw new NotImplementedException ();
+ }
+
+ [Browsable (false)]
+ [Category ("Layout")]
+ [DesignOnly (true)]
+ [Localizable (false)]
+ [MonoTODO]
+ public Point GetTrayLocation (IComponent receiver)
+ {
+ throw new NotImplementedException ();
+ }
+
+ [MonoTODO]
+ public bool IsTrayComponent (IComponent comp)
+ {
+ throw new NotImplementedException ();
+ }
+
+ [MonoTODO]
+ public void SetTrayLocation (IComponent receiver, Point location)
+ {
+ throw new NotImplementedException ();
+ }
+
+ [MonoTODO]
+ protected override void OnMouseDoubleClick (MouseEventArgs e)
+ {
+ }
+
+ [MonoTODO]
+ protected override void OnDragDrop (DragEventArgs de)
+ {
+ }
+
+ [MonoTODO]
+ protected override void OnDragEnter (DragEventArgs de)
+ {
+ }
+
+ [MonoTODO]
+ protected override void OnDragLeave (EventArgs e)
+ {
+ }
+
+ [MonoTODO]
+ protected override void OnDragOver (DragEventArgs de)
+ {
+ }
+
+ [MonoTODO]
+ protected override void OnGiveFeedback (GiveFeedbackEventArgs gfevent)
+ {
+ }
+
+ [MonoTODO]
+ protected override void OnLayout (LayoutEventArgs levent)
+ {
+ }
+
+ [MonoTODO]
+ protected virtual void OnLostCapture ()
+ {
+ }
+
+ [MonoTODO]
+ protected override void OnMouseDown (MouseEventArgs e)
+ {
+ }
+
+ [MonoTODO]
+ protected override void OnMouseMove (MouseEventArgs e)
+ {
+ }
+
+ [MonoTODO]
+ protected override void OnMouseUp (MouseEventArgs e)
+ {
+ }
+
+ [MonoTODO]
+ protected override void OnPaint (PaintEventArgs pe)
+ {
+ }
+
+ [MonoTODO]
+ protected virtual void OnSetCursor ()
+ {
+ }
+
+ [MonoTODO]
+ public virtual void RemoveComponent (IComponent component)
+ {
+ }
+
+ [MonoTODO]
+ protected override void WndProc (ref Message m)
+ {
+ base.WndProc (ref m);
+ }
+
+ bool IExtenderProvider.CanExtend (object component)
+ {
+ return false;
+ }
+
+ protected override object GetService (Type service)
+ {
+ if (_serviceProvider != null) {
+ return _serviceProvider.GetService (service);
+ }
+ return null;
+ }
+
+ }
+}
diff --git a/source/ShiftUI/Design/Consts.cs b/source/ShiftUI/Design/Consts.cs
new file mode 100644
index 0000000..ef7fc20
--- /dev/null
+++ b/source/ShiftUI/Design/Consts.cs
@@ -0,0 +1,100 @@
+//
+// Consts.cs
+//
+// Author:
+// Marek Sieradzki ([email protected])
+//
+// (C) 2006 Marek Sieradzki
+//
+// Permission is hereby granted, free of charge, to any person obtaining
+// a copy of this software and associated documentation files (the
+// "Software"), to deal in the Software without restriction, including
+// without limitation the rights to use, copy, modify, merge, publish,
+// distribute, sublicense, and/or sell copies of the Software, and to
+// permit persons to whom the Software is furnished to do so, subject to
+// the following conditions:
+//
+// The above copyright notice and this permission notice shall be
+// included in all copies or substantial portions of the Software.
+//
+// THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND,
+// EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF
+// MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND
+// NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE
+// LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION
+// OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION
+// WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
+#define NET_4_5
+using System;
+using System.IO;
+using Microsoft.Build.Utilities;
+
+public static class Consts {
+
+ public static bool RunningOnMono ()
+ {
+ return Type.GetType ("Mono.Runtime") != null;
+ }
+
+ public static string BinPath {
+ get {
+ if (RunningOnMono ()) {
+#if XBUILD_14
+ string profile = "xbuild_14";
+#elif XBUILD_12
+ string profile = "xbuild_12";
+#elif NET_4_5
+ string profile = "net_4_x";
+#else
+ #error "Unknown profile"
+#endif
+ var corlib = typeof (object).Assembly.Location;
+ var lib = Path.GetDirectoryName (Path.GetDirectoryName (corlib));
+ return Path.Combine (lib, profile);
+ } else {
+#if XBUILD_14
+ return ToolLocationHelper.GetPathToBuildTools ("14.0");
+#elif XBUILD_12
+ return ToolLocationHelper.GetPathToBuildTools ("12.0");
+#elif NET_4_5
+ return ToolLocationHelper.GetPathToDotNetFramework (TargetDotNetFrameworkVersion.Version45);
+#elif NET_4_0
+ return ToolLocationHelper.GetPathToDotNetFramework (TargetDotNetFrameworkVersion.Version40);
+#else
+ return ToolLocationHelper.GetPathToDotNetFramework (TargetDotNetFrameworkVersion.Version20);
+#endif
+ }
+ }
+ }
+
+ public static string ToolsVersionString {
+ get {
+#if XBUILD_14
+ return " ToolsVersion='14.0'";
+#elif XBUILD_12
+ return " ToolsVersion='12.0'";
+#elif NET_4_0
+ return " ToolsVersion='4.0'";
+#else
+ return String.Empty;
+#endif
+ }
+ }
+
+ public static string GetTasksAsmPath ()
+ {
+#if XBUILD_14
+ return Path.Combine (BinPath, "Microsoft.Build.Tasks.Core.dll");
+#elif XBUILD_12
+ return Path.Combine (BinPath, "Microsoft.Build.Tasks.v12.0.dll");
+#elif NET_4_0
+ return Path.Combine (BinPath, "Microsoft.Build.Tasks.v4.0.dll");
+#else
+ return Path.Combine (BinPath, "Microsoft.Build.Tasks.dll");
+#endif
+ }
+
+ public const string AssemblySystem_Drawing = "System.Drawing";
+ public const string AssemblySystem_Design = "System.Design";
+ public const string AssemblySystem_Windows_Forms = "ShiftUI";
+}
diff --git a/source/ShiftUI/Design/ControlDataObject.cs b/source/ShiftUI/Design/ControlDataObject.cs
new file mode 100644
index 0000000..932a4de
--- /dev/null
+++ b/source/ShiftUI/Design/ControlDataObject.cs
@@ -0,0 +1,120 @@
+using System;
+using ShiftUI;
+
+namespace ShiftUI.Design
+{
+ // A IDataObject that supports Widget and Widget[] format
+ //
+ internal class WidgetDataObject : IDataObject
+ {
+ private object _data = null;
+ private string _format = null;
+
+ public WidgetDataObject ()
+ {
+ _data = null;
+ _format = null;
+ }
+
+ public WidgetDataObject (Widget control)
+ {
+ SetData (control);
+ }
+
+ public WidgetDataObject (Widget[] controls)
+ {
+ SetData (controls);
+ }
+
+ public object GetData (Type format)
+ {
+ return this.GetData (format.ToString ());
+ }
+
+ public object GetData (string format)
+ {
+ return this.GetData (format, true);
+ }
+
+ public object GetData (string format, bool autoConvert)
+ {
+ if (format == _format) {
+ return _data;
+ }
+ return null;
+ }
+
+ public bool GetDataPresent (Type format)
+ {
+ return this.GetDataPresent (format.ToString());
+ }
+
+ public bool GetDataPresent (string format)
+ {
+ return this.GetDataPresent (format, true);
+ }
+
+ public bool GetDataPresent (string format, bool autoConvert)
+ {
+ if (format == _format) {
+ return true;
+ }
+ return false;
+ }
+
+ public string[] GetFormats ()
+ {
+ return this.GetFormats (true);
+ }
+
+ public string[] GetFormats (bool autoConvert)
+ {
+ string[] formats = new string[2];
+ formats[0] = typeof (Widget).ToString ();
+ formats[1] = typeof (Widget[]).ToString ();
+ return formats;
+ }
+
+ public void SetData (object data)
+ {
+ if (data is Widget)
+ this.SetData (typeof (Widget), data);
+ else if (data is Widget[])
+ this.SetData (typeof (Widget[]), data);
+ }
+
+ public void SetData (Type format, object data)
+ {
+ this.SetData (format.ToString (), data);
+ }
+
+ public void SetData (string format, object data)
+ {
+ this.SetData (format, true, data);
+ }
+
+ public void SetData (string format, bool autoConvert, object data)
+ {
+ if (ValidateFormat (format)) {
+ _data = data;
+ _format = format;
+ }
+ }
+
+ private bool ValidateFormat (string format)
+ {
+ bool valid = false;
+
+ string[] formats = GetFormats ();
+ foreach (string f in formats) {
+ if (f == format) {
+ valid = true;
+ break;
+ }
+ }
+
+ return valid;
+ }
+ }
+}
+
diff --git a/source/ShiftUI/Design/ControlDesigner.cs b/source/ShiftUI/Design/ControlDesigner.cs
new file mode 100644
index 0000000..e241f08
--- /dev/null
+++ b/source/ShiftUI/Design/ControlDesigner.cs
@@ -0,0 +1,974 @@
+//
+// ShiftUI.Design.WidgetDesigner
+//
+// Authors:
+// Ivan N. Zlatev (contact i-nZ.net)
+//
+// (C) 2006-2007 Ivan N. Zlatev
+
+//
+// Permission is hereby granted, free of charge, to any person obtaining
+// a copy of this software and associated documentation files (the
+// "Software"), to deal in the Software without restriction, including
+// without limitation the rights to use, copy, modify, merge, publish,
+// distribute, sublicense, and/or sell copies of the Software, and to
+// permit persons to whom the Software is furnished to do so, subject to
+// the following conditions:
+//
+// The above copyright notice and this permission notice shall be
+// included in all copies or substantial portions of the Software.
+//
+// THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND,
+// EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF
+// MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND
+// NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE
+// LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION
+// OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION
+// WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
+//
+
+
+using System;
+using System.ComponentModel;
+using System.ComponentModel.Design;
+using System.Runtime.InteropServices;
+using ShiftUI;
+using System.Drawing;
+using System.Drawing.Design;
+using System.Collections;
+using ShiftUI.Design.Behavior;
+
+namespace ShiftUI.Design
+{
+ public class WidgetDesigner : ComponentDesigner, IMessageReceiver
+ {
+
+
+ private WndProcRouter _messageRouter;
+ private bool _locked = false;
+ private bool _mouseDown = false;
+ private bool _mouseMoveAfterMouseDown = false;
+ private bool _mouseDownFirstMove = false;
+ private bool _firstMouseMoveInClient = true;
+
+ public WidgetDesigner ()
+ {
+ }
+
+#region Initialization
+ public override void Initialize (IComponent component)
+ {
+ base.Initialize (component);
+
+ if (!(component is Widget))
+ throw new ArgumentException ("Component is not a Widget.");
+
+ Widget.Text = component.Site.Name;
+ _messageRouter = new WndProcRouter ((Widget) component, (IMessageReceiver) this);
+ Widget.WindowTarget = _messageRouter;
+
+ // DT properties
+ //
+ this.Visible = true;
+ this.Enabled = true;
+ this.Locked = false;
+ this.AllowDrop = false;
+ //
+ // The control properties
+ //
+ Widget.Enabled = true;
+ Widget.Visible = true;
+ Widget.AllowDrop = false;
+
+ this.Widget.DragDrop += new DragEventHandler (OnDragDrop);
+ this.Widget.DragEnter += new DragEventHandler (OnDragEnter);
+ this.Widget.DragLeave += new EventHandler (OnDragLeave);
+ this.Widget.DragOver += new DragEventHandler (OnDragOver);
+
+ // XXX: The control already has a handle?
+ //
+ if (Widget.IsHandleCreated)
+ OnCreateHandle ();
+
+ }
+
+ // The default implementation of this method sets the component's Text property to
+ // its name (Component.Site.Name), if the property field is of type string.
+ //
+ public override void OnSetComponentDefaults ()
+ {
+ if (this.Component != null && this.Component.Site != null) {
+ PropertyDescriptor propertyDescriptor = TypeDescriptor.GetProperties (this.Component)["Text"];
+ if (propertyDescriptor != null && !propertyDescriptor.IsReadOnly &&
+ propertyDescriptor.PropertyType == typeof (string)) {
+ propertyDescriptor.SetValue (Component, Component.Site.Name);
+ }
+ }
+ }
+#endregion
+
+
+#region Properties and Fields - AccessabilityObject Left
+ protected static readonly Point InvalidPoint = new Point (int.MinValue, int.MinValue);
+
+ protected internal BehaviorService BehaviorService {
+ get { throw new NotImplementedException (); }
+ }
+
+ public virtual Widget Widget {
+ get { return (Widget) base.Component; }
+ }
+
+ protected virtual bool EnableDragRect {
+ get { return true; }
+ }
+
+ public virtual SelectionRules SelectionRules {
+ get {
+ if (this.Widget == null)
+ return SelectionRules.None;
+
+ // all controls on the surface are visible
+ //
+ SelectionRules selectionRules = SelectionRules.Visible;
+
+ if ((bool)GetValue (this.Component, "Locked") == true) {
+ selectionRules |= SelectionRules.Locked;
+ }
+ else {
+ DockStyle dockStyle = (DockStyle) this.GetValue (base.Component, "Dock", typeof (DockStyle));
+
+ switch (dockStyle) {
+ case DockStyle.Top:
+ selectionRules |= SelectionRules.BottomSizeable;
+ break;
+ case DockStyle.Left:
+ selectionRules |= SelectionRules.RightSizeable;
+ break;
+ case DockStyle.Right:
+ selectionRules |= SelectionRules.LeftSizeable;
+ break;
+ case DockStyle.Bottom:
+ selectionRules |= SelectionRules.TopSizeable;
+ break;
+ case DockStyle.Fill:
+ break;
+ default:
+ selectionRules |= SelectionRules.Moveable;
+ selectionRules |= SelectionRules.AllSizeable;
+ break;
+ }
+ }
+
+ return selectionRules;
+ }
+ }
+
+ public override ICollection AssociatedComponents {
+ get {
+ ArrayList components = new ArrayList ();
+ foreach (Widget c in this.Widget.Widgets)
+ if (c.Site != null)
+ components.Add (c);
+ return components;
+ }
+ }
+
+ protected override IComponent ParentComponent {
+ get { return this.GetValue (this.Widget, "Parent") as Widget;}
+ }
+ // TODO: implement WidgetDesigner.WidgetAccessabilityObject
+ //
+ public virtual AccessibleObject AccessibilityObject {
+ get {
+ if (accessibilityObj == null)
+ accessibilityObj = new AccessibleObject ();
+
+ return accessibilityObj;
+ }
+ }
+ protected AccessibleObject accessibilityObj;
+
+#endregion
+
+
+#region WndProc
+
+ protected void DefWndProc (ref Message m)
+ {
+ _messageRouter.ToWidget (ref m);
+ }
+
+ protected void BaseWndProc (ref Message m)
+ {
+ _messageRouter.ToSystem (ref m);
+ }
+
+ void IMessageReceiver.WndProc (ref Message m)
+ {
+ this.WndProc (ref m);
+ }
+
+ // Keep in mind that messages are recieved for the child controls if routed
+ //
+ protected virtual void WndProc (ref Message m)
+ {
+ // Filter out kb input
+ //
+ if ((Native.Msg) m.Msg >= Native.Msg.WM_KEYFIRST && (Native.Msg) m.Msg <= Native.Msg.WM_KEYLAST)
+ return;
+
+ // Mouse messages should be routed the control, if GetHitTest (virtual) returns true.
+ //
+ if (IsMouseMessage ((Native.Msg) m.Msg) &&
+ this.GetHitTest (new Point (Native.LoWord((int) m.LParam), Native.HiWord (((int) m.LParam))))) {
+
+ this.DefWndProc (ref m);
+ return;
+ }
+
+ switch ((Native.Msg) m.Msg) {
+ case Native.Msg.WM_CREATE:
+ this.DefWndProc (ref m);
+ if (m.HWnd == this.Widget.Handle)
+ OnCreateHandle ();
+ break;
+
+ case Native.Msg.WM_CONTEXTMENU:
+ break;
+
+ case Native.Msg.WM_SETCURSOR:
+ if (this.GetHitTest (new Point (Native.LoWord ((int) m.LParam), Native.HiWord ((int) m.LParam))))
+ this.DefWndProc (ref m);
+ else
+ OnSetCursor ();
+ break;
+
+ case Native.Msg.WM_SETFOCUS:
+ this.DefWndProc (ref m);
+ break;
+
+ case Native.Msg.WM_PAINT:
+ // Wait for control's WM_PAINT to complete first.
+ //
+ this.DefWndProc (ref m);
+
+ Graphics gfx = Graphics.FromHwnd (m.HWnd);
+ PaintEventArgs args = new PaintEventArgs (gfx, this.Widget.Bounds);
+ OnPaintAdornments (args);
+ gfx.Dispose ();
+ args.Dispose ();
+ break;
+
+ case Native.Msg.WM_NCRBUTTONDOWN:
+ case Native.Msg.WM_NCLBUTTONDOWN:
+ case Native.Msg.WM_NCMBUTTONDOWN:
+ case Native.Msg.WM_NCLBUTTONDBLCLK:
+ case Native.Msg.WM_NCRBUTTONDBLCLK:
+ break;
+
+ case Native.Msg.WM_LBUTTONDBLCLK:
+ case Native.Msg.WM_RBUTTONDBLCLK:
+ case Native.Msg.WM_MBUTTONDBLCLK:
+ if ((Native.Msg)m.Msg == Native.Msg.WM_LBUTTONDBLCLK)
+ _mouseButtonDown = MouseButtons.Left;
+ else if ((Native.Msg)m.Msg == Native.Msg.WM_RBUTTONDBLCLK)
+ _mouseButtonDown = MouseButtons.Right;
+ else if ((Native.Msg)m.Msg == Native.Msg.WM_MBUTTONDBLCLK)
+ _mouseButtonDown = MouseButtons.Middle;
+ OnMouseDoubleClick ();
+ this.BaseWndProc (ref m);
+ break;
+
+ case Native.Msg.WM_MOUSEHOVER:
+ OnMouseHover ();
+ break;
+
+ case Native.Msg.WM_LBUTTONDOWN:
+ case Native.Msg.WM_RBUTTONDOWN:
+ case Native.Msg.WM_MBUTTONDOWN:
+ _mouseMoveAfterMouseDown = true;
+ if ((Native.Msg)m.Msg == Native.Msg.WM_LBUTTONDOWN)
+ _mouseButtonDown = MouseButtons.Left;
+ else if ((Native.Msg)m.Msg == Native.Msg.WM_RBUTTONDOWN)
+ _mouseButtonDown = MouseButtons.Right;
+ else if ((Native.Msg)m.Msg == Native.Msg.WM_MBUTTONDOWN)
+ _mouseButtonDown = MouseButtons.Middle;
+
+ if (_firstMouseMoveInClient) {
+ OnMouseEnter ();
+ _firstMouseMoveInClient = false;
+ }
+ this.OnMouseDown (Native.LoWord ((int)m.LParam), Native.HiWord ((int)m.LParam));
+ this.BaseWndProc (ref m);
+ break;
+
+ case Native.Msg.WM_MOUSELEAVE:
+ _firstMouseMoveInClient = false;
+ OnMouseLeave ();
+ this.BaseWndProc (ref m);
+ break;
+
+ // The WM_CANCELMODE message is sent to cancel certain modes, such as mouse capture.
+ // For example, the system sends this message to the active window when a dialog box
+ // or message box is displayed. Certain functions also send this message explicitly to
+ // the specified window regardless of whether it is the active window. For example,
+ // the EnableWindow function sends this message when disabling the specified window.
+ //
+ case Native.Msg.WM_CANCELMODE:
+ OnMouseDragEnd (true);
+ this.DefWndProc (ref m);
+ break;
+
+ case Native.Msg.WM_LBUTTONUP:
+ case Native.Msg.WM_RBUTTONUP:
+ case Native.Msg.WM_NCLBUTTONUP:
+ case Native.Msg.WM_NCRBUTTONUP:
+ case Native.Msg.WM_MBUTTONUP:
+ case Native.Msg.WM_NCMBUTTONUP:
+ _mouseMoveAfterMouseDown = false; // just in case
+ this.OnMouseUp ();
+ this.BaseWndProc (ref m);
+ break;
+
+ // // MWF Specific msg! - must reach control
+ // //
+ // case Native.Msg.WM_MOUSE_ENTER:
+ // _firstMouseMoveInClient = false; // just so that nothing will get fired in WM_MOUSEMOVE
+ // OnMouseEnter ();
+ // this.DefWndProc (ref m);
+ // break;
+
+ // FIXME: The first MOUSEMOVE after WM_MOUSEDOWN should be ingored
+ //
+ case Native.Msg.WM_MOUSEMOVE:
+ if (_mouseMoveAfterMouseDown) { // mousemove is send after each mousedown so ignore that
+ _mouseMoveAfterMouseDown = false;
+ this.BaseWndProc (ref m);
+ return;
+ }
+ // If selection is in progress pass the mouse move msg to the primary selection.
+ // If resizing is in progress pass to the parent of the primary selection (remmember that the selection
+ // frame is not a control and is drawn in the parent of the primary selection).
+ //
+ // Required in order for those 2 operations to continue when the mouse is moving over a control covering
+ // the one where the action takes place.
+ //
+ IUISelectionService uiSelectionServ = this.GetService (typeof (IUISelectionService)) as IUISelectionService;
+ ISelectionService selectionServ = this.GetService (typeof (ISelectionService)) as ISelectionService;
+ IDesignerHost host = this.GetService (typeof (IDesignerHost)) as IDesignerHost;
+
+
+ if (uiSelectionServ != null && selectionServ != null && host != null) {
+ Widget primarySelection = selectionServ.PrimarySelection as Widget;
+ Point location = new Point (Native.LoWord ((int)m.LParam), Native.HiWord ((int)m.LParam));
+
+ if (uiSelectionServ.SelectionInProgress &&
+ this.Component != host.RootComponent &&
+ this.Component != selectionServ.PrimarySelection) {
+
+ location = primarySelection.PointToClient (this.Widget.PointToScreen (location));
+ Native.SendMessage (primarySelection.Handle, (Native.Msg)m.Msg, m.WParam, Native.LParam (location.X, location.Y));
+ }
+ else if (uiSelectionServ.ResizeInProgress &&
+ // this.Component != host.RootComponent &&
+ this.Widget.Parent == ((Widget)selectionServ.PrimarySelection).Parent) {
+
+ location = this.Widget.Parent.PointToClient (this.Widget.PointToScreen (location));
+ Native.SendMessage (this.Widget.Parent.Handle, (Native.Msg)m.Msg, m.WParam, Native.LParam (location.X, location.Y));
+ }
+ else {
+ this.OnMouseMove (location.X, location.Y);
+ }
+ }
+ else {
+ this.OnMouseMove (Native.LoWord ((int)m.LParam), Native.HiWord ((int)m.LParam));
+ }
+ this.BaseWndProc (ref m);
+ break;
+
+ default:
+ // Pass everything else to the control and return
+ //
+ this.DefWndProc (ref m);
+ break;
+ }
+ }
+
+ // Indicates whether a mouse click at the specified point should be handled by the control.
+ //
+ protected virtual bool GetHitTest (Point point)
+ {
+ return false;
+ }
+
+ private bool IsMouseMessage (Native.Msg msg)
+ {
+ if (msg >= Native.Msg.WM_MOUSEFIRST && msg <= Native.Msg.WM_MOUSELAST)
+ return true;
+ else if (msg >= Native.Msg.WM_NCLBUTTONDOWN && msg <= Native.Msg.WM_NCMBUTTONDBLCLK)
+ return true;
+ else if (msg == Native.Msg.WM_MOUSEHOVER || msg == Native.Msg.WM_MOUSELEAVE)
+ return true;
+ else
+ return false;
+ }
+#endregion
+
+
+#region WndProc Message Handlers
+
+ protected virtual void OnSetCursor ()
+ {
+ }
+
+ // Raises the DoDefaultAction.
+ //
+ private void OnMouseDoubleClick ()
+ {
+ try {
+ base.DoDefaultAction ();
+ }
+ catch (Exception e) {
+ this.DisplayError (e);
+ }
+ }
+
+ internal virtual void OnMouseDown (int x, int y)
+ {
+ _mouseDown = true;
+ _mouseDownFirstMove = true;
+ IUISelectionService uiSelection = this.GetService (typeof (IUISelectionService)) as IUISelectionService;
+ if (uiSelection != null && uiSelection.AdornmentsHitTest (this.Widget, x, y)) {
+ // 1) prevent primary selection from being changed at this point.
+ // 2) delegate behaviour in the future to the IUISelectionService
+ }
+ else {
+ ISelectionService selectionService = this.GetService (typeof (ISelectionService)) as ISelectionService;
+ if (selectionService != null) {
+ selectionService.SetSelectedComponents (new IComponent[] { this.Component });
+ }
+ }
+ }
+
+ // Note that this is a pure WM_MOUSEMOVE acceptor
+ //
+ internal virtual void OnMouseMove (int x, int y)
+ {
+ if (_mouseDown) {
+ if (_mouseDownFirstMove) {
+ OnMouseDragBegin (x, y);
+ _mouseDownFirstMove = false;
+ }
+ else {
+ OnMouseDragMove (x, y);
+ }
+ }
+
+ }
+
+ internal virtual void OnMouseUp ()
+ {
+ IUISelectionService uiSelection = this.GetService (typeof (IUISelectionService)) as IUISelectionService;
+
+ if (_mouseDown) {
+ this.OnMouseDragEnd (false);
+ if (uiSelection != null && (uiSelection.SelectionInProgress || uiSelection.ResizeInProgress)) {
+ uiSelection.MouseDragEnd (false);
+ }
+ _mouseDown = false;
+ }
+ else {
+ if (uiSelection != null && (uiSelection.SelectionInProgress || uiSelection.ResizeInProgress)) {
+ // If the mouse up happens over the a control which is not defacto participating in
+ // the selection or resizing in progress, then inform the IUISelectionService of that event
+ //
+ uiSelection.MouseDragEnd (false);
+ }
+ }
+ }
+
+ protected virtual void OnMouseEnter ()
+ {
+ }
+
+ protected virtual void OnMouseHover ()
+ {
+ }
+
+ protected virtual void OnMouseLeave ()
+ {
+ }
+
+ // Provides an opportunity to perform additional processing immediately
+ // after the control handle has been created.
+ //
+ protected virtual void OnCreateHandle ()
+ {
+ }
+
+ // Called after the control is done with the painting so that the designer host
+ // can paint stuff over it.
+ //
+ protected virtual void OnPaintAdornments (PaintEventArgs pe)
+ {
+ }
+#endregion
+
+
+#region Mouse Dragging
+
+ MouseButtons _mouseButtonDown;
+
+ internal MouseButtons MouseButtonDown {
+ get { return _mouseButtonDown; }
+ }
+
+ protected virtual void OnMouseDragBegin (int x, int y)
+ {
+ IUISelectionService selectionServ = this.GetService (typeof (IUISelectionService)) as IUISelectionService;
+ if (selectionServ != null && ((this.SelectionRules & SelectionRules.Moveable) == SelectionRules.Moveable)) {
+ // once this is fired the parent control (parentcontroldesigner) will start getting dragover events.
+ //
+ selectionServ.DragBegin ();
+ }
+ }
+
+ protected virtual void OnMouseDragMove (int x, int y)
+ {
+ }
+
+ protected virtual void OnMouseDragEnd (bool cancel)
+ {
+ }
+#endregion
+
+
+#region Parenting
+ protected void HookChildWidgets (Widget firstWidget)
+ {
+ if (firstWidget != null) {
+ foreach (Widget control in firstWidget.Widgets) {
+ control.WindowTarget = (IWindowTarget) new WndProcRouter (control, (IMessageReceiver) this);
+ }
+ }
+ }
+
+ protected void UnhookChildWidgets (Widget firstWidget)
+ {
+ if (firstWidget != null) {
+ foreach (Widget control in firstWidget.Widgets) {
+ if (control.WindowTarget is WndProcRouter)
+ ((WndProcRouter) control.WindowTarget).Dispose ();
+ }
+ }
+ }
+
+ // Someone please tell me why the hell is this method here?
+ // What about having ParentWidgetDesigner.CanParent(...) ?
+ //
+ public virtual bool CanBeParentedTo (IDesigner parentDesigner)
+ {
+ IDesignerHost host = this.GetService (typeof (IDesignerHost)) as IDesignerHost;
+
+ if (parentDesigner is ParentWidgetDesigner &&
+ this.Component != host.RootComponent &&
+ !this.Widget.Widgets.Contains (((ParentWidgetDesigner)parentDesigner).Widget)) {
+ return true;
+ } else {
+ return false;
+ }
+ }
+#endregion
+
+ protected void DisplayError (Exception e)
+ {
+ if (e != null) {
+ IUIService uiService = GetService (typeof (IUIService)) as IUIService;
+ if (uiService != null) {
+ uiService.ShowError (e);
+ }
+ else {
+ string errorText = e.Message;
+ if (errorText == null || errorText == String.Empty)
+ errorText = e.ToString ();
+ MessageBox.Show (errorText, "Error");
+ }
+ }
+ }
+
+#region Drag and Drop handling
+
+ // Enables or disables Drag and Drop
+ //
+ protected void EnableDragDrop(bool value)
+ {
+ if (this.Widget != null) {
+ if (value) {
+ Widget.DragDrop += new DragEventHandler (OnDragDrop);
+ Widget.DragOver += new DragEventHandler (OnDragOver);
+ Widget.DragEnter += new DragEventHandler (OnDragEnter);
+ Widget.DragLeave += new EventHandler (OnDragLeave);
+ Widget.GiveFeedback += new GiveFeedbackEventHandler (OnGiveFeedback);
+ Widget.AllowDrop = true;
+ }
+ else {
+ Widget.DragDrop -= new DragEventHandler (OnDragDrop);
+ Widget.DragOver -= new DragEventHandler (OnDragOver);
+ Widget.DragEnter -= new DragEventHandler (OnDragEnter);
+ Widget.DragLeave -= new EventHandler (OnDragLeave);
+ Widget.GiveFeedback -= new GiveFeedbackEventHandler (OnGiveFeedback);
+ Widget.AllowDrop = false;
+ }
+ }
+ }
+
+ private void OnGiveFeedback (object sender, GiveFeedbackEventArgs e)
+ {
+ OnGiveFeedback (e);
+ }
+
+ private void OnDragDrop (object sender, DragEventArgs e)
+ {
+ OnDragDrop (e);
+ }
+
+ private void OnDragEnter (object sender, DragEventArgs e)
+ {
+ OnDragEnter (e);
+ }
+
+ private void OnDragLeave (object sender, EventArgs e)
+ {
+ OnDragLeave (e);
+ }
+
+ private void OnDragOver (object sender, DragEventArgs e)
+ {
+ OnDragOver (e);
+ }
+
+ protected virtual void OnGiveFeedback (GiveFeedbackEventArgs e)
+ {
+ e.UseDefaultCursors = false;
+ }
+
+ protected virtual void OnDragDrop (DragEventArgs e)
+ {
+ }
+
+ protected virtual void OnDragEnter (DragEventArgs e)
+ {
+ }
+
+ protected virtual void OnDragLeave (EventArgs e)
+ {
+ }
+
+ protected virtual void OnDragOver (DragEventArgs e)
+ {
+ }
+#endregion
+
+
+#region Redirected Properties
+
+ // This IDesignerFilter interface method override adds a set of properties
+ // to this designer's component at design time. This method adds the following
+ // browsable properties: "Visible", "Enabled", "ContextMenu", "AllowDrop", "Location",
+ // "Name", "Widgets", and "Locked".
+ //
+ // XXX: We aren't redirecting Widgets
+ //
+ protected override void PreFilterProperties (IDictionary properties)
+ {
+ base.PreFilterProperties (properties);
+
+ string[] newProperties = {
+ "Visible", "Enabled", "ContextMenu", "AllowDrop", "Location", "Name",
+ };
+
+ Attribute[][] attributes = {
+ new Attribute[] { new DefaultValueAttribute (true) },
+ new Attribute[] { new DefaultValueAttribute (true) },
+ new Attribute[] { new DefaultValueAttribute (null) },
+ new Attribute[] { new DefaultValueAttribute (false) },
+ new Attribute[] { new DefaultValueAttribute (typeof (Point), "0, 0") },
+ new Attribute[] {}
+ };
+
+ PropertyDescriptor propertyDescriptor = null;
+
+ // If existing redirect each property to the WidgetDesigner.
+ //
+ for (int i=0; i < newProperties.Length; i++) {
+ propertyDescriptor = properties[newProperties[i]] as PropertyDescriptor;
+ if (propertyDescriptor != null)
+ properties[newProperties[i]] = TypeDescriptor.CreateProperty (typeof (WidgetDesigner),
+ propertyDescriptor,
+ attributes[i]);
+ }
+
+ // This one is a must to have.
+ //
+ properties["Locked"] = TypeDescriptor.CreateProperty (typeof (WidgetDesigner), "Locked",
+ typeof(bool),
+ new Attribute[] {
+ DesignOnlyAttribute.Yes,
+ BrowsableAttribute.Yes,
+ CategoryAttribute.Design,
+ new DefaultValueAttribute (false),
+ new DescriptionAttribute("The Locked property determines if we can move or resize the control.")
+ });
+
+ }
+
+ // ShadowProperties returns the real property value if there is no "shadow" one set
+ // Welcome to the land of shadows... :-)
+ //
+ private bool Visible {
+ get { return (bool) base.ShadowProperties["Visible"]; }
+ set { base.ShadowProperties["Visible"] = value; }
+ }
+
+ private bool Enabled {
+ get { return (bool) base.ShadowProperties["Enabled"]; }
+ set { base.ShadowProperties["Enabled"] = value; }
+ }
+
+ private bool Locked {
+ get { return _locked; }
+ set { _locked = value; }
+ }
+
+ private bool AllowDrop {
+ get { return (bool)base.ShadowProperties["AllowDrop"]; }
+ set { base.ShadowProperties["AllowDrop"] = value; }
+ }
+
+ private string Name {
+ get { return base.Component.Site.Name; }
+ set { base.Component.Site.Name = value; }
+ }
+
+ private Point Location {
+ get { return this.Widget.Location; }
+ set { this.Widget.Location = value; }
+ }
+#endregion
+
+
+#region Utility methods
+ internal object GetValue (object component, string propertyName)
+ {
+ return this.GetValue (component, propertyName, null);
+ }
+
+ internal object GetValue (object component, string propertyName, Type propertyType)
+ {
+ PropertyDescriptor prop = TypeDescriptor.GetProperties (component)[propertyName] as PropertyDescriptor;
+ if (prop == null)
+ throw new InvalidOperationException ("Property \"" + propertyName + "\" is missing on " +
+ component.GetType().AssemblyQualifiedName);
+ if (propertyType != null && !propertyType.IsAssignableFrom (prop.PropertyType))
+ throw new InvalidOperationException ("Types do not match: " + prop.PropertyType.AssemblyQualifiedName +
+ " : " + propertyType.AssemblyQualifiedName);
+ return prop.GetValue (component);
+ }
+
+ internal void SetValue (object component, string propertyName, object value)
+ {
+ PropertyDescriptor prop = TypeDescriptor.GetProperties (component)[propertyName] as PropertyDescriptor;
+
+ if (prop == null)
+ throw new InvalidOperationException ("Property \"" + propertyName + "\" is missing on " +
+ component.GetType().AssemblyQualifiedName);
+ if (!prop.PropertyType.IsAssignableFrom (value.GetType ()))
+ throw new InvalidOperationException ("Types do not match: " + value.GetType ().AssemblyQualifiedName +
+ " : " + prop.PropertyType.AssemblyQualifiedName);
+ if (!prop.IsReadOnly)
+ prop.SetValue (component, value);
+ }
+#endregion
+
+ protected override void Dispose (bool disposing)
+ {
+ if (disposing) {
+ if (this.Widget != null) {
+ UnhookChildWidgets (Widget);
+ OnMouseDragEnd (true);
+ _messageRouter.Dispose ();
+ this.Widget.DragDrop -= new DragEventHandler (OnDragDrop);
+ this.Widget.DragEnter -= new DragEventHandler (OnDragEnter);
+ this.Widget.DragLeave -= new EventHandler (OnDragLeave);
+ this.Widget.DragOver -= new DragEventHandler (OnDragOver);
+ }
+ }
+ base.Dispose (true);
+ }
+
+
+
+ public virtual WidgetDesigner InternalWidgetDesigner (int internalWidgetIndex)
+ {
+ return null;
+ }
+
+ public virtual int NumberOfInternalWidgetDesigners ()
+ {
+ return 0;
+ }
+
+ protected bool EnableDesignMode (Widget child, string name)
+ {
+ if (name == null)
+ throw new ArgumentNullException ("name");
+ if (child == null)
+ throw new ArgumentNullException ("child");
+
+ bool success = false;
+ INestedContainer nestedContainer = this.GetService (typeof (INestedContainer)) as INestedContainer;
+ if (nestedContainer != null) {
+ nestedContainer.Add (child, name);
+ success = true;
+ }
+ return success;
+ }
+
+#region NET_2_0 Stubs
+
+ [ComVisible (true)]
+ public class WidgetDesignerAccessibleObject : AccessibleObject
+ {
+ [MonoTODO]
+ public WidgetDesignerAccessibleObject (WidgetDesigner designer, Widget control)
+ {
+ throw new NotImplementedException ();
+ }
+
+ [MonoTODO]
+ public override AccessibleObject GetChild (int index)
+ {
+ throw new NotImplementedException ();
+ }
+
+ [MonoTODO]
+ public override int GetChildCount ()
+ {
+ throw new NotImplementedException ();
+ }
+
+ [MonoTODO]
+ public override AccessibleObject GetFocused ()
+ {
+ throw new NotImplementedException ();
+ }
+
+ [MonoTODO]
+ public override AccessibleObject GetSelected ()
+ {
+ throw new NotImplementedException ();
+ }
+
+ [MonoTODO]
+ public override AccessibleObject HitTest (int x, int y)
+ {
+ throw new NotImplementedException ();
+ }
+
+ [MonoTODO]
+ public override Rectangle Bounds {
+ get { throw new NotImplementedException (); }
+ }
+
+ [MonoTODO]
+ public override string DefaultAction {
+ get { throw new NotImplementedException (); }
+ }
+
+ [MonoTODO]
+ public override string Description {
+ get { throw new NotImplementedException (); }
+ }
+
+ [MonoTODO]
+ public override string Name {
+ get { throw new NotImplementedException (); }
+ }
+
+ [MonoTODO]
+ public override AccessibleObject Parent {
+ get { throw new NotImplementedException (); }
+ }
+
+ [MonoTODO]
+ public override AccessibleRole Role {
+ get { throw new NotImplementedException (); }
+ }
+
+ [MonoTODO]
+ public override AccessibleStates State {
+ get { throw new NotImplementedException (); }
+ }
+
+ [MonoTODO]
+ public override string Value {
+ get { throw new NotImplementedException (); }
+ }
+ }
+
+ [MonoTODO]
+ protected virtual WidgetBodyGlyph GetWidgetGlyph (GlyphSelectionType selectionType)
+ {
+ throw new NotImplementedException ();
+ }
+
+ [MonoTODO]
+ public virtual GlyphCollection GetGlyphs (GlyphSelectionType selectionType)
+ {
+ throw new NotImplementedException ();
+ }
+
+ [MonoTODO]
+ public override void InitializeExistingComponent (IDictionary defaultValues)
+ {
+ throw new NotImplementedException ();
+ }
+
+ [MonoTODO]
+ public override void InitializeNewComponent (IDictionary defaultValues)
+ {
+ throw new NotImplementedException ();
+ }
+
+ [MonoTODO]
+ protected virtual void OnDragComplete (DragEventArgs de)
+ {
+ throw new NotImplementedException ();
+ }
+
+ [MonoTODO]
+ protected override InheritanceAttribute InheritanceAttribute {
+ get { throw new NotImplementedException (); }
+ }
+
+ [MonoTODO]
+ public virtual IList SnapLines {
+ get { throw new NotImplementedException (); }
+ }
+
+ [MonoTODO]
+ public virtual bool ParticipatesWithSnapLines {
+ get { throw new NotImplementedException (); }
+ }
+
+ [MonoTODO]
+ public bool AutoResizeHandles {
+ get { throw new NotImplementedException (); }
+ set { throw new NotImplementedException (); }
+ }
+#endregion
+
+
+ }
+}
diff --git a/source/ShiftUI/Design/DefaultMenuCommands.cs b/source/ShiftUI/Design/DefaultMenuCommands.cs
new file mode 100644
index 0000000..8284d82
--- /dev/null
+++ b/source/ShiftUI/Design/DefaultMenuCommands.cs
@@ -0,0 +1,274 @@
+//
+// System.ComponentModel.Design.DefaultMenuCommands.cs
+//
+// Author:
+// Ivan N. Zlatev <[email protected]>
+//
+// (C) 2008 Ivan N. Zlatev
+//
+
+//
+// Permission is hereby granted, free of charge, to any person obtaining
+// a copy of this software and associated documentation files (the
+// "Software"), to deal in the Software without restriction, including
+// without limitation the rights to use, copy, modify, merge, publish,
+// distribute, sublicense, and/or sell copies of the Software, and to
+// permit persons to whom the Software is furnished to do so, subject to
+// the following conditions:
+//
+// The above copyright notice and this permission notice shall be
+// included in all copies or substantial portions of the Software.
+//
+// THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND,
+// EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF
+// MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND
+// NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE
+// LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION
+// OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION
+// WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
+//
+
+using System;
+using System.ComponentModel;
+using System.ComponentModel.Design;
+using System.ComponentModel.Design.Serialization;
+using System.Runtime.Serialization.Formatters.Binary;
+using System.Runtime.InteropServices;
+using ShiftUI;
+using System.Drawing;
+using System.Drawing.Design;
+using System.Collections;
+using System.IO;
+using ShiftUI.Design;
+
+namespace ShiftUI
+{
+ internal sealed class DefaultMenuCommands
+ {
+ private IServiceProvider _serviceProvider;
+ private const string DT_DATA_FORMAT = "DT_DATA_FORMAT";
+
+ public DefaultMenuCommands (IServiceProvider serviceProvider)
+ {
+ if (serviceProvider == null)
+ throw new ArgumentNullException ("serviceProvider");
+ _serviceProvider = serviceProvider;
+ }
+
+ public void AddTo (IMenuCommandService commands)
+ {
+ commands.AddCommand (new MenuCommand (Copy, StandardCommands.Copy));
+ commands.AddCommand (new MenuCommand (Cut, StandardCommands.Cut));
+ commands.AddCommand (new MenuCommand (Paste, StandardCommands.Paste));
+ commands.AddCommand (new MenuCommand (Delete, StandardCommands.Delete));
+ commands.AddCommand (new MenuCommand (SelectAll, StandardCommands.SelectAll));
+ }
+
+ private object _clipboard = null;
+
+ private void Copy (object sender, EventArgs args)
+ {
+ IDesignerSerializationService stateSerializer = GetService (typeof (IDesignerSerializationService)) as IDesignerSerializationService;
+ IDesignerHost host = GetService (typeof (IDesignerHost)) as IDesignerHost;
+ ISelectionService selection = GetService (typeof (ISelectionService)) as ISelectionService;
+ if (host == null || stateSerializer == null || selection == null)
+ return;
+
+ // copy selected components and their associated components
+ ICollection selectedComponents = selection.GetSelectedComponents ();
+ ArrayList toCopy = new ArrayList ();
+ foreach (object component in selectedComponents) {
+ if (component == host.RootComponent)
+ continue;
+ toCopy.Add (component);
+ Design.ComponentDesigner designer = host.GetDesigner ((IComponent)component) as Design.ComponentDesigner;
+ if (designer != null && designer.AssociatedComponents != null)
+ toCopy.AddRange (designer.AssociatedComponents);
+ }
+ object stateData = stateSerializer.Serialize (toCopy);
+ _clipboard = stateData;
+ // Console.WriteLine ("Copied components: ");
+ // foreach (object c in toCopy)
+ // Console.WriteLine (((IComponent)c).Site.Name);
+ //
+
+ // TODO: MWF X11 doesn't seem to support custom clipboard formats - bug #357642
+ //
+ // MemoryStream stream = new MemoryStream ();
+ // new BinaryFormatter().Serialize (stream, stateData);
+ // stream.Seek (0, SeekOrigin.Begin);
+ // byte[] serializedData = stream.GetBuffer ();
+ // Clipboard.SetDataObject (new DataObject (DT_DATA_FORMAT, serializedData));
+ }
+
+ // Reminder: We set control.Parent so that it gets serialized for Undo/Redo
+ //
+ private void Paste (object sender, EventArgs args)
+ {
+ IDesignerSerializationService stateSerializer = GetService (typeof (IDesignerSerializationService)) as IDesignerSerializationService;
+ ISelectionService selection = GetService (typeof (ISelectionService)) as ISelectionService;
+ IDesignerHost host = GetService (typeof (IDesignerHost)) as IDesignerHost;
+ IComponentChangeService changeService = GetService (typeof (IComponentChangeService)) as IComponentChangeService;
+ if (host == null || stateSerializer == null)
+ return;
+ //
+ // TODO: MWF X11 doesn't seem to support custom clipboard formats - bug #357642
+ //
+ // IDataObject dataObject = Clipboard.GetDataObject ();
+ // byte[] data = dataObject == null ? null : dataObject.GetData (DT_DATA_FORMAT) as byte[];
+ // if (data != null) {
+ // MemoryStream stream = new MemoryStream (data);
+ // stateSerializer.Deserialize (new BinaryFormatter().Deserialize (stream));
+ // .....
+ // }
+ //
+ if (_clipboard == null)
+ return;
+
+ DesignerTransaction transaction = host.CreateTransaction ("Paste");
+ ICollection components = stateSerializer.Deserialize (_clipboard);
+ // Console.WriteLine ("Pasted components: ");
+ // foreach (object c in components)
+ // Console.WriteLine (((IComponent)c).Site.Name);
+ foreach (object component in components) {
+ Widget control = component as Widget;
+ if (control == null)
+ continue; // pure Components are added to the ComponentTray by the DocumentDesigner
+
+ PropertyDescriptor parentProperty = TypeDescriptor.GetProperties (control)["Parent"];
+ if (control.Parent != null) {
+ // Already parented during deserialization?
+ // In that case explicitly raise component changing/ed for the Parent property,
+ // so it get's cought by the UndoEngine
+ if (changeService != null) {
+ changeService.OnComponentChanging (control, parentProperty);
+ changeService.OnComponentChanged (control, parentProperty, null, control.Parent);
+ }
+ } else {
+ ParentWidgetDesigner parentDesigner = null;
+ if (selection != null && selection.PrimarySelection != null)
+ parentDesigner = host.GetDesigner ((IComponent)selection.PrimarySelection) as ParentWidgetDesigner;
+ if (parentDesigner == null)
+ parentDesigner = host.GetDesigner (host.RootComponent) as DocumentDesigner;
+ if (parentDesigner != null && parentDesigner.CanParent (control))
+ parentProperty.SetValue (control, parentDesigner.Widget);
+ }
+ }
+ _clipboard = null;
+ transaction.Commit ();
+ ((IDisposable)transaction).Dispose ();
+ }
+
+ private void Cut (object sender, EventArgs args)
+ {
+ IDesignerHost host = GetService (typeof (IDesignerHost)) as IDesignerHost;
+ if (host == null)
+ return;
+ using (DesignerTransaction transaction = host.CreateTransaction ("Cut")) {
+ Copy (this, EventArgs.Empty);
+ Delete (this, EventArgs.Empty);
+ transaction.Commit ();
+ }
+ }
+
+ private void Delete (object sender, EventArgs args)
+ {
+ IDesignerHost host = GetService (typeof (IDesignerHost)) as IDesignerHost;
+ ISelectionService selection = GetService (typeof (ISelectionService)) as ISelectionService;
+ if (host == null || selection == null)
+ return;
+
+ ICollection selectedComponents = selection.GetSelectedComponents ();
+ string description = "Delete " +
+ (selectedComponents.Count > 1 ? (selectedComponents.Count.ToString () + " controls") :
+ ((IComponent)selection.PrimarySelection).Site.Name);
+ DesignerTransaction transaction = host.CreateTransaction (description);
+
+ foreach (object component in selectedComponents) {
+ if (component != host.RootComponent) {
+ Design.ComponentDesigner designer = host.GetDesigner ((IComponent)component) as Design.ComponentDesigner;
+ if (designer != null && designer.AssociatedComponents != null) {
+ foreach (object associatedComponent in designer.AssociatedComponents)
+ host.DestroyComponent ((IComponent)associatedComponent);
+ }
+ host.DestroyComponent ((IComponent)component);
+ }
+ }
+ selection.SetSelectedComponents (selectedComponents, SelectionTypes.Remove);
+ transaction.Commit ();
+ }
+
+ private void SelectAll (object sender, EventArgs args)
+ {
+ IDesignerHost host = GetService (typeof (IDesignerHost)) as IDesignerHost;
+ ISelectionService selection = GetService (typeof (ISelectionService)) as ISelectionService;
+ if (host != null && selection != null)
+ selection.SetSelectedComponents (host.Container.Components, SelectionTypes.Replace);
+ }
+
+ // * StandardCommands
+ // o AlignBottom
+ // o AlignHorizontalCenters
+ // o AlignLeft
+ // o AlignRight
+ // o AlignToGrid
+ // o AlignTop
+ // o AlignVerticalCenters
+ // o BringToFront
+ // o CenterHorizontally
+ // o CenterVertically
+ // -o Copy
+ // -o Cut
+ // -o Delete
+ // o HorizSpaceConcatenate
+ // o HorizSpaceDecrease
+ // o HorizSpaceIncrease
+ // o HorizSpaceMakeEqual
+ // -o Paste
+ // -o SelectAll
+ // o SendToBack
+ // o SizeToWidget
+ // o SizeToWidgetHeight
+ // o SizeToWidgetWidth
+ // o SizeToGrid
+ // o SnapToGrid
+ // o TabOrder
+ // o VertSpaceConcatenate
+ // o VertSpaceDecrease
+ // o VertSpaceIncrease
+ // o VertSpaceMakeEqual
+ // o ShowGrid
+ // o LockWidgets
+ //
+ // * MenuCommands
+ // o KeyDefaultAction
+ // o KeySelectNext
+ // o KeySelectPrevious
+ // o KeyMoveLeft
+ // o KeySizeWidthDecrease
+ // o KeyMoveRight
+ // o KeySizeWidthIncrease
+ // o KeyMoveUp
+ // o KeySizeHeightIncrease
+ // o KeyMoveDown
+ // o KeySizeHeightDecrease
+ // o KeyCancel
+ // o KeyNudgeLeft
+ // o KeyNudgeDown
+ // o KeyNudgeRight
+ // o KeyNudgeUp
+ // o KeyNudgeHeightIncrease
+ // o KeyNudgeHeightDecrease
+ // o KeyNudgeWidthDecrease
+ // o KeyNudgeWidthIncrease
+ // o DesignerProperties
+ // o KeyReverseCancel
+
+ private object GetService (Type serviceType)
+ {
+ if (_serviceProvider != null)
+ return _serviceProvider.GetService (serviceType);
+ return null;
+ }
+ }
+}
diff --git a/source/ShiftUI/Design/DocumentDesigner.cs b/source/ShiftUI/Design/DocumentDesigner.cs
new file mode 100644
index 0000000..e132b1d
--- /dev/null
+++ b/source/ShiftUI/Design/DocumentDesigner.cs
@@ -0,0 +1,485 @@
+//
+// ShiftUI.Design.DocumentDesigner
+//
+// Authors:
+// Ivan N. Zlatev (contact i-nZ.net)
+//
+// (C) 2006-2007 Ivan N. Zlatev
+
+//
+// Permission is hereby granted, free of charge, to any person obtaining
+// a copy of this software and associated documentation files (the
+// "Software"), to deal in the Software without restriction, including
+// without limitation the rights to use, copy, modify, merge, publish,
+// distribute, sublicense, and/or sell copies of the Software, and to
+// permit persons to whom the Software is furnished to do so, subject to
+// the following conditions:
+//
+// The above copyright notice and this permission notice shall be
+// included in all copies or substantial portions of the Software.
+//
+// THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND,
+// EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF
+// MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND
+// NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE
+// LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION
+// OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION
+// WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
+//
+
+using System;
+using System.ComponentModel;
+using System.ComponentModel.Design;
+using ShiftUI;
+using System.Drawing;
+using System.Drawing.Design;
+using System.Collections;
+using ShiftUI.Design.Behavior;
+
+namespace ShiftUI.Design
+{
+ [ToolboxItemFilter ("ShiftUI")]
+ public class DocumentDesigner : ScrollableWidgetDesigner, IRootDesigner, IToolboxUser
+ {
+
+ // This is what you *see*
+ /*
+ .-------------------------------------.
+ | Panel to host the designed Widget |
+ |--------------Splitter---------------|
+ | Panel with a ComponentTray |
+ |_____________________________________|
+
+ */
+ //
+#region DesignerViewFrame
+ public class DesignerViewFrame : ShiftUI.UserWidget
+ {
+ private ShiftUI.Panel DesignerPanel;
+ private ShiftUI.Splitter splitter1;
+ private ShiftUI.Panel ComponentTrayPanel;
+ private ComponentTray _componentTray;
+ private Widget _designedWidget;
+
+ public DesignerViewFrame (Widget designedWidget, ComponentTray tray)
+ {
+ if (designedWidget == null) {
+ throw new ArgumentNullException ("designedWidget");
+ }
+ if (tray == null) {
+ throw new ArgumentNullException ("tray");
+ }
+ //
+ // The InitializeComponent() call is required for Windows Forms designer support.
+ //
+ InitializeComponent();
+
+ _designedWidget = designedWidget;
+ this.SuspendLayout ();
+ this.DesignerPanel.Widgets.Add (designedWidget);
+ this.ResumeLayout ();
+
+ this.ComponentTray = tray;
+ }
+
+#region Windows Forms Designer generated code
+ /// <summary>
+ /// This method is required for Windows Forms designer support.
+ /// Do not change the method contents inside the source code editor. The Forms designer might
+ /// not be able to load this method if it was changed manually.
+ /// </summary>
+ private void InitializeComponent() {
+ this.ComponentTrayPanel = new ShiftUI.Panel();
+ this.splitter1 = new ShiftUI.Splitter();
+ this.DesignerPanel = new ShiftUI.Panel();
+ this.SuspendLayout();
+ //
+ // ComponentTrayPanel
+ //
+ this.ComponentTrayPanel.BackColor = System.Drawing.Color.LemonChiffon;
+ this.ComponentTrayPanel.Dock = ShiftUI.DockStyle.Bottom;
+ this.ComponentTrayPanel.Location = new System.Drawing.Point(0, 194);
+ this.ComponentTrayPanel.Name = "ComponentTrayPanel";
+ this.ComponentTrayPanel.Size = new System.Drawing.Size(292, 72);
+ this.ComponentTrayPanel.TabIndex = 1;
+ this.ComponentTrayPanel.Visible = false;
+ //
+ // splitter1
+ //
+ this.splitter1.Dock = ShiftUI.DockStyle.Bottom;
+ this.splitter1.Location = new System.Drawing.Point(0, 186);
+ this.splitter1.Name = "splitter1";
+ this.splitter1.Size = new System.Drawing.Size(292, 8);
+ this.splitter1.TabIndex = 2;
+ this.splitter1.TabStop = false;
+ this.splitter1.Visible = false;
+ //
+ // DesignerPanel
+ //
+ this.DesignerPanel.AutoScroll = true;
+ this.DesignerPanel.BackColor = System.Drawing.Color.White;
+ this.DesignerPanel.Dock = ShiftUI.DockStyle.Fill;
+ this.DesignerPanel.Location = new System.Drawing.Point(0, 0);
+ this.DesignerPanel.Name = "DesignerPanel";
+ this.DesignerPanel.Size = new System.Drawing.Size(292, 266);
+ this.DesignerPanel.TabIndex = 0;
+ this.DesignerPanel.MouseUp += new ShiftUI.MouseEventHandler(this.DesignerPanel_MouseUp);
+ this.DesignerPanel.MouseMove += new ShiftUI.MouseEventHandler(this.DesignerPanel_MouseMove);
+ this.DesignerPanel.MouseDown += new ShiftUI.MouseEventHandler(this.DesignerPanel_MouseDown);
+ this.DesignerPanel.Paint += new PaintEventHandler (DesignerPanel_Paint);
+ //
+ // DesignerViewFrame
+ //
+ this.Widgets.Add(this.splitter1);
+ this.Widgets.Add(this.ComponentTrayPanel);
+ this.Widgets.Add(this.DesignerPanel);
+ this.Name = "UserWidget1";
+ this.Size = new System.Drawing.Size(292, 266);
+ this.Dock = DockStyle.Fill;
+ this.ResumeLayout(false);
+ }
+
+#endregion
+
+ private bool _mouseDown = false;
+ private bool _firstMove = false;
+
+ void DesignerPanel_Paint (object sender, PaintEventArgs e)
+ {
+ IUISelectionService selectionServ = this.DesignedWidget.Site.GetService (typeof (IUISelectionService)) as IUISelectionService;
+ if (selectionServ != null)
+ selectionServ.PaintAdornments (this.DesignerPanel, e.Graphics);
+ }
+
+ void DesignerPanel_MouseDown(object sender, ShiftUI.MouseEventArgs e)
+ {
+ _mouseDown = true;
+ _firstMove = true;
+ }
+
+ void DesignerPanel_MouseMove(object sender, ShiftUI.MouseEventArgs e)
+ {
+ IUISelectionService selectionServ = this.DesignedWidget.Site.GetService (typeof (IUISelectionService)) as IUISelectionService;
+ if (selectionServ == null)
+ return;
+
+ selectionServ.SetCursor (e.X, e.Y);
+ if (_mouseDown) {
+ if (_firstMove) {
+ selectionServ.MouseDragBegin (this.DesignerPanel, e.X, e.Y);
+ _firstMove = false;
+ }
+ else {
+ selectionServ.MouseDragMove (e.X, e.Y);
+ }
+ }
+ else if (selectionServ.SelectionInProgress) {
+ selectionServ.MouseDragMove (e.X, e.Y);
+ }
+ }
+
+ void DesignerPanel_MouseUp(object sender, ShiftUI.MouseEventArgs e)
+ {
+ IUISelectionService selectionServ = this.DesignedWidget.Site.GetService (typeof (IUISelectionService)) as IUISelectionService;
+ if (_mouseDown) {
+ if (selectionServ != null)
+ selectionServ.MouseDragEnd (false);
+ _mouseDown = false;
+ }
+ else if (selectionServ.SelectionInProgress) {
+ selectionServ.MouseDragEnd (false);
+ }
+ }
+
+ // by default the component tray is hidden and essentially should be shown once there
+ // is a component added to it
+ //
+ public void ShowComponentTray ()
+ {
+ if (!this.ComponentTray.Visible) {
+ this.ComponentTrayPanel.Visible = true;
+ this.ComponentTray.Visible = true;
+ this.splitter1.Visible = true;
+ }
+ }
+
+ public void HideComponentTray ()
+ {
+ if (!this.ComponentTray.Visible) {
+ this.ComponentTrayPanel.Visible = true;
+ this.ComponentTray.Visible = true;
+ this.splitter1.Visible = true;
+ }
+ }
+
+ public ComponentTray ComponentTray {
+ get { return _componentTray; }
+ set {
+ this.SuspendLayout ();
+ this.ComponentTrayPanel.Widgets.Remove (_componentTray);
+ this.ComponentTrayPanel.Widgets.Add (value);
+ this.ResumeLayout ();
+ _componentTray = value;
+ _componentTray.Visible = false;
+ }
+ }
+
+ public Widget DesignedWidget {
+ get { return _designedWidget; }
+ set {
+ }
+ }
+
+ protected override void Dispose (bool disposing)
+ {
+ if (_designedWidget != null) {
+ this.DesignerPanel.Widgets.Remove (_designedWidget);
+ _designedWidget = null;
+ }
+
+ if (_componentTray != null) {
+ this.ComponentTrayPanel.Widgets.Remove (_componentTray);
+ _componentTray.Dispose ();
+ _componentTray = null;
+ }
+
+ base.Dispose (disposing);
+ }
+ }
+#endregion
+
+
+
+
+ private DesignerViewFrame _designerViewFrame;
+
+ public DocumentDesigner ()
+ {
+ }
+
+ private DesignerViewFrame View {
+ get { return _designerViewFrame; }
+ }
+
+#region Initialization
+ public override void Initialize (IComponent component)
+ {
+ base.Initialize (component);
+
+ _designerViewFrame = new DesignerViewFrame (this.Widget, new ComponentTray (this, component.Site));
+ _designerViewFrame.DesignedWidget.Location = new Point (15, 15);
+ SetValue (this.Component, "Location", new Point (0, 0));
+
+ IComponentChangeService componentChangeSvc = GetService (typeof (IComponentChangeService)) as IComponentChangeService;
+ if (componentChangeSvc != null) {
+ componentChangeSvc.ComponentAdded += new ComponentEventHandler (OnComponentAdded);
+ componentChangeSvc.ComponentRemoved += new ComponentEventHandler (OnComponentRemoved);
+ }
+
+ IMenuCommandService menuCommands = GetService (typeof (IMenuCommandService)) as IMenuCommandService;
+ IServiceContainer serviceContainer = this.GetService (typeof (IServiceContainer)) as IServiceContainer;
+ if (menuCommands != null && serviceContainer != null)
+ new DefaultMenuCommands (serviceContainer).AddTo (menuCommands);
+ InitializeSelectionService ();
+ }
+
+ private void InitializeSelectionService ()
+ {
+ IUISelectionService guiSelectionService = this.GetService (typeof (IUISelectionService)) as IUISelectionService;
+ if (guiSelectionService == null) {
+ IServiceContainer serviceContainer = this.GetService (typeof (IServiceContainer)) as IServiceContainer;
+ serviceContainer.AddService (typeof (IUISelectionService), (IUISelectionService) new UISelectionService (serviceContainer));
+ }
+
+ ISelectionService selectionService = this.GetService (typeof (ISelectionService)) as ISelectionService;
+ selectionService.SetSelectedComponents (new IComponent[] { this.Component });
+ }
+
+
+ protected override void Dispose (bool disposing)
+ {
+ if (disposing) {
+ if (_designerViewFrame != null) {
+ _designerViewFrame.Dispose ();
+ _designerViewFrame = null;
+
+ }
+ IComponentChangeService componentChangeSvc = GetService (typeof (IComponentChangeService)) as IComponentChangeService;
+ if (componentChangeSvc != null) {
+ componentChangeSvc.ComponentAdded -= new ComponentEventHandler (OnComponentAdded);
+ componentChangeSvc.ComponentRemoved -= new ComponentEventHandler (OnComponentRemoved);
+ }
+ }
+ base.Dispose (disposing);
+ }
+#endregion
+
+
+#region MSDN says overriden
+
+ public override GlyphCollection GetGlyphs (GlyphSelectionType selectionType)
+ {
+ return base.GetGlyphs (selectionType);
+ }
+
+ protected override void WndProc (ref Message m)
+ {
+ base.WndProc (ref m);
+ }
+
+ protected override void OnCreateHandle ()
+ {
+ base.OnCreateHandle ();
+ }
+
+#endregion
+
+
+#region Components and ComponentTray
+
+ private void OnComponentAdded (object sender, ComponentEventArgs args)
+ {
+ if (!(args.Component is Widget)) {
+ this.View.ComponentTray.AddComponent (args.Component);
+ if (this.View.ComponentTray.ComponentCount > 0) {
+ if (!this.View.ComponentTray.Visible)
+ this.View.ShowComponentTray ();
+ }
+ }
+ }
+
+ private void OnComponentRemoved (object sender, ComponentEventArgs args)
+ {
+ if (!(args.Component is Widget)) {
+ this.View.ComponentTray.RemoveComponent (args.Component);
+ if (this.View.ComponentTray.ComponentCount == 0) {
+ if (this.View.ComponentTray.Visible)
+ this.View.HideComponentTray ();
+ }
+ }
+ }
+#endregion
+
+
+#region IRootDesigner
+
+ object IRootDesigner.GetView (ViewTechnology technology)
+ {
+ if (technology != ViewTechnology.Default)
+ throw new ArgumentException ("Only ViewTechnology.WindowsForms is supported.");
+ return _designerViewFrame;
+ }
+
+ ViewTechnology[] IRootDesigner.SupportedTechnologies {
+ get {
+ return new ViewTechnology[] { ViewTechnology.Default };
+ }
+ }
+#endregion
+
+
+#region IToolBoxUser
+
+ // Indicates whether the specified tool is supported by the designer.
+ // If it is not the tool is disabled in the toolbox.
+ //
+ // Used for subclasses, e.g the FormDocumentDesigner won't accept a Form?
+ //
+ bool IToolboxUser.GetToolSupported (ToolboxItem tool)
+ {
+ return this.GetToolSupported (tool);
+ }
+
+ protected virtual bool GetToolSupported (ToolboxItem tool)
+ {
+ return true;
+ }
+
+
+ // Handles the behavior that occurs when a user double-clicks a toolbox item.
+ //
+ void IToolboxUser.ToolPicked (ToolboxItem tool)
+ {
+ this.ToolPicked (tool);
+ }
+
+ // ToolPicked is called when the user double-clicks on a toolbox item.
+ // The document designer should create a component for the specified tool.
+ // Only tools that are enabled in the toolbox will be passed to this method.
+ //
+ // I create the component in the parent container of the primary selection.
+ // If not available I create it in the rootcomponent (this essentially :-) )
+ //
+ protected virtual void ToolPicked (ToolboxItem tool)
+ {
+ ISelectionService selectionSvc = GetService (typeof (ISelectionService)) as ISelectionService;
+ IDesignerHost host = GetService (typeof (IDesignerHost)) as IDesignerHost;
+ if (selectionSvc != null && host != null) {
+ IDesigner designer = host.GetDesigner ((IComponent) selectionSvc.PrimarySelection);
+ if (designer is ParentWidgetDesigner)
+ ParentWidgetDesigner.InvokeCreateTool ((ParentWidgetDesigner) designer, tool);
+ else
+ this.CreateTool (tool);
+ }
+ else {
+ this.CreateTool (tool);
+ }
+ IToolboxService tbServ = this.GetService (typeof (IToolboxService)) as IToolboxService;
+ tbServ.SelectedToolboxItemUsed ();
+ }
+#endregion
+
+
+#region Properties
+ // A root designer can be resized to the bottom and to the right.
+ //
+ public override SelectionRules SelectionRules {
+ get {
+ return (SelectionRules.RightSizeable | SelectionRules.BottomSizeable | SelectionRules.Visible);
+ }
+ }
+#endregion
+
+
+#region Metadata filtering and Design-Time properties
+
+ // MSDN says that this adds the "BackColor" and "Location" browsable design-time propeties.
+ //
+ // The reason for overwriting the Location property created by the ControDesigner is that
+ // the root component is not draggable (e.g a form has a static location in the DesignerViewFrame)
+ //
+ protected override void PreFilterProperties (IDictionary properties)
+ {
+ base.PreFilterProperties (properties);
+
+ PropertyDescriptor propertyDescriptor = properties["BackColor"] as PropertyDescriptor;
+ if (propertyDescriptor != null) {
+ properties["BackColor"] = TypeDescriptor.CreateProperty (typeof (DocumentDesigner),
+ propertyDescriptor,
+ new Attribute[] { new DefaultValueAttribute (System.Drawing.SystemColors.Control) });
+ }
+
+ propertyDescriptor = properties["Location"] as PropertyDescriptor;
+ if (propertyDescriptor != null) {
+ properties["Location"] = TypeDescriptor.CreateProperty (typeof (DocumentDesigner),
+ propertyDescriptor,
+ new Attribute[] { new DefaultValueAttribute (typeof (Point), "0, 0") });
+ }
+ }
+
+ private Color BackColor {
+ get { return (Color) ShadowProperties["BackColor"]; }
+ set {
+ ShadowProperties["BackColor"] = value;
+ this.Widget.BackColor = value;
+ }
+ }
+
+ private Point Location {
+ get { return (Point) ShadowProperties["Location"]; }
+ set { ShadowProperties["Location"] = value; }
+ }
+#endregion
+
+ }
+}
diff --git a/source/ShiftUI/Design/EventsTab.cs b/source/ShiftUI/Design/EventsTab.cs
new file mode 100644
index 0000000..570f850
--- /dev/null
+++ b/source/ShiftUI/Design/EventsTab.cs
@@ -0,0 +1,101 @@
+// Permission is hereby granted, free of charge, to any person obtaining
+// a copy of this software and associated documentation files (the
+// "Software"), to deal in the Software without restriction, including
+// without limitation the rights to use, copy, modify, merge, publish,
+// distribute, sublicense, and/or sell copies of the Software, and to
+// permit persons to whom the Software is furnished to do so, subject to
+// the following conditions:
+//
+// The above copyright notice and this permission notice shall be
+// included in all copies or substantial portions of the Software.
+//
+// THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND,
+// EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF
+// MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND
+// NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE
+// LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION
+// OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION
+// WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
+//
+// Copyright (c) 2004-2008 Novell, Inc.
+//
+// Authors:
+// Dennis Hayes ([email protected])
+// Rafael Teixeira ([email protected])
+// Ivan N. Zlatev ([email protected])
+//
+
+// COMPLETE
+
+using System;
+using System.ComponentModel;
+using System.ComponentModel.Design;
+
+namespace ShiftUI.Design
+{
+ public class EventsTab : PropertyTab
+ {
+ private EventsTab()
+ {
+ }
+
+ private IServiceProvider serviceProvider;
+
+ public EventsTab(IServiceProvider sp)
+ {
+ this.serviceProvider = sp;
+ }
+
+ public override string HelpKeyword {
+ get { return TabName; }
+ }
+
+ public override string TabName {
+ get { return "Events"; }
+ }
+
+ public override PropertyDescriptorCollection GetProperties(ITypeDescriptorContext context, object component,
+ Attribute[] attributes)
+ {
+ IEventBindingService eventPropertySvc = null;
+ EventDescriptorCollection events = null;
+
+ if (serviceProvider != null)
+ eventPropertySvc = (IEventBindingService) serviceProvider.GetService(typeof(IEventBindingService));
+
+ if (eventPropertySvc == null)
+ return new PropertyDescriptorCollection(null);
+
+ if (attributes != null)
+ events = TypeDescriptor.GetEvents(component, attributes);
+ else
+ events = TypeDescriptor.GetEvents(component);
+
+ // Return event properties for the event descriptors.
+ return eventPropertySvc.GetEventProperties(events);
+ }
+
+ public override PropertyDescriptorCollection GetProperties(object component, Attribute[] attributes)
+ {
+ return this.GetProperties(null, component, attributes);
+ }
+
+ public override bool CanExtend(object extendee)
+ {
+ return false;
+ }
+
+ public override PropertyDescriptor GetDefaultProperty(object obj)
+ {
+ if (serviceProvider == null)
+ return null;
+
+ EventDescriptor defaultEvent = TypeDescriptor.GetDefaultEvent (obj);
+ IEventBindingService eventPropertySvc = (IEventBindingService) serviceProvider.GetService(typeof(IEventBindingService));
+ if (defaultEvent != null && eventPropertySvc != null)
+ return eventPropertySvc.GetEventProperty (defaultEvent);
+ return null;
+ }
+
+ }
+}
diff --git a/source/ShiftUI/Design/FormDocumentDesigner.cs b/source/ShiftUI/Design/FormDocumentDesigner.cs
new file mode 100644
index 0000000..d3f8b14
--- /dev/null
+++ b/source/ShiftUI/Design/FormDocumentDesigner.cs
@@ -0,0 +1,86 @@
+//
+// ShiftUI.Design.FormDocumentDesigner
+//
+// Authors:
+// Ivan N. Zlatev (contact i-nZ.net)
+//
+// (C) 2008 Ivan N. Zlatev
+
+//
+// Permission is hereby granted, free of charge, to any person obtaining
+// a copy of this software and associated documentation files (the
+// "Software"), to deal in the Software without restriction, including
+// without limitation the rights to use, copy, modify, merge, publish,
+// distribute, sublicense, and/or sell copies of the Software, and to
+// permit persons to whom the Software is furnished to do so, subject to
+// the following conditions:
+//
+// The above copyright notice and this permission notice shall be
+// included in all copies or substantial portions of the Software.
+//
+// THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND,
+// EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF
+// MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND
+// NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE
+// LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION
+// OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION
+// WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
+//
+
+using System;
+using System.ComponentModel;
+using System.ComponentModel.Design;
+using ShiftUI;
+using System.Drawing;
+using System.Drawing.Design;
+using System.Collections;
+
+namespace ShiftUI.Design
+{
+ internal class FormDocumentDesigner : DocumentDesigner
+ {
+
+ public FormDocumentDesigner ()
+ {
+ }
+
+ public override void Initialize (IComponent component)
+ {
+ Form form = component as Form;
+ if (form == null)
+ throw new NotSupportedException ("FormDocumentDesigner can be initialized only with Forms");
+
+ form.TopLevel = false;
+ form.Visible = true;
+ base.Initialize (component);
+ }
+
+ public override bool CanParent (Widget control)
+ {
+ if (control is Form)
+ return false;
+ return base.CanParent (control);
+ }
+
+ protected override void WndProc (ref Message m)
+ {
+ // Filter out titlebar clicks
+ //
+ switch ((Native.Msg) m.Msg) {
+ case Native.Msg.WM_NCLBUTTONDBLCLK:
+ case Native.Msg.WM_NCLBUTTONDOWN:
+ case Native.Msg.WM_NCMBUTTONDBLCLK:
+ case Native.Msg.WM_NCMBUTTONDOWN:
+ case Native.Msg.WM_NCRBUTTONDBLCLK:
+ case Native.Msg.WM_NCRBUTTONDOWN:
+ ISelectionService selectionServ = this.GetService (typeof (ISelectionService)) as ISelectionService;
+ if (selectionServ != null)
+ selectionServ.SetSelectedComponents (new object[] { this.Component });
+ break;
+ default:
+ base.WndProc (ref m);
+ break;
+ }
+ }
+ }
+}
diff --git a/source/ShiftUI/Design/IMenuEditorService.cs b/source/ShiftUI/Design/IMenuEditorService.cs
new file mode 100644
index 0000000..2d90849
--- /dev/null
+++ b/source/ShiftUI/Design/IMenuEditorService.cs
@@ -0,0 +1,34 @@
+
+//
+// Permission is hereby granted, free of charge, to any person obtaining
+// a copy of this software and associated documentation files (the
+// "Software"), to deal in the Software without restriction, including
+// without limitation the rights to use, copy, modify, merge, publish,
+// distribute, sublicense, and/or sell copies of the Software, and to
+// permit persons to whom the Software is furnished to do so, subject to
+// the following conditions:
+//
+// The above copyright notice and this permission notice shall be
+// included in all copies or substantial portions of the Software.
+//
+// THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND,
+// EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF
+// MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND
+// NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE
+// LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION
+// OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION
+// WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
+//
+using System;
+
+namespace ShiftUI.Design
+{
+ public interface IMenuEditorService
+ {
+ Menu GetMenu();
+ bool IsActive();
+ bool MessageFilter(ref Message m);
+ void SetMenu(Menu menu);
+ void SetSelection(MenuItem item);
+ }
+}
diff --git a/source/ShiftUI/Design/IMessageReceiver.cs b/source/ShiftUI/Design/IMessageReceiver.cs
new file mode 100644
index 0000000..b36ad31
--- /dev/null
+++ b/source/ShiftUI/Design/IMessageReceiver.cs
@@ -0,0 +1,39 @@
+//
+// ShiftUI.Design.IMessageReceiver
+//
+// Authors:
+// Ivan N. Zlatev (contact i-nZ.net)
+//
+// (C) 2006-2007 Ivan N. Zlatev
+
+//
+// Permission is hereby granted, free of charge, to any person obtaining
+// a copy of this software and associated documentation files (the
+// "Software"), to deal in the Software without restriction, including
+// without limitation the rights to use, copy, modify, merge, publish,
+// distribute, sublicense, and/or sell copies of the Software, and to
+// permit persons to whom the Software is furnished to do so, subject to
+// the following conditions:
+//
+// The above copyright notice and this permission notice shall be
+// included in all copies or substantial portions of the Software.
+//
+// THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND,
+// EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF
+// MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND
+// NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE
+// LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION
+// OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION
+// WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
+//
+
+using System;
+using ShiftUI;
+
+namespace ShiftUI.Design
+{
+ internal interface IMessageReceiver
+ {
+ void WndProc (ref Message m);
+ }
+}
diff --git a/source/ShiftUI/Design/IUISelectionService.cs b/source/ShiftUI/Design/IUISelectionService.cs
new file mode 100644
index 0000000..7c8ad47
--- /dev/null
+++ b/source/ShiftUI/Design/IUISelectionService.cs
@@ -0,0 +1,71 @@
+//
+// ShiftUI.Design.IUISelectionService
+//
+// Authors:
+// Ivan N. Zlatev (contact i-nZ.net)
+//
+// (C) 2006-2007 Ivan N. Zlatev
+
+//
+// Permission is hereby granted, free of charge, to any person obtaining
+// a copy of this software and associated documentation files (the
+// "Software"), to deal in the Software without restriction, including
+// without limitation the rights to use, copy, modify, merge, publish,
+// distribute, sublicense, and/or sell copies of the Software, and to
+// permit persons to whom the Software is furnished to do so, subject to
+// the following conditions:
+//
+// The above copyright notice and this permission notice shall be
+// included in all copies or substantial portions of the Software.
+//
+// THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND,
+// EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF
+// MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND
+// NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE
+// LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION
+// OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION
+// WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
+//
+
+using System;
+using System.Collections;
+using System.ComponentModel;
+using System.ComponentModel.Design;
+using System.Drawing;
+using System.Drawing.Drawing2D;
+using ShiftUI;
+
+namespace ShiftUI.Design
+{
+
+
+ internal interface IUISelectionService
+ {
+ bool SelectionInProgress {
+ get;
+ }
+ bool DragDropInProgress {
+ get;
+ }
+ bool ResizeInProgress {
+ get;
+ }
+
+ Rectangle SelectionBounds {
+ get;
+ }
+
+ void MouseDragBegin (Widget container, int x, int y);
+ void MouseDragMove (int x, int y);
+ void MouseDragEnd (bool cancel);
+
+ void DragBegin ();
+ void DragOver (Widget container, int x, int y);
+ void DragDrop (bool cancel, Widget container, int x, int y);
+
+ void PaintAdornments (Widget container, Graphics gfx);
+ bool SetCursor (int x, int y);
+
+ bool AdornmentsHitTest (Widget control, int x, int y);
+ }
+}
diff --git a/source/ShiftUI/Design/IUIService.cs b/source/ShiftUI/Design/IUIService.cs
new file mode 100644
index 0000000..71368dd
--- /dev/null
+++ b/source/ShiftUI/Design/IUIService.cs
@@ -0,0 +1,52 @@
+// Permission is hereby granted, free of charge, to any person obtaining
+// a copy of this software and associated documentation files (the
+// "Software"), to deal in the Software without restriction, including
+// without limitation the rights to use, copy, modify, merge, publish,
+// distribute, sublicense, and/or sell copies of the Software, and to
+// permit persons to whom the Software is furnished to do so, subject to
+// the following conditions:
+//
+// The above copyright notice and this permission notice shall be
+// included in all copies or substantial portions of the Software.
+//
+// THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND,
+// EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF
+// MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND
+// NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE
+// LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION
+// OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION
+// WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
+//
+// Copyright (c) 2004 Novell, Inc.
+//
+// Authors:
+// Andreas Nahr ([email protected])
+//
+
+// NOT COMPLETE
+
+using System.Runtime.InteropServices;
+using System.Collections;
+using System;
+
+namespace ShiftUI.Design
+{
+ [Guid ("06a9c74b-5e32-4561-be73-381b37869f4f")]
+ public interface IUIService
+ {
+ IDictionary Styles {get;}
+
+ bool CanShowComponentEditor (object component);
+ IWin32Window GetDialogOwnerWindow ();
+ void SetUIDirty ();
+ bool ShowComponentEditor (object component, IWin32Window parent);
+ void ShowError (Exception ex);
+ void ShowError (string message);
+ void ShowError (Exception ex, string message);
+ DialogResult ShowDialog (Form form);
+ void ShowMessage (string message);
+ void ShowMessage (string message, string caption);
+ DialogResult ShowMessage (string message, string caption, MessageBoxButtons buttons);
+ bool ShowToolWindow (Guid toolWindow);
+ }
+}
diff --git a/source/ShiftUI/Design/IWindowsFormsEditorService.cs b/source/ShiftUI/Design/IWindowsFormsEditorService.cs
new file mode 100644
index 0000000..cfd5601
--- /dev/null
+++ b/source/ShiftUI/Design/IWindowsFormsEditorService.cs
@@ -0,0 +1,35 @@
+// Permission is hereby granted, free of charge, to any person obtaining
+// a copy of this software and associated documentation files (the
+// "Software"), to deal in the Software without restriction, including
+// without limitation the rights to use, copy, modify, merge, publish,
+// distribute, sublicense, and/or sell copies of the Software, and to
+// permit persons to whom the Software is furnished to do so, subject to
+// the following conditions:
+//
+// The above copyright notice and this permission notice shall be
+// included in all copies or substantial portions of the Software.
+//
+// THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND,
+// EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF
+// MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND
+// NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE
+// LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION
+// OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION
+// WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
+//
+// Copyright (c) 2004 Novell, Inc.
+//
+// Authors:
+// Andreas Nahr ([email protected])
+//
+
+// NOT COMPLETE
+
+namespace ShiftUI.Design
+{
+ public interface IWindowsFormsEditorService {
+ void CloseDropDown ();
+ void DropDownWidget (Widget Widget);
+ DialogResult ShowDialog (Form dialog);
+ }
+}
diff --git a/source/ShiftUI/Design/Native.cs b/source/ShiftUI/Design/Native.cs
new file mode 100644
index 0000000..bd86c42
--- /dev/null
+++ b/source/ShiftUI/Design/Native.cs
@@ -0,0 +1,216 @@
+//
+// ShiftUI.Design.Native
+//
+// Authors:
+// Ivan N. Zlatev (contact i-nZ.net)
+//
+// (C) 2006-2007 Ivan N. Zlatev
+//
+// Permission is hereby granted, free of charge, to any person obtaining
+// a copy of this software and associated documentation files (the
+// "Software"), to deal in the Software without restriction, including
+// without limitation the rights to use, copy, modify, merge, publish,
+// distribute, sublicense, and/or sell copies of the Software, and to
+// permit persons to whom the Software is furnished to do so, subject to
+// the following conditions:
+//
+// The above copyright notice and this permission notice shall be
+// included in all copies or substantial portions of the Software.
+//
+// THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND,
+// EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF
+// MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND
+// NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE
+// LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION
+// OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION
+// WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
+//
+
+using System;
+using System.Drawing;
+using ShiftUI;
+using System.Runtime.InteropServices;
+using System.Reflection;
+
+
+namespace ShiftUI
+{
+
+ internal class Native
+ {
+
+ private static Type _xplatuiType;
+
+ static Native ()
+ {
+ Assembly assembly = Assembly.GetExecutingAssembly();
+ if (assembly == null)
+ throw new InvalidOperationException ("Can't load ShiftUI assembly.");
+
+ _xplatuiType = assembly.GetType ("ShiftUI.XplatUI");
+ if (_xplatuiType == null)
+ throw new InvalidOperationException ("Can't find the ShiftUI.XplatUI type.");
+ }
+
+ private static object InvokeMethod (string methodName, object[] args)
+ {
+ return InvokeMethod (methodName, args, null);
+ }
+
+ // will also match types
+ private static object InvokeMethod (string methodName, object[] args, Type[] types)
+ {
+ MethodInfo method = null;
+
+ if (types != null) {
+ method = _xplatuiType.GetMethod (methodName, BindingFlags.NonPublic | BindingFlags.Static |
+ BindingFlags.InvokeMethod, null, types, null);
+ } else {
+ method = _xplatuiType.GetMethod (methodName, BindingFlags.NonPublic | BindingFlags.Static |
+ BindingFlags.InvokeMethod);
+ }
+
+ if (method == null)
+ throw new InvalidOperationException (methodName + " not found!");
+
+ return method.Invoke (null, args);
+ }
+
+ public static void DefWndProc (ref Message m)
+ {
+ object[] args = new object[] { m };
+ m.Result = (IntPtr) InvokeMethod ("DefWndProc", args);
+ m = (Message) args[0];
+ }
+
+ public static IntPtr SendMessage (IntPtr hwnd, Msg message, IntPtr wParam, IntPtr lParam)
+ {
+
+ Assembly assembly = Assembly.GetExecutingAssembly();
+ Type refType = assembly.GetType ("ShiftUI.Message&");
+ object[] args = new object[] { Message.Create (hwnd, (int)message, wParam, lParam) };
+ InvokeMethod ("SendMessage", args, new Type[] { refType });
+ return ((Message)args[0]).Result;
+ }
+
+ public static Point PointToClient (Widget control, Point point)
+ {
+ if (control == null)
+ throw new ArgumentNullException ("control");
+
+ object[] args = new object[] { control.Handle, point.X, point.Y };
+ InvokeMethod ("ScreenToClient", args);
+ return new Point ((int) args[1], (int) args[2]);
+ }
+
+ public static IntPtr SetParent (IntPtr childHandle, IntPtr parentHandle)
+ {
+ return (IntPtr) InvokeMethod ("SetParent", new object[] { childHandle, parentHandle });
+ }
+
+
+#region Helpers
+ public static int HiWord (int dword)
+ {
+ // 12345678 -> 12340000 -> 00001234
+ return ((dword >> 16) & 0x0000ffff);
+ }
+
+ public static int LoWord (int dword)
+ {
+ // 12345678 -> 00005678
+ return (dword & 0x0000ffff);
+ }
+
+ public static IntPtr LParam (int hiword, int loword)
+ {
+ // results [hiword|loword] dword
+ //
+ return (IntPtr)((loword << 16) | (hiword & 0x0000FFFF));
+ }
+#endregion
+
+ public enum Msg {
+ WM_CREATE = 0x0001,
+ WM_SETFOCUS = 0x0007,
+ WM_PAINT = 0X000F,
+ WM_CANCELMODE = 0x001F,
+ WM_SETCURSOR = 0x0020,
+ WM_CONTEXTMENU = 0x007B,
+ WM_NCHITTEST = 0x0084,
+ //
+ // AccessabilityObject
+ //
+ WM_GETOBJECT = 0x003D,
+ //
+ // Mouse input - Client area
+ //
+ WM_MOUSEFIRST = 0x0200,
+ 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_MOUSELAST = 0x020A,
+ WM_NCMOUSEHOVER = 0x02A0,
+ WM_MOUSEHOVER = 0x02A1,
+ WM_NCMOUSELEAVE = 0x02A2,
+ WM_MOUSELEAVE = 0x02A3,
+ //
+ // Mouse input - Non-client area
+ //
+ 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,
+ //
+ // Keyboard input
+ //
+ WM_KEYFIRST = 0x0100,
+ WM_KEYDOWN = 0x0100,
+ WM_KEYUP = 0x0101,
+ WM_CHAR = 0x0102,
+ WM_DEADCHAR = 0x0103,
+ WM_SYSKEYDOWN = 0x0104,
+ WM_SYSKEYUP = 0x0105,
+ WM_SYS1CHAR = 0x0106,
+ WM_SYSDEADCHAR = 0x0107,
+ WM_KEYLAST = 0x0108,
+ //
+ // Scrolling
+ //
+ WM_HSCROLL = 0x0114,
+ WM_VSCROLL = 0x0115,
+
+ //
+ // IME - International Text
+ //
+ 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,
+
+ // MWF Custom msgs
+ //
+ WM_MOUSE_ENTER = 0x0401,
+ }
+ }
+}
+
diff --git a/source/ShiftUI/Design/ParentControlDesigner.cs b/source/ShiftUI/Design/ParentControlDesigner.cs
new file mode 100644
index 0000000..0e906e7
--- /dev/null
+++ b/source/ShiftUI/Design/ParentControlDesigner.cs
@@ -0,0 +1,726 @@
+//
+// ShiftUI.Design.ParentWidgetDesigner
+//
+// Authors:
+// Ivan N. Zlatev (contact i-nZ.net)
+//
+// (C) 2006 Ivan N. Zlatev
+
+//
+// Permission is hereby granted, free of charge, to any person obtaining
+// a copy of this software and associated documentation files (the
+// "Software"), to deal in the Software without restriction, including
+// without limitation the rights to use, copy, modify, merge, publish,
+// distribute, sublicense, and/or sell copies of the Software, and to
+// permit persons to whom the Software is furnished to do so, subject to
+// the following conditions:
+//
+// The above copyright notice and this permission notice shall be
+// included in all copies or substantial portions of the Software.
+//
+// THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND,
+// EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF
+// MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND
+// NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE
+// LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION
+// OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION
+// WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
+//
+
+using System;
+using System.ComponentModel;
+using System.ComponentModel.Design;
+using ShiftUI;
+using System.Drawing;
+using System.Drawing.Drawing2D;
+using System.Drawing.Design;
+using System.Collections;
+using ShiftUI.Design.Behavior;
+
+namespace ShiftUI.Design
+
+{
+
+ public class ParentWidgetDesigner : WidgetDesigner
+ {
+
+ public ParentWidgetDesigner ()
+ {
+ }
+
+
+#region Initialization
+ // Settings paths taken from the example at:
+ // http://msdn2.microsoft.com/en-us/library/system.componentmodel.design.idesigneroptionservice.aspx
+ //
+ public override void Initialize (IComponent component)
+ {
+ base.Initialize (component);
+
+ this.Widget.AllowDrop = true;
+
+ // Initialize the default values of the Design-Time properties.
+ //
+ _defaultDrawGrid = true;
+ _defaultSnapToGrid = true;
+ _defaultGridSize = new Size (8, 8);
+
+ // If the parent Widget of the designed one has a ParentDesigner then inherit the values
+ // from it's designer.
+ //
+ if (this.Widget.Parent != null) {
+ ParentWidgetDesigner parentDesigner = GetParentWidgetDesignerOf (Widget.Parent);
+ if (parentDesigner != null) {
+ _defaultDrawGrid = (bool) GetValue (parentDesigner.Component, "DrawGrid");
+ _defaultSnapToGrid = (bool) GetValue (parentDesigner.Component, "SnapToGrid");
+ _defaultGridSize = (Size) GetValue (parentDesigner.Component, "GridSize");
+ }
+ }
+ else {
+ // Else retrieve them through the IDesignerOptionService (if available)
+ //
+ IDesignerOptionService options = GetService (typeof (IDesignerOptionService)) as
+ IDesignerOptionService;
+ if (options != null) {
+ object value = null;
+ value = options.GetOptionValue (@"WindowsFormsDesigner\General", "DrawGrid");
+ if (value is bool)
+ _defaultDrawGrid = (bool) value;
+
+ value = options.GetOptionValue (@"WindowsFormsDesigner\General", "SnapToGrid");
+ if (value is bool)
+ _defaultSnapToGrid = (bool) value;
+
+ value = options.GetOptionValue (@"WindowsFormsDesigner\General", "GridSize");
+ if (value is Size)
+ _defaultGridSize = (Size) value;
+ }
+ }
+
+ IComponentChangeService componentChangeSvc = GetService (typeof (IComponentChangeService)) as IComponentChangeService;
+ if (componentChangeSvc != null) {
+ componentChangeSvc.ComponentRemoving += new ComponentEventHandler (OnComponentRemoving);
+ componentChangeSvc.ComponentRemoved += new ComponentEventHandler (OnComponentRemoved);
+ }
+
+ // At the end set whatever we've managed to get
+ //
+ _drawGrid = _defaultDrawGrid;
+ _snapToGrid = _defaultSnapToGrid;
+ _gridSize = _defaultGridSize;
+ }
+
+ protected override void Dispose (bool disposing)
+ {
+ if (disposing) {
+ EnableDragDrop (false);
+ OnMouseDragEnd (true);
+ }
+ base.Dispose (disposing);
+ }
+#endregion
+
+
+#region IToolboxService Related
+
+ // This is the code that is executed when you drop a tool from the Toolbox in the designer.
+ //
+
+ protected static void InvokeCreateTool (ParentWidgetDesigner toInvoke, ToolboxItem tool)
+ {
+ if (toInvoke != null)
+ toInvoke.CreateTool (tool);
+ }
+
+ protected void CreateTool (ToolboxItem tool)
+ {
+ CreateToolCore (tool, DefaultWidgetLocation.X, DefaultWidgetLocation.Y, 0, 0, true, false);
+ }
+
+ protected void CreateTool (ToolboxItem tool, Point location)
+ {
+ CreateToolCore (tool, location.X, location.Y, 0, 0, true, false);
+ }
+
+ protected void CreateTool (ToolboxItem tool, Rectangle bounds)
+ {
+ CreateToolCore (tool, bounds.X, bounds.Y, bounds.Width, bounds.Width, true, true);
+ }
+
+ // Creates a component from a ToolboxItem, sets its location and size if available and snaps it's
+ // location to the grid.
+ //
+ protected virtual IComponent[] CreateToolCore (ToolboxItem tool, int x, int y, int width, int height,
+ bool hasLocation, bool hasSize)
+ {
+ if (tool == null)
+ throw new ArgumentNullException ("tool");
+
+ IDesignerHost host = GetService (typeof (IDesignerHost)) as IDesignerHost;
+ DesignerTransaction transaction = host.CreateTransaction ("Create components in tool '" + tool.DisplayName + "'");
+ IComponent[] components = tool.CreateComponents (host);
+
+ foreach (IComponent component in components)
+ {
+ WidgetDesigner controlDesigner = host.GetDesigner (component) as WidgetDesigner;
+ if (controlDesigner == null) { // not a Widget, but e.g. a plain Component
+ continue;
+ } else if (!this.CanParent (controlDesigner)) {
+ host.DestroyComponent (component);
+ continue;
+ }
+
+ Widget control = component as Widget;
+ if (control != null) {
+ this.Widget.SuspendLayout ();
+ // set parent instead of controls.Add so that it gets serialized for Undo/Redo
+ TypeDescriptor.GetProperties (control)["Parent"].SetValue (control, this.Widget);
+ this.Widget.SuspendLayout ();
+
+ if (hasLocation)
+ base.SetValue (component, "Location", this.SnapPointToGrid (new Point (x, y)));
+ else
+ base.SetValue (component, "Location", this.SnapPointToGrid (this.DefaultWidgetLocation));
+
+ if (hasSize)
+ base.SetValue (component, "Size", new Size (width, height));
+
+ this.Widget.Refresh ();
+ }
+ }
+ ISelectionService selectionServ = this.GetService (typeof (ISelectionService)) as ISelectionService;
+ if (selectionServ != null)
+ selectionServ.SetSelectedComponents (components, SelectionTypes.Replace);
+ transaction.Commit ();
+ return components;
+ }
+
+#endregion
+
+
+#region Drag and Drop
+
+ // If the control is not already parented return true
+ //
+ public virtual bool CanParent (Widget control)
+ {
+ if (control != null)
+ return !control.Contains (this.Widget);
+
+ return false;
+ }
+
+ public virtual bool CanParent (WidgetDesigner designer)
+ {
+ return CanParent (designer.Widget);
+ }
+
+ protected override void OnDragDrop (DragEventArgs e)
+ {
+ IUISelectionService selectionServ = this.GetService (typeof (IUISelectionService)) as IUISelectionService;
+ if (selectionServ != null) {
+ // once this is fired the parent control (parentcontroldesigner) will start getting dragover events.
+ //
+ Point location = this.SnapPointToGrid (this.Widget.PointToClient (new Point (e.X, e.Y)));
+ selectionServ.DragDrop (false, this.Widget, location.X, location.Y);
+ }
+ }
+
+ protected override void OnDragEnter (DragEventArgs e)
+ {
+ this.Widget.Refresh ();
+ }
+
+ protected override void OnDragLeave (EventArgs e)
+ {
+ this.Widget.Refresh ();
+ }
+
+ protected override void OnDragOver (DragEventArgs e)
+ {
+ IUISelectionService selectionServ = this.GetService (typeof (IUISelectionService)) as IUISelectionService;
+ if (selectionServ != null) {
+ // once WidgetDesigner.MouseDragBegin is called this will start getting dragover events.
+ //
+ Point location = this.SnapPointToGrid (this.Widget.PointToClient (new Point (e.X, e.Y)));
+ selectionServ.DragOver (this.Widget, location.X, location.Y);
+ }
+ e.Effect = DragDropEffects.Move;
+ }
+#endregion
+
+
+#region Properties
+ // The default location where a control is placed, when added to the designer
+ //
+ protected virtual Point DefaultWidgetLocation {
+ get { return new Point (0, 0); }
+ }
+
+
+ protected override bool EnableDragRect {
+ get { return true; }
+ }
+#endregion
+
+#region ComponentChange
+
+ private void OnComponentRemoving (object sender, ComponentEventArgs args)
+ {
+ IComponentChangeService componentChangeSvc = GetService (typeof (IComponentChangeService)) as IComponentChangeService;
+ Widget control = args.Component as Widget;
+ if (control != null && control.Parent == this.Widget && componentChangeSvc != null)
+ componentChangeSvc.OnComponentChanging (args.Component, TypeDescriptor.GetProperties (args.Component)["Parent"]);
+ }
+
+ private void OnComponentRemoved (object sender, ComponentEventArgs args)
+ {
+ IComponentChangeService componentChangeSvc = GetService (typeof (IComponentChangeService)) as IComponentChangeService;
+ Widget control = args.Component as Widget;
+ if (control != null && control.Parent == this.Widget && componentChangeSvc != null) {
+ control.Parent = null;
+ componentChangeSvc.OnComponentChanged (args.Component,
+ TypeDescriptor.GetProperties (args.Component)["Parent"],
+ this.Widget, null);
+ }
+ }
+#endregion
+
+#region Design-Time Properties
+
+ private bool _defaultDrawGrid;
+ private bool _defaultSnapToGrid;
+ private Size _defaultGridSize;
+ private bool _drawGrid;
+ private bool _snapToGrid;
+ private Size _gridSize;
+
+ //This method adds the following design-time browsable properties:
+ // "DrawGrid", "SnapToGrid", and "GridSize".
+ //
+ protected override void PreFilterProperties (IDictionary properties)
+ {
+ base.PreFilterProperties (properties);
+
+ properties["DrawGrid"] = TypeDescriptor.CreateProperty (typeof (ParentWidgetDesigner),
+ "DrawGrid",
+ typeof (bool),
+ new Attribute[] {
+ BrowsableAttribute.Yes,
+ DesignOnlyAttribute.Yes,
+ new DescriptionAttribute (
+ "Indicates whether or not to draw the positioning grid."),
+ CategoryAttribute.Design
+ });
+
+ properties["SnapToGrid"] = TypeDescriptor.CreateProperty (typeof (ParentWidgetDesigner),
+ "SnapToGrid",
+ typeof (bool),
+ new Attribute[] {
+ BrowsableAttribute.Yes,
+ DesignOnlyAttribute.Yes,
+ new DescriptionAttribute (
+ "Determines if controls should snap to the positioning grid."),
+ CategoryAttribute.Design
+ });
+
+ properties["GridSize"] = TypeDescriptor.CreateProperty (typeof (ParentWidgetDesigner),
+ "GridSize",
+ typeof (Size),
+ new Attribute[] {
+ BrowsableAttribute.Yes,
+ DesignOnlyAttribute.Yes,
+ new DescriptionAttribute (
+ "Determines the size of the positioning grid."),
+ CategoryAttribute.Design
+ });
+
+ }
+
+
+ // Informs all children controls' ParentWidgetDesigners that the grid properties
+ // have changed and passes them
+ //
+ private void PopulateGridProperties ()
+ {
+ // Widget.Invalidate (true) will redraw the control and it's children
+ // this will cause a WM_PAINT message to be send and the WidgetDesigenr will raise
+ // the OnPaintAdornments, where the grid drawing takes place.
+ //
+ // Note that this should be called *after* the grid properties have changed :-)
+ //
+ this.Widget.Invalidate (false);
+
+ if (this.Widget != null) {
+ ParentWidgetDesigner designer = null;
+ foreach (Widget control in this.Widget.Widgets) {
+ designer = this.GetParentWidgetDesignerOf (control);
+ if (designer != null)
+ designer.OnParentGridPropertiesChanged (this);
+ }
+ }
+ }
+
+ // Called by the parent ParentWidgetDesigner when it is populating the grid-related
+ // design-time properties changes
+ //
+ private void OnParentGridPropertiesChanged (ParentWidgetDesigner parentDesigner)
+ {
+ SetValue (this.Component, "DrawGrid", (bool) GetValue (parentDesigner.Component, "DrawGrid"));
+ SetValue (this.Component, "SnapToGrid", (bool) GetValue (parentDesigner.Component, "SnapToGrid"));
+ SetValue (this.Component, "GridSize", (Size) GetValue (parentDesigner.Component, "GridSize"));
+
+ // Set also the default values to be those, because we should
+ // match the parent ParentWidgetDesigner values.
+ // called recursivly, so I will rather go for slower, but no stack-overflowable code
+ //
+ _defaultDrawGrid = (bool) GetValue (parentDesigner.Component, "DrawGrid");
+ _defaultSnapToGrid = (bool) GetValue (parentDesigner.Component, "SnapToGrid");
+ _defaultGridSize = (Size) GetValue (parentDesigner.Component, "GridSize");
+
+ this.PopulateGridProperties ();
+ }
+
+
+ // Retrieves the ParentWidgetDesigner of the specified control if available,
+ // else returns null.
+ //
+ private ParentWidgetDesigner GetParentWidgetDesignerOf (Widget control)
+ {
+ if (control != null) {
+ IDesignerHost designerHost = GetService (typeof (IDesignerHost)) as IDesignerHost;
+ if (designerHost != null) {
+ ParentWidgetDesigner designer = null;
+ designer = designerHost.GetDesigner (this.Widget.Parent) as ParentWidgetDesigner;
+ if (designer != null)
+ return designer;
+ }
+ }
+ return null;
+ }
+
+ protected virtual bool DrawGrid {
+ get { return _drawGrid; }
+ set {
+ _drawGrid = value;
+
+ if (value == false)
+ SetValue (this.Component, "SnapToGrid", false);
+
+ PopulateGridProperties ();
+ }
+ }
+
+ private bool SnapToGrid {
+ get { return _snapToGrid; }
+ set {
+ _snapToGrid = value;
+ PopulateGridProperties ();
+ }
+ }
+
+ protected Size GridSize {
+ get { return _gridSize; }
+ set {
+ _gridSize = value;
+ PopulateGridProperties ();
+ }
+ }
+
+ // http://msdn.microsoft.com/library/default.asp?url=/library/en-us/cpguide/html/cpconshouldpersistresetmethods.asp
+ //
+ // The ShouldSerializerPROPERTYNAME determines whether a property has changed from
+ // the default value and should get serialized.
+ //
+ // The ResetPROPERTYNAME resets the property to it's default value (used when
+ // one right clicks on a property in the property grid and clicks on "Reset".
+ //
+
+ private bool ShouldSerializeDrawGrid ()
+ {
+ return DrawGrid != _defaultDrawGrid;
+ }
+
+ private void ResetDrawGrid ()
+ {
+ this.DrawGrid = _defaultDrawGrid;
+ }
+
+ private bool ShouldSerializeSnapToGrid ()
+ {
+ return _drawGrid != _defaultDrawGrid;
+ }
+
+ private void ResetSnapToGrid ()
+ {
+ this.SnapToGrid = _defaultSnapToGrid;
+ }
+
+ private bool ShouldSerializeGridSize ()
+ {
+ return GridSize != _defaultGridSize;
+ }
+
+ private void ResetGridSize ()
+ {
+ this.GridSize = _defaultGridSize;
+ }
+#endregion
+
+
+#region Design-Time Mouse Drag and Drop
+ protected override void OnMouseDragBegin (int x, int y)
+ {
+ // do not call base here because the behaviour is specific for the WidgetDesgner (does IUISelectionService.DragBegin)
+ //
+
+ IUISelectionService selectionServ = this.GetService (typeof (IUISelectionService)) as IUISelectionService;
+ if (selectionServ != null) {
+ // once WidgetDesigner.MouseDragBegin is fired this will start getting dragover events.
+ //
+ Point location = new Point (x, y);
+ IDesignerHost host = GetService (typeof (IDesignerHost)) as IDesignerHost;
+ if (base.MouseButtonDown == MouseButtons.Middle && host != null && host.RootComponent != this.Widget) {
+ location = this.Widget.Parent.PointToClient (this.Widget.PointToScreen (new Point (x, y)));
+ // I have to do this, because I get DragOver events fired for the control I am actually dragging
+ //
+ this.Widget.AllowDrop = false;
+ selectionServ.DragBegin ();
+ }
+ else {
+ selectionServ.MouseDragBegin (this.Widget, location.X, location.Y);
+ }
+ }
+ }
+
+ protected override void OnMouseDragMove (int x, int y)
+ {
+ IUISelectionService selectionServ = this.GetService (typeof (IUISelectionService)) as IUISelectionService;
+ if (selectionServ != null) {
+ Point location = new Point (x, y);
+ if (!selectionServ.SelectionInProgress)
+ location = this.SnapPointToGrid (new Point (x, y));
+
+ selectionServ.MouseDragMove (location.X, location.Y);
+ }
+ }
+
+ protected override void OnMouseDragEnd (bool cancel)
+ {
+ IUISelectionService selectionServ = this.GetService (typeof (IUISelectionService)) as IUISelectionService;
+ if (selectionServ != null) {
+ // If there is a Toolbox component seleted then create it instead of finishing the selection
+ IToolboxService toolBoxService = this.GetService (typeof (IToolboxService)) as IToolboxService;
+ if (!cancel && toolBoxService != null && toolBoxService.GetSelectedToolboxItem () != null) {
+ if (selectionServ.SelectionInProgress) {
+ bool hasSize = selectionServ.SelectionBounds.Width > 0 &&
+ selectionServ.SelectionBounds.Height > 0;
+ CreateToolCore (toolBoxService.GetSelectedToolboxItem (),
+ selectionServ.SelectionBounds.X,
+ selectionServ.SelectionBounds.Y,
+ selectionServ.SelectionBounds.Width,
+ selectionServ.SelectionBounds.Height,
+ true, hasSize);
+ toolBoxService.SelectedToolboxItemUsed ();
+ cancel = true;
+ } else if (!selectionServ.SelectionInProgress &&
+ !selectionServ.ResizeInProgress && !selectionServ.DragDropInProgress){
+ CreateTool (toolBoxService.GetSelectedToolboxItem (), _mouseDownPoint);
+ toolBoxService.SelectedToolboxItemUsed ();
+ cancel = true;
+ }
+ }
+
+ if (selectionServ.SelectionInProgress || selectionServ.ResizeInProgress)
+ selectionServ.MouseDragEnd (cancel);
+ }
+ }
+
+ protected override void OnDragComplete (DragEventArgs de)
+ {
+ base.OnDragComplete (de);
+ }
+
+ Point _mouseDownPoint = Point.Empty;
+
+ internal override void OnMouseDown (int x, int y)
+ {
+ _mouseDownPoint.X = x;
+ _mouseDownPoint.Y = y;
+ base.OnMouseDown (x, y);
+ }
+
+ internal override void OnMouseUp ()
+ {
+ base.OnMouseUp ();
+ if (!this.Widget.AllowDrop) // check MouseDragBegin for the reason of having this
+ this.Widget.AllowDrop = true;
+ _mouseDownPoint = Point.Empty;
+ }
+
+ internal override void OnMouseMove (int x, int y)
+ {
+ IUISelectionService uiSelection = this.GetService (typeof (IUISelectionService)) as IUISelectionService;
+ if (uiSelection != null)
+ uiSelection.SetCursor (x, y);
+
+ base.OnMouseMove (x, y);
+ }
+
+ // Align the point to the grid
+ //
+ private Point SnapPointToGrid (Point location)
+ {
+ Rectangle gridSurface = this.Widget.Bounds;
+ Size gridSize = (Size)GetValue (this.Component, "GridSize");
+
+ if ((bool)GetValue (this.Component, "SnapToGrid")) {
+ int x = location.X + (gridSize.Width - (location.X % gridSize.Width));
+ if (x > gridSurface.Width)
+ x = gridSurface.Width - gridSize.Width;
+
+ location.X = x;
+
+ int y = location.Y + (gridSize.Height - (location.Y % gridSize.Height));
+ if (y > gridSurface.Height)
+ y = gridSurface.Height - gridSize.Height;
+
+ location.Y = y;
+ }
+ return location;
+ }
+
+#endregion
+
+
+ #region WndProc and Misc Message Handlers
+
+ protected override void OnSetCursor ()
+ {
+ if (this.Widget != null) {
+ IToolboxService tbService = GetService (typeof (IToolboxService)) as IToolboxService;
+ if (tbService != null)
+ tbService.SetCursor ();
+ else
+ base.OnSetCursor ();
+ }
+ }
+
+ // Draws the design-time grid if DrawGrid == true
+ //
+ protected override void OnPaintAdornments (PaintEventArgs pe)
+ {
+ base.OnPaintAdornments (pe);
+
+ bool drawGrid;
+ Size gridSize;
+
+ // in case WM_PAINT is received before the IDesignerFilter is invoked to add
+ // those properties.
+ try {
+ drawGrid = (bool)GetValue (this.Component, "DrawGrid");
+ } catch {
+ drawGrid = this.DrawGrid;
+ }
+ try {
+ gridSize = (Size)GetValue (this.Component, "GridSize");
+ } catch {
+ gridSize = this.GridSize;
+ }
+
+ if (drawGrid) {
+ GraphicsState state = pe.Graphics.Save ();
+ pe.Graphics.TranslateTransform (this.Widget.ClientRectangle.X,
+ this.Widget.ClientRectangle.Y);
+ WidgetPaint.DrawGrid (pe.Graphics, this.Widget.ClientRectangle, gridSize, this.Widget.BackColor);
+ pe.Graphics.Restore (state);
+ }
+
+ IUISelectionService selection = this.GetService (typeof (IUISelectionService)) as IUISelectionService;
+ if (selection != null)
+ selection.PaintAdornments (this.Widget, pe.Graphics);
+ }
+
+#endregion
+
+
+ protected Widget GetWidget (object component)
+ {
+ IComponent comp = component as IComponent;
+
+ if (comp != null && comp.Site != null) {
+ IDesignerHost host = comp.Site.GetService (typeof (IDesignerHost)) as IDesignerHost;
+ if (host != null) {
+ WidgetDesigner designer = host.GetDesigner (comp) as WidgetDesigner;
+ if (designer != null)
+ return designer.Widget;
+ }
+ }
+ return null;
+ }
+
+#region NET_2_0 Stubs
+ [MonoTODO]
+ protected virtual bool AllowWidgetLasso {
+ get { return false; }
+ }
+
+ [MonoTODO]
+ protected virtual bool AllowGenericDragBox {
+ get { return false; }
+ }
+
+ [MonoTODO]
+ protected internal virtual bool AllowSetChildIndexOnDrop {
+ get { return false; }
+ }
+
+ [MonoTODO]
+ public override IList SnapLines {
+ get { return new object [0]; }
+ }
+
+ [MonoTODO]
+ protected ToolboxItem MouseDragTool {
+ get { return null; }
+ }
+
+ [MonoTODO]
+ public override void InitializeNewComponent (IDictionary defaultValues)
+ {
+ base.InitializeNewComponent (defaultValues);
+ }
+
+ [MonoTODO]
+ protected void AddPaddingSnapLines (ref ArrayList snapLines)
+ {
+ throw new NotImplementedException ();
+ }
+
+ [MonoTODO]
+ protected virtual Widget GetParentForComponent (IComponent component)
+ {
+ throw new NotImplementedException ();
+ }
+
+ [MonoTODO]
+ protected override WidgetBodyGlyph GetWidgetGlyph (GlyphSelectionType selectionType)
+ {
+ return base.GetWidgetGlyph (selectionType);
+ }
+
+ [MonoTODO]
+ public override GlyphCollection GetGlyphs (GlyphSelectionType selectionType)
+ {
+ return base.GetGlyphs (selectionType);
+ }
+
+ [MonoTODO]
+ protected Rectangle GetUpdatedRect (Rectangle originalRect, Rectangle dragRect, bool updateSize)
+ {
+ throw new NotImplementedException ();
+ }
+#endregion
+
+ }
+}
diff --git a/source/ShiftUI/Design/PropertyTab.cs b/source/ShiftUI/Design/PropertyTab.cs
new file mode 100644
index 0000000..bb40e11
--- /dev/null
+++ b/source/ShiftUI/Design/PropertyTab.cs
@@ -0,0 +1,102 @@
+// Permission is hereby granted, free of charge, to any person obtaining
+// a copy of this software and associated documentation files (the
+// "Software"), to deal in the Software without restriction, including
+// without limitation the rights to use, copy, modify, merge, publish,
+// distribute, sublicense, and/or sell copies of the Software, and to
+// permit persons to whom the Software is furnished to do so, subject to
+// the following conditions:
+//
+// The above copyright notice and this permission notice shall be
+// included in all copies or substantial portions of the Software.
+//
+// THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND,
+// EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF
+// MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND
+// NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE
+// LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION
+// OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION
+// WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
+//
+// Copyright (c) 2004 Novell, Inc.
+//
+// Authors: Marek Safar ([email protected])
+//
+
+// COMPLETE
+
+using System.Drawing;
+using System.ComponentModel;
+using System;
+
+namespace ShiftUI.Design
+{
+ public abstract class PropertyTab: IExtenderProvider
+ {
+ Bitmap bitmap;
+ object[] components;
+
+ protected PropertyTab () {}
+
+ ~PropertyTab ()
+ {
+ Dispose (false);
+ }
+
+ public virtual Bitmap Bitmap {
+ get {
+ if (bitmap == null) {
+ Type t = base.GetType();
+ bitmap = new Bitmap (t, t.Name + ".bmp");
+ }
+ return bitmap;
+ }
+ }
+
+ public virtual object[] Components {
+ get { return components; }
+ set { components = value; }
+ }
+
+ public virtual string HelpKeyword {
+ get { return TabName; }
+ }
+
+ public abstract string TabName { get; }
+
+ public virtual bool CanExtend (object extendee)
+ {
+ return true;
+ }
+
+ public virtual void Dispose()
+ {
+ Dispose (true);
+ GC.SuppressFinalize (this);
+ }
+
+ protected virtual void Dispose(bool disposing)
+ {
+ if (disposing && bitmap != null) {
+ bitmap.Dispose ();
+ bitmap = null;
+ }
+ }
+
+ public virtual PropertyDescriptor GetDefaultProperty (object component)
+ {
+ return TypeDescriptor.GetDefaultProperty(component);
+ }
+
+ public virtual PropertyDescriptorCollection GetProperties (object component)
+ {
+ return GetProperties (component, null);
+ }
+
+ public abstract PropertyDescriptorCollection GetProperties (object component, Attribute[] attributes);
+
+ public virtual PropertyDescriptorCollection GetProperties (ITypeDescriptorContext context, object component, Attribute[] attributes)
+ {
+ return GetProperties (component, attributes);
+ }
+ }
+}
diff --git a/source/ShiftUI/Design/ScrollableControlDesigner.cs b/source/ShiftUI/Design/ScrollableControlDesigner.cs
new file mode 100644
index 0000000..fb49f9a
--- /dev/null
+++ b/source/ShiftUI/Design/ScrollableControlDesigner.cs
@@ -0,0 +1,83 @@
+//
+// ShiftUI.Design.ScrollableWidgetDesigner
+//
+// Authors:
+// Ivan N. Zlatev (contact i-nZ.net)
+//
+// (C) 2006-2007 Ivan N. Zlatev
+
+//
+// Permission is hereby granted, free of charge, to any person obtaining
+// a copy of this software and associated documentation files (the
+// "Software"), to deal in the Software without restriction, including
+// without limitation the rights to use, copy, modify, merge, publish,
+// distribute, sublicense, and/or sell copies of the Software, and to
+// permit persons to whom the Software is furnished to do so, subject to
+// the following conditions:
+//
+// The above copyright notice and this permission notice shall be
+// included in all copies or substantial portions of the Software.
+//
+// THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND,
+// EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF
+// MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND
+// NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE
+// LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION
+// OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION
+// WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
+//
+
+
+using System;
+using System.ComponentModel;
+using System.ComponentModel.Design;
+using ShiftUI;
+using System.Drawing;
+using System.Drawing.Design;
+using System.Collections;
+
+
+
+namespace ShiftUI.Design
+{
+
+ public class ScrollableWidgetDesigner : ParentWidgetDesigner
+ {
+
+ public ScrollableWidgetDesigner ()
+ {
+ }
+
+ private const int HTHSCROLL = 6;
+ private const int HTVSCROLL = 7;
+
+ protected override bool GetHitTest (Point point)
+ {
+ if (base.GetHitTest (point)) {
+ return true;
+ }
+
+ // Check if the user has clicked on the scroll bars and forward the message to
+ // the ScrollableWidget. (Don't filter out the scrolling.). Keep in mind that scrollbars
+ // will be shown only if ScrollableWidget.AutoScroll = true
+ //
+ if (this.Widget is ScrollableWidget && ((ScrollableWidget)Widget).AutoScroll) {
+ int hitTestResult = (int) Native.SendMessage (this.Widget.Handle,
+ Native.Msg.WM_NCHITTEST,
+ IntPtr.Zero,
+ (IntPtr) Native.LParam (point.X, point.Y));
+ if (hitTestResult == HTHSCROLL || hitTestResult == HTVSCROLL)
+ return true;
+ }
+ return false;
+ }
+
+
+ protected override void WndProc (ref Message m)
+ {
+ base.WndProc (ref m);
+ if (m.Msg == (int)Native.Msg.WM_HSCROLL || m.Msg == (int)Native.Msg.WM_VSCROLL)
+ this.DefWndProc (ref m);
+ }
+ }
+}
diff --git a/source/ShiftUI/Design/SelectionFrame.cs b/source/ShiftUI/Design/SelectionFrame.cs
new file mode 100644
index 0000000..a3c092d
--- /dev/null
+++ b/source/ShiftUI/Design/SelectionFrame.cs
@@ -0,0 +1,481 @@
+//
+// ShiftUI.Design.SelectionFrame
+//
+// Authors:
+// Ivan N. Zlatev (contact i-nZ.net)
+//
+// (C) 2006-2007 Ivan N. Zlatev
+
+//
+// Permission is hereby granted, free of charge, to any person obtaining
+// a copy of this software and associated documentation files (the
+// "Software"), to deal in the Software without restriction, including
+// without limitation the rights to use, copy, modify, merge, publish,
+// distribute, sublicense, and/or sell copies of the Software, and to
+// permit persons to whom the Software is furnished to do so, subject to
+// the following conditions:
+//
+// The above copyright notice and this permission notice shall be
+// included in all copies or substantial portions of the Software.
+//
+// THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND,
+// EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF
+// MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND
+// NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE
+// LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION
+// OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION
+// WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
+//
+
+using System;
+using System.Collections;
+using System.ComponentModel;
+using System.ComponentModel.Design;
+using System.Drawing;
+using System.Drawing.Drawing2D;
+using ShiftUI;
+
+
+namespace ShiftUI.Design
+{
+ // This is not a control!
+ //
+ internal class SelectionFrame
+ {
+
+ public SelectionFrame (Widget control)
+ {
+ if (control == null)
+ throw new ArgumentNullException ("control");
+
+ _control = control;
+ }
+
+
+ private Rectangle _bounds;
+ private Widget _control;
+ private Rectangle[] _handles = new Rectangle[8];
+ private GrabHandle _handle = GrabHandle.None;
+ private const int BORDER_SIZE = 7;
+
+
+#region Properties
+ private enum GrabHandle {
+ None = -1,
+ TopLeft = 0,
+ TopMiddle,
+ TopRight,
+ Right,
+ BottomRight,
+ BottomMiddle,
+ BottomLeft,
+ Left,
+ Border // the border surrounding the control.
+ }
+
+ public Rectangle Bounds {
+ get {
+ _bounds.X = _control.Location.X - BORDER_SIZE;
+ _bounds.Y = _control.Location.Y - BORDER_SIZE;
+ _bounds.Width = _control.Width + BORDER_SIZE *2;
+ _bounds.Height = _control.Height + BORDER_SIZE *2;
+
+ return _bounds;
+ }
+ set {
+ _bounds = value;
+ _control.Bounds = _bounds;
+ }
+ }
+
+ private SelectionRules SelectionRules {
+ get {
+ SelectionRules result = SelectionRules.AllSizeable;
+
+ if (_control.Site != null) {
+ IDesignerHost host = _control.Site.GetService (typeof (IDesignerHost)) as IDesignerHost;
+ if (host != null) {
+ WidgetDesigner designer = host.GetDesigner (_control) as WidgetDesigner;
+ if (designer != null)
+ result = designer.SelectionRules;
+ }
+ }
+
+ return result;
+ }
+ }
+
+ public Widget Widget {
+ get { return _control; }
+ set {
+ if (value != null)
+ _control = value;
+ }
+ }
+
+ public Widget Parent {
+ get {
+ if (_control.Parent == null)
+ return _control;
+ else
+ return _control.Parent;
+ }
+ }
+
+ private GrabHandle GrabHandleSelected {
+ get { return _handle; }
+ set { _handle = value; }
+ }
+
+ private bool PrimarySelection{
+ get {
+ bool result = false;
+ if (this.Widget != null && this.Widget.Site != null) {
+ ISelectionService selection = this.Widget.Site.GetService (typeof (ISelectionService)) as ISelectionService;
+ if (selection != null && selection.PrimarySelection == this.Widget)
+ result = true;
+ }
+ return result;
+ }
+ }
+#endregion
+
+
+#region Drawing
+ public void OnPaint (Graphics gfx)
+ {
+ DrawFrame (gfx);
+ DrawGrabHandles (gfx);
+ }
+
+ private void DrawGrabHandles (Graphics gfx)
+ {
+ GraphicsState state = gfx.Save();
+ gfx.TranslateTransform (this.Bounds.X, this.Bounds.Y);
+
+ for (int i = 0; i < _handles.Length; i++) {
+ _handles[i].Width = BORDER_SIZE;
+ _handles[i].Height = BORDER_SIZE;
+ }
+
+ SelectionRules rules = this.SelectionRules;
+ bool primarySelection = this.PrimarySelection;
+ bool enabled = false;
+
+ _handles[(int) GrabHandle.TopLeft].Location = new Point (0,0);
+ if (this.CheckSelectionRules (rules, SelectionRules.TopSizeable | SelectionRules.LeftSizeable))
+ enabled = true;
+
+ WidgetPaint.DrawGrabHandle (gfx, _handles[(int)GrabHandle.TopLeft], primarySelection, enabled);
+ enabled = false;
+
+ _handles[(int) GrabHandle.TopMiddle].Location = new Point ((this.Bounds.Width - BORDER_SIZE) / 2, 0);
+ if (this.CheckSelectionRules (rules, SelectionRules.TopSizeable))
+ enabled = true;
+
+ WidgetPaint.DrawGrabHandle (gfx, _handles[(int)GrabHandle.TopMiddle], primarySelection, enabled);
+ enabled = false;
+
+ _handles[(int) GrabHandle.TopRight].Location = new Point (this.Bounds.Width - BORDER_SIZE, 0);
+ if (this.CheckSelectionRules (rules, SelectionRules.TopSizeable | SelectionRules.RightSizeable))
+ enabled = true;
+
+ WidgetPaint.DrawGrabHandle (gfx, _handles[(int)GrabHandle.TopRight], primarySelection, enabled);
+ enabled = false;
+
+ _handles[(int) GrabHandle.Right].Location = new Point (this.Bounds.Width - BORDER_SIZE,
+ (this.Bounds.Height - BORDER_SIZE) / 2);
+ if (this.CheckSelectionRules (rules, SelectionRules.RightSizeable))
+ enabled = true;
+
+ WidgetPaint.DrawGrabHandle (gfx, _handles[(int)GrabHandle.Right], primarySelection, enabled);
+ enabled = false;
+
+ _handles[(int) GrabHandle.BottomRight].Location = new Point (this.Bounds.Width - BORDER_SIZE,
+ this.Bounds.Height - BORDER_SIZE);
+ if (this.CheckSelectionRules (rules, SelectionRules.BottomSizeable | SelectionRules.RightSizeable))
+ enabled = true;
+
+ WidgetPaint.DrawGrabHandle (gfx, _handles[(int)GrabHandle.BottomRight], primarySelection, enabled);
+ enabled = false;
+
+ _handles[(int) GrabHandle.BottomMiddle].Location = new Point ((this.Bounds.Width - BORDER_SIZE) / 2,
+ this.Bounds.Height - BORDER_SIZE);
+ if (this.CheckSelectionRules (rules, SelectionRules.BottomSizeable))
+ enabled = true;
+
+ WidgetPaint.DrawGrabHandle (gfx, _handles[(int)GrabHandle.BottomMiddle], primarySelection, enabled);
+ enabled = false;
+
+ _handles[(int) GrabHandle.BottomLeft].Location = new Point (0, this.Bounds.Height - BORDER_SIZE);
+ if (this.CheckSelectionRules (rules, SelectionRules.BottomSizeable | SelectionRules.LeftSizeable))
+ enabled = true;
+
+ WidgetPaint.DrawGrabHandle (gfx, _handles[(int)GrabHandle.BottomLeft], primarySelection, enabled);
+ enabled = false;
+
+ _handles[(int) GrabHandle.Left].Location = new Point (0, (this.Bounds.Height - BORDER_SIZE) / 2);
+ if (this.CheckSelectionRules (rules, SelectionRules.LeftSizeable))
+ enabled = true;
+
+ WidgetPaint.DrawGrabHandle (gfx, _handles[(int)GrabHandle.Left], primarySelection, enabled);
+ gfx.Restore (state);
+ }
+
+ protected void DrawFrame (Graphics gfx)
+ {
+ Color negativeColor = Color.FromArgb ((byte)~(_control.Parent.BackColor.R),
+ (byte)~(_control.Parent.BackColor.G),
+ (byte)~(_control.Parent.BackColor.B));
+ Pen pen = new Pen (new HatchBrush (HatchStyle.Percent30, negativeColor, Color.FromArgb (0)), BORDER_SIZE);
+ gfx.DrawRectangle (pen, this.Widget.Bounds);
+ }
+#endregion
+
+
+#region Dragging
+ private bool _resizing = false;
+
+
+ public bool SetCursor (int x, int y)
+ {
+ bool modified = false;
+
+ if (!_resizing) {
+ GrabHandle handle = PointToGrabHandle (this.PointToClient (Widget.MousePosition));
+ if (handle != GrabHandle.None)
+ modified = true;
+
+ if (handle == GrabHandle.TopLeft)
+ Cursor.Current = Cursors.SizeNWSE;
+ else if (handle == GrabHandle.TopMiddle)
+ Cursor.Current = Cursors.SizeNS;
+ else if (handle == GrabHandle.TopRight)
+ Cursor.Current = Cursors.SizeNESW;
+ else if (handle == GrabHandle.Right)
+ Cursor.Current = Cursors.SizeWE;
+ else if (handle == GrabHandle.BottomRight)
+ Cursor.Current = Cursors.SizeNWSE;
+ else if (handle == GrabHandle.BottomMiddle)
+ Cursor.Current = Cursors.SizeNS;
+ else if (handle == GrabHandle.BottomLeft)
+ Cursor.Current = Cursors.SizeNESW;
+ else if (handle == GrabHandle.Left)
+ Cursor.Current = Cursors.SizeWE;
+ else
+ Cursor.Current = Cursors.Default;
+ }
+ return modified;
+ }
+
+ // container coordinates
+ public void ResizeBegin (int x, int y)
+ {
+ this.GrabHandleSelected = PointToGrabHandle (this.PointToClient (this.Parent.PointToScreen (new Point (x, y))));
+
+ if (this.GrabHandleSelected != GrabHandle.None)
+ _resizing = true;
+ }
+
+ private bool CheckSelectionRules (SelectionRules rules, SelectionRules toCheck)
+ {
+ return ((rules & toCheck) == toCheck);
+ }
+
+ // container coordinates returns deltaBounds
+ public Rectangle ResizeContinue (int x, int y)
+ {
+ //Console.WriteLine ("ResizeContinue: " + x + " : " + y);
+ //Console.WriteLine ("GrabHandleSelected: " + GrabHandleSelected);
+
+ Rectangle bounds = (Rectangle)TypeDescriptor.GetProperties (_control)["Bounds"].GetValue (_control);
+ Rectangle deltaBounds = bounds;
+ Point pointerLocation = new Point (x, y);
+ SelectionRules rules = this.SelectionRules;
+ int top, height, left, width = 0;
+
+ if (_resizing && this.GrabHandleSelected != GrabHandle.None && rules != SelectionRules.Locked) {
+ if (this.GrabHandleSelected == GrabHandle.TopLeft &&
+ CheckSelectionRules (rules, SelectionRules.LeftSizeable | SelectionRules.TopSizeable)) {
+
+ top = _control.Top;
+ height = _control.Height;
+ left = _control.Left;
+ width = _control.Width;
+
+ if (pointerLocation.Y < _control.Bottom) {
+ top = pointerLocation.Y;
+ height = _control.Bottom - pointerLocation.Y;
+ }
+ if (pointerLocation.X < _control.Right) {
+ left = pointerLocation.X;
+ width = _control.Right - pointerLocation.X;
+ bounds = new Rectangle (left, top, width, height);
+ }
+ }
+ else if (this.GrabHandleSelected == GrabHandle.TopRight &&
+ CheckSelectionRules (rules, SelectionRules.TopSizeable | SelectionRules.RightSizeable)) {
+
+ top = _control.Top;
+ height = _control.Height;
+ width = _control.Width;
+
+ if (pointerLocation.Y < _control.Bottom) {
+ top = pointerLocation.Y;
+ height = _control.Bottom - pointerLocation.Y;
+ }
+ width = pointerLocation.X - _control.Left;
+ bounds = new Rectangle (_control.Left, top, width, height);
+ }
+ else if (GrabHandleSelected == GrabHandle.TopMiddle && CheckSelectionRules (rules, SelectionRules.TopSizeable)) {
+ if (pointerLocation.Y < _control.Bottom) {
+ top = pointerLocation.Y;
+ height = _control.Bottom - pointerLocation.Y;
+ bounds = new Rectangle (_control.Left, top, _control.Width, height);
+ }
+ }
+ else if (this.GrabHandleSelected == GrabHandle.Right && CheckSelectionRules (rules, SelectionRules.RightSizeable)) {
+ width = pointerLocation.X - _control.Left;
+ bounds = new Rectangle (_control.Left, _control.Top, width, _control.Height);
+ }
+ else if (this.GrabHandleSelected == GrabHandle.BottomRight &&
+ CheckSelectionRules (rules, SelectionRules.BottomSizeable | SelectionRules.RightSizeable)) {
+
+ width = pointerLocation.X - _control.Left;
+ height = pointerLocation.Y - _control.Top;
+ bounds = new Rectangle (_control.Left, _control.Top, width, height);
+ }
+ else if (GrabHandleSelected == GrabHandle.BottomMiddle && CheckSelectionRules (rules, SelectionRules.BottomSizeable)) {
+ height = pointerLocation.Y - _control.Top;
+ bounds = new Rectangle (_control.Left, _control.Top, _control.Width, height);
+ }
+ else if (GrabHandleSelected == GrabHandle.BottomLeft &&
+ CheckSelectionRules (rules, SelectionRules.BottomSizeable | SelectionRules.LeftSizeable)) {
+
+ height = _control.Height;
+ left = _control.Left;
+ width = _control.Width;
+
+ if (pointerLocation.X < _control.Right) {
+ left = pointerLocation.X;
+ width = _control.Right - pointerLocation.X;
+ }
+ height = pointerLocation.Y - _control.Top;
+ bounds = new Rectangle (left, _control.Top, width, height);
+ }
+ else if (GrabHandleSelected == GrabHandle.Left && CheckSelectionRules (rules, SelectionRules.LeftSizeable)) {
+ if (pointerLocation.X < _control.Right) {
+ left = pointerLocation.X;
+ width = _control.Right - pointerLocation.X;
+ bounds = new Rectangle (left, _control.Top, width, _control.Height);
+ }
+ }
+
+ //Console.WriteLine ("bounds: " + bounds.ToString ());
+ TypeDescriptor.GetProperties (_control)["Bounds"].SetValue (_control, bounds);
+
+ }
+
+ this.Parent.Refresh ();
+ deltaBounds.X = bounds.X - deltaBounds.X;
+ deltaBounds.Y = bounds.Y - deltaBounds.Y;
+ deltaBounds.Height = bounds.Height - deltaBounds.Height;
+ deltaBounds.Width = bounds.Width - deltaBounds.Width;
+ return deltaBounds;
+ }
+
+
+ public void ResizeEnd (bool cancel)
+ {
+ this.GrabHandleSelected = GrabHandle.None;
+ _resizing = false;
+ }
+
+ public void Resize (Rectangle deltaBounds)
+ {
+ SelectionRules rules = this.SelectionRules;
+
+ if (this.CheckSelectionRules (rules, SelectionRules.Locked) || !this.CheckSelectionRules (rules, SelectionRules.Moveable))
+ return;
+
+ Rectangle bounds = (Rectangle)TypeDescriptor.GetProperties (_control)["Bounds"].GetValue (_control);
+
+ if (CheckSelectionRules (rules, SelectionRules.LeftSizeable)) {
+ bounds.X += deltaBounds.X;
+ bounds.Width += deltaBounds.Width;
+ }
+ if (CheckSelectionRules (rules, SelectionRules.RightSizeable) && !CheckSelectionRules (rules, SelectionRules.LeftSizeable)) {
+ bounds.Y += deltaBounds.Y;
+ bounds.Width += deltaBounds.Width;
+ }
+ if (CheckSelectionRules (rules, SelectionRules.TopSizeable)) {
+ bounds.Y += deltaBounds.Y;
+ bounds.Height += deltaBounds.Height;
+ }
+ if (CheckSelectionRules (rules, SelectionRules.BottomSizeable) && !CheckSelectionRules (rules, SelectionRules.TopSizeable)) {
+ bounds.Height += deltaBounds.Height;
+ }
+
+ TypeDescriptor.GetProperties (_control)["Bounds"].SetValue (_control, bounds);
+ }
+#endregion
+
+
+#region Utility methods
+
+ public bool HitTest (int x, int y)
+ {
+ if (PointToGrabHandle (this.PointToClient (this.Parent.PointToScreen (new Point (x, y)))) != GrabHandle.None)
+ return true;
+ else
+ return false;
+ }
+
+ private GrabHandle PointToGrabHandle (Point pointerLocation)
+ {
+ GrabHandle result = GrabHandle.None;
+
+ if (IsCursorOnGrabHandle (pointerLocation, _handles[0]))
+ result = GrabHandle.TopLeft;
+ else if (IsCursorOnGrabHandle (pointerLocation, _handles[1]))
+ result = GrabHandle.TopMiddle;
+ else if (IsCursorOnGrabHandle (pointerLocation, _handles[2]))
+ result = GrabHandle.TopRight;
+ else if (IsCursorOnGrabHandle (pointerLocation, _handles[3]))
+ result = GrabHandle.Right;
+ else if (IsCursorOnGrabHandle (pointerLocation, _handles[4]))
+ result = GrabHandle.BottomRight;
+ else if (IsCursorOnGrabHandle (pointerLocation, _handles[5]))
+ result = GrabHandle.BottomMiddle;
+ else if (IsCursorOnGrabHandle (pointerLocation, _handles[6]))
+ result = GrabHandle.BottomLeft;
+ else if (IsCursorOnGrabHandle (pointerLocation, _handles[7]))
+ result = GrabHandle.Left;
+ else
+ result = GrabHandle.None;
+
+ return result;
+ }
+
+ private bool IsCursorOnGrabHandle (Point pointerLocation, Rectangle handleRectangle)
+ {
+ if (pointerLocation.X >= handleRectangle.X &&
+ pointerLocation.X <= handleRectangle.X + handleRectangle.Width &&
+ pointerLocation.Y >= handleRectangle.Y &&
+ pointerLocation.Y <= handleRectangle.Y + handleRectangle.Height) {
+ return true;
+ }
+ return false;
+ }
+
+ private Point PointToClient (Point screenPoint)
+ {
+ Point pointerLocation = this.Parent.PointToClient (screenPoint);
+ pointerLocation.X = pointerLocation.X - this.Bounds.X;
+ pointerLocation.Y = pointerLocation.Y - this.Bounds.Y;
+ return pointerLocation;
+ }
+#endregion
+
+ }
+}
diff --git a/source/ShiftUI/Design/SelectionRules.cs b/source/ShiftUI/Design/SelectionRules.cs
new file mode 100644
index 0000000..84e5a41
--- /dev/null
+++ b/source/ShiftUI/Design/SelectionRules.cs
@@ -0,0 +1,47 @@
+//
+// ShiftUI.Design.SelectionRules.cs
+//
+// Author:
+// Gert Driesen ([email protected])
+// (C) 2004 Ximian, Inc. http://www.ximian.com
+//
+
+//
+// Permission is hereby granted, free of charge, to any person obtaining
+// a copy of this software and associated documentation files (the
+// "Software"), to deal in the Software without restriction, including
+// without limitation the rights to use, copy, modify, merge, publish,
+// distribute, sublicense, and/or sell copies of the Software, and to
+// permit persons to whom the Software is furnished to do so, subject to
+// the following conditions:
+//
+// The above copyright notice and this permission notice shall be
+// included in all copies or substantial portions of the Software.
+//
+// THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND,
+// EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF
+// MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND
+// NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE
+// LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION
+// OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION
+// WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
+//
+
+using System;
+
+namespace ShiftUI.Design
+{
+ [Flags]
+ public enum SelectionRules
+ {
+ AllSizeable = 15,
+ BottomSizeable = 2,
+ LeftSizeable = 4,
+ Locked = -2147483648,
+ Moveable = 268435456,
+ None = 0,
+ RightSizeable = 8,
+ TopSizeable = 1,
+ Visible = 1073741824
+ }
+}
diff --git a/source/ShiftUI/Design/ToolStripItemDesignerAvailability.cs b/source/ShiftUI/Design/ToolStripItemDesignerAvailability.cs
new file mode 100644
index 0000000..5452d15
--- /dev/null
+++ b/source/ShiftUI/Design/ToolStripItemDesignerAvailability.cs
@@ -0,0 +1,43 @@
+//
+// ToolStripItemDesignerAvailability.cs
+//
+// Permission is hereby granted, free of charge, to any person obtaining
+// a copy of this software and associated documentation files (the
+// "Software"), to deal in the Software without restriction, including
+// without limitation the rights to use, copy, modify, merge, publish,
+// distribute, sublicense, and/or sell copies of the Software, and to
+// permit persons to whom the Software is furnished to do so, subject to
+// the following conditions:
+//
+// The above copyright notice and this permission notice shall be
+// included in all copies or substantial portions of the Software.
+//
+// THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND,
+// EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF
+// MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND
+// NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE
+// LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION
+// OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION
+// WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
+//
+// Copyright (c) Jonathan Pobst
+//
+// Authors:
+// Jonathan Pobst ([email protected])
+//
+
+using System;
+
+namespace ShiftUI.Design
+{
+ [Flags]
+ public enum ToolStripItemDesignerAvailability
+ {
+ None = 0,
+ ToolStrip = 1,
+ MenuStrip = 2,
+ ContextMenuStrip = 4,
+ StatusStrip = 8,
+ All = 15
+ }
+}
diff --git a/source/ShiftUI/Design/ToolStripItemDesignerAvailabilityAttribute.cs b/source/ShiftUI/Design/ToolStripItemDesignerAvailabilityAttribute.cs
new file mode 100644
index 0000000..f5ca759
--- /dev/null
+++ b/source/ShiftUI/Design/ToolStripItemDesignerAvailabilityAttribute.cs
@@ -0,0 +1,81 @@
+//
+// ToolStripItemDesignerAvailabilityAttribute.cs
+//
+// Permission is hereby granted, free of charge, to any person obtaining
+// a copy of this software and associated documentation files (the
+// "Software"), to deal in the Software without restriction, including
+// without limitation the rights to use, copy, modify, merge, publish,
+// distribute, sublicense, and/or sell copies of the Software, and to
+// permit persons to whom the Software is furnished to do so, subject to
+// the following conditions:
+//
+// The above copyright notice and this permission notice shall be
+// included in all copies or substantial portions of the Software.
+//
+// THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND,
+// EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF
+// MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND
+// NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE
+// LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION
+// OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION
+// WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
+//
+// Copyright (c) Jonathan Pobst
+//
+// Authors:
+// Jonathan Pobst ([email protected])
+//
+
+using System;
+using System.Collections.Generic;
+using System.Text;
+
+namespace ShiftUI.Design
+{
+ [AttributeUsage (AttributeTargets.Class)]
+ public sealed class ToolStripItemDesignerAvailabilityAttribute : Attribute
+ {
+ private ToolStripItemDesignerAvailability visibility;
+ public static readonly ToolStripItemDesignerAvailabilityAttribute Default = new ToolStripItemDesignerAvailabilityAttribute ();
+
+ #region Public Constructors
+ public ToolStripItemDesignerAvailabilityAttribute ()
+ : base ()
+ {
+ this.visibility = ToolStripItemDesignerAvailability.None;
+ }
+
+ public ToolStripItemDesignerAvailabilityAttribute (ToolStripItemDesignerAvailability visibility)
+ : base ()
+ {
+ this.visibility = visibility;
+ }
+ #endregion
+
+ #region Public Properties
+ public ToolStripItemDesignerAvailability ItemAdditionVisibility {
+ get { return this.visibility; }
+ }
+ #endregion
+
+ #region Public Methods
+ public override bool Equals (object obj)
+ {
+ if (!(obj is ToolStripItemDesignerAvailabilityAttribute))
+ return false;
+
+ return this.ItemAdditionVisibility == (obj as ToolStripItemDesignerAvailabilityAttribute).ItemAdditionVisibility;
+ }
+
+ public override int GetHashCode ()
+ {
+ return (int)this.visibility;
+ }
+
+ public override bool IsDefaultAttribute ()
+ {
+ return this.visibility == ToolStripItemDesignerAvailability.None;
+ }
+ #endregion
+ }
+}
diff --git a/source/ShiftUI/Design/UISelectionService.cs b/source/ShiftUI/Design/UISelectionService.cs
new file mode 100644
index 0000000..78a722b
--- /dev/null
+++ b/source/ShiftUI/Design/UISelectionService.cs
@@ -0,0 +1,532 @@
+//
+// ShiftUI.Design.UISelectionService
+//
+// Authors:
+// Ivan N. Zlatev (contact i-nZ.net)
+//
+// (C) 2007 Ivan N. Zlatev
+
+//
+// Permission is hereby granted, free of charge, to any person obtaining
+// a copy of this software and associated documentation files (the
+// "Software"), to deal in the Software without restriction, including
+// without limitation the rights to use, copy, modify, merge, publish,
+// distribute, sublicense, and/or sell copies of the Software, and to
+// permit persons to whom the Software is furnished to do so, subject to
+// the following conditions:
+//
+// The above copyright notice and this permission notice shall be
+// included in all copies or substantial portions of the Software.
+//
+// THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND,
+// EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF
+// MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND
+// NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE
+// LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION
+// OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION
+// WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
+//
+
+using System;
+using System.Collections;
+using System.ComponentModel;
+using System.ComponentModel.Design;
+using System.Drawing;
+using System.Drawing.Drawing2D;
+using ShiftUI;
+
+namespace ShiftUI.Design
+{
+
+ internal class UISelectionService : IUISelectionService
+ {
+
+ private IServiceProvider _serviceProvider;
+ private DesignerTransaction _transaction;
+ private ISelectionService _selectionService;
+
+ public UISelectionService (IServiceProvider serviceProvider)
+ {
+ if (serviceProvider == null)
+ throw new ArgumentNullException ("serviceProvider");
+
+ _serviceProvider = serviceProvider;
+ _transaction = null;
+
+ _selectionService = serviceProvider.GetService (typeof (ISelectionService)) as ISelectionService;
+ if (_selectionService == null) {
+ IServiceContainer serviceContainer = serviceProvider.GetService (typeof (IServiceContainer)) as IServiceContainer;
+ _selectionService = new UISelectionService (serviceContainer) as ISelectionService;
+ serviceContainer.AddService (typeof (ISelectionService), (ISelectionService) _selectionService);
+ }
+
+ _selectionService.SelectionChanged += new EventHandler (OnSelectionChanged);
+ }
+
+ private ISelectionService SelectionService {
+ get { return _selectionService; }
+ }
+
+ private object GetService (Type service)
+ {
+ return _serviceProvider.GetService (service);
+ }
+
+ public bool SelectionInProgress {
+ get { return _selecting; }
+ }
+
+ public bool DragDropInProgress {
+ get { return _dragging; }
+ }
+
+ public bool ResizeInProgress{
+ get { return _resizing; }
+ }
+
+
+ public bool SetCursor (int x, int y)
+ {
+ bool modified = false;
+ // if moving mouse around - set cursor if mouse is hovering a selectionframes' grabhandles
+ //
+ SelectionFrame frame = GetSelectionFrameAt (x, y);
+ if (frame != null && frame.HitTest (x, y) && frame.SetCursor (x, y))
+ modified = true;
+
+ return modified;
+ }
+
+
+ public void MouseDragBegin (Widget container, int x, int y)
+ {
+ // * start resizing the selection frame
+ // * start selecting
+ //
+ SelectionFrame frame = GetSelectionFrameAt (x, y);
+
+ if (frame != null && frame.HitTest (x, y)) {
+ this.SelectionService.SetSelectedComponents (new IComponent[] { frame.Widget });
+ if (_transaction == null) {
+ IDesignerHost host = this.GetService (typeof (IDesignerHost)) as IDesignerHost;
+ _transaction = host.CreateTransaction ("Resize " +
+ (this.SelectionService.SelectionCount == 1 ? ((IComponent)this.SelectionService.PrimarySelection).Site.Name : "controls"));
+ }
+ this.ResizeBegin (x, y);
+ }
+ else {
+ SelectionBegin (container, x, y);
+ }
+ }
+
+ public void MouseDragMove (int x, int y)
+ {
+ if (_selecting)
+ SelectionContinue (x, y);
+ else if (_resizing)
+ ResizeContinue (x, y);
+ }
+
+ public void MouseDragEnd (bool cancel)
+ {
+ if (_selecting)
+ SelectionEnd (cancel);
+ else if (_resizing) {
+ ResizeEnd (cancel);
+ if (_transaction != null) {
+ if (cancel)
+ _transaction.Cancel ();
+ else
+ _transaction.Commit ();
+ _transaction = null;
+ }
+ }
+
+ if (Cursor.Current != Cursors.Default)
+ Cursor.Current = Cursors.Default;
+ }
+
+
+#region Dragging
+ private bool _dragging = false;
+ private Point _prevMousePosition;
+ private bool _firstMove = false;
+
+ // container coordinates (primary selection's)
+ //
+ public void DragBegin ()
+ {
+ // Console.WriteLine ("DragBegin");
+ if (_transaction == null) {
+ IDesignerHost host = this.GetService (typeof (IDesignerHost)) as IDesignerHost;
+ _transaction = host.CreateTransaction ("Move " +
+ (this.SelectionService.SelectionCount == 1? ((IComponent)this.SelectionService.PrimarySelection).Site.Name : "controls"));
+ }
+ _dragging = true;
+ _firstMove = true;
+ if (this.SelectionService.PrimarySelection != null)
+ ((Widget)this.SelectionService.PrimarySelection).DoDragDrop (new WidgetDataObject ((Widget)this.SelectionService.PrimarySelection), DragDropEffects.All);
+ }
+
+ // container cordinates
+ //
+ public void DragOver (Widget container, int x, int y)
+ {
+ // Console.WriteLine ("DragOver");
+ if (_dragging) {
+ if (_firstMove) {
+ _prevMousePosition = new Point (x, y);
+ _firstMove = false;
+ }
+ else {
+ int dx = x - _prevMousePosition.X;
+ int dy = y - _prevMousePosition.Y;
+ MoveSelection (container, dx, dy);
+ _prevMousePosition = new Point (x, y);
+
+ // Repaint everything >_<
+ //
+ IDesignerHost host = this.GetService (typeof (IDesignerHost)) as IDesignerHost;
+ if (host != null && host.RootComponent != null)
+ ((Widget)host.RootComponent).Refresh ();
+ //container.Refresh ();
+ }
+ }
+ }
+
+ // container coordinates
+ //
+ public void DragDrop (bool cancel, Widget container, int x, int y)
+ {
+ // Console.WriteLine ("UISelectionService.DragDrop: in " + container.Site.Name);
+ if (_dragging) {
+ int dx = x - _prevMousePosition.X;
+ int dy = y - _prevMousePosition.Y;
+
+ MoveSelection (container, dx, dy);
+ _dragging = false;
+
+ // Repaint everything
+ //
+ IDesignerHost host = this.GetService (typeof (IDesignerHost)) as IDesignerHost;
+ if (host != null && host.RootComponent != null)
+ ((Widget)host.RootComponent).Refresh ();
+ // Send mouse up message to the primary selection
+ // Else for parentcontroldesigner there is no mouseup event and it doesn't set allow drop back to false
+ //
+ Native.SendMessage (((Widget)this.SelectionService.PrimarySelection).Handle, Native.Msg.WM_LBUTTONUP, (IntPtr) 0, (IntPtr) 0);
+ if (_transaction != null) {
+ if (cancel)
+ _transaction.Cancel ();
+ else
+ _transaction.Commit ();
+ _transaction = null;
+ }
+ }
+ }
+
+ private void MoveSelection (Widget container, int dx, int dy)
+ {
+ bool reparent = false;
+ Widget oldParent = null;
+
+ if (((Widget)this.SelectionService.PrimarySelection).Parent != container && !this.SelectionService.GetComponentSelected (container)) {
+ reparent = true;
+ oldParent = ((Widget)this.SelectionService.PrimarySelection).Parent;
+ }
+
+ // FIXME: Should check selectionstyle per control to determine if it's locked...
+ // if locked -> don't move
+ //
+ ICollection selection = this.SelectionService.GetSelectedComponents ();
+ foreach (Component component in selection) {
+ Widget control = component as Widget;
+ if (reparent)
+ TypeDescriptor.GetProperties (control)["Parent"].SetValue (control, container);
+
+ PropertyDescriptor property = TypeDescriptor.GetProperties (control)["Location"];
+ Point location = (Point) property.GetValue (control);
+ location.X += dx;
+ location.Y += dy;
+ property.SetValue (control, location);
+ }
+
+ if (reparent) {
+ oldParent.Invalidate (false);
+ oldParent.Update ();
+ }
+ }
+#endregion
+
+
+#region Selection
+
+ private bool _selecting = false;
+ private Widget _selectionContainer = null;
+ private Point _initialMousePosition;
+ private Rectangle _selectionRectangle;
+ // XXX
+ private ArrayList _selectionFrames = new ArrayList ();
+
+
+ public Rectangle SelectionBounds {
+ get { return _selectionRectangle; }
+ }
+
+ // container coordinates
+ //
+ private void SelectionBegin (Widget container, int x, int y)
+ {
+ // Console.WriteLine ("SelectionBegin");
+ _selecting = true;
+ _selectionContainer = container;
+ _prevMousePosition = new Point (x, y);
+ _initialMousePosition = _prevMousePosition;
+ _selectionRectangle = new Rectangle (x , y, 0, 0);
+ }
+
+ private void SelectionContinue (int x, int y)
+ {
+ // Console.WriteLine ("SelectionContinue");
+ if (_selecting) {
+ // right to right
+ //
+ if (x > _selectionRectangle.Right) {
+ _selectionRectangle.Width = x - _selectionRectangle.X;
+ }
+ // right to left
+ else if (x > _selectionRectangle.X && x < _selectionRectangle.Right &&
+ x < _prevMousePosition.X) {
+
+ _selectionRectangle.Width = x - _selectionRectangle.X;
+ }
+ // left to left - f
+ else if (x < _selectionRectangle.X) {
+
+ // hasn't flipped
+ if (_prevMousePosition.X > _selectionRectangle.X) {
+ _selectionRectangle.X = _initialMousePosition.X;
+ _selectionRectangle.Width = 0;
+ }
+ else {
+ _selectionRectangle.Width += _selectionRectangle.X - x;
+ _selectionRectangle.X = x;
+ }
+ }
+ // left to right - f
+ else if (x > _selectionRectangle.X && x < _selectionRectangle.Right &&
+ x > _prevMousePosition.X) {
+
+ if (_prevMousePosition.X < _selectionRectangle.X) {
+ _selectionRectangle.X = _initialMousePosition.X;
+ _selectionRectangle.Width = 0;
+ }
+ else {
+ _selectionRectangle.Width -= x - _selectionRectangle.X;
+ _selectionRectangle.X = x;
+ }
+ }
+
+
+ if (y > _selectionRectangle.Bottom) {
+ _selectionRectangle.Height = y - _selectionRectangle.Y;
+ }
+ else if (y > _selectionRectangle.Y && y < _selectionRectangle.Bottom &&
+ y < _prevMousePosition.Y) {
+
+ _selectionRectangle.Height = y - _selectionRectangle.Y;
+
+ }
+ else if (y < _selectionRectangle.Y) {
+ if (_prevMousePosition.Y > _selectionRectangle.Y) {
+ _selectionRectangle.Y = _initialMousePosition.Y;
+ _selectionRectangle.Height = 0;
+ }
+ else {
+ _selectionRectangle.Height += _selectionRectangle.Y - y;
+ _selectionRectangle.Y = y;
+ }
+ }
+ else if (y > _selectionRectangle.Y && y < _selectionRectangle.Bottom &&
+ y > _prevMousePosition.Y) {
+
+ if (_prevMousePosition.Y < _selectionRectangle.Y) {
+ _selectionRectangle.Y = _initialMousePosition.Y;
+ _selectionRectangle.Height = 0;
+ }
+ else {
+ _selectionRectangle.Height -= y - _selectionRectangle.Y;
+ _selectionRectangle.Y = y;
+ }
+ }
+
+ _prevMousePosition.X = x;
+ _prevMousePosition.Y = y;
+
+ _selectionContainer.Refresh ();
+ }
+ }
+
+ private void SelectionEnd (bool cancel)
+ {
+ // Console.WriteLine ("SelectionEnd");
+ _selecting = false;
+ ICollection selectedWidgets = GetWidgetsIn (_selectionRectangle);
+ // do not change selection if nothing has changed
+ //
+ if (selectedWidgets.Count != 0)
+ this.SelectionService.SetSelectedComponents (selectedWidgets, SelectionTypes.Replace);
+
+ _selectionContainer.Refresh ();
+ }
+#endregion
+
+
+#region Resizing
+ private SelectionFrame _selectionFrame;
+ private bool _resizing = false;
+
+ private void ResizeBegin (int x, int y)
+ {
+ // Console.WriteLine ("ResizeBegin");
+ _resizing = true;
+ _selectionFrame = this.GetSelectionFrameAt (x, y);
+ _selectionFrame.ResizeBegin (x, y);
+ }
+
+ private void ResizeContinue (int x, int y)
+ {
+ // Console.WriteLine ("ResizeContinue");
+ Rectangle deltaBounds = _selectionFrame.ResizeContinue (x, y);
+ ICollection selection = this.SelectionService.GetSelectedComponents ();
+
+ foreach (IComponent component in selection) {
+ if (component is Widget) {
+ SelectionFrame frame = GetSelectionFrameFor ((Widget)component);
+ if (frame != _selectionFrame)
+ frame.Resize (deltaBounds);
+ }
+ }
+
+ }
+
+ private void ResizeEnd (bool cancel)
+ {
+ // Console.WriteLine ("ResizeEnd");
+ _selectionFrame.ResizeEnd (cancel);
+ _resizing = false;
+ }
+
+
+ private SelectionFrame GetSelectionFrameAt (int x, int y)
+ {
+ SelectionFrame result = null;
+
+ foreach (SelectionFrame frame in _selectionFrames) {
+ if (frame.Bounds.Contains (new Point (x, y))) {
+ result = frame;
+ break;
+ }
+ }
+
+ return result;
+ }
+
+ private SelectionFrame GetSelectionFrameFor (Widget control)
+ {
+ foreach (SelectionFrame frame in _selectionFrames) {
+ if (control == frame.Widget)
+ return frame;
+ }
+ return null;
+ }
+#endregion
+
+ public bool AdornmentsHitTest (Widget control, int x, int y)
+ {
+ SelectionFrame frame = GetSelectionFrameAt (x, y);
+ if (frame != null)
+ return frame.HitTest (x, y);
+
+ return false;
+ }
+
+ // This method is called by all ParentWidgetDesigner.OnPaintAdornments.
+ // Selection frames are drawn in the parent container of the primary selection
+ // selection rectangle is drawn in the primary selection
+ //
+ public void PaintAdornments (Widget container, Graphics gfx)
+ {
+ IDesignerHost host = this.GetService (typeof (IDesignerHost)) as IDesignerHost;
+
+ if (host == null || !(this.SelectionService.PrimarySelection is Widget))
+ return;
+
+ if ((Widget)this.SelectionService.PrimarySelection == container) {
+ if (_selecting) {
+ Color negativeColor = Color.FromArgb ((byte)~(_selectionContainer.BackColor.R),
+ (byte)~(_selectionContainer.BackColor.G),
+ (byte)~(_selectionContainer.BackColor.B));
+ DrawSelectionRectangle (gfx, _selectionRectangle, negativeColor);
+ }
+ }
+ else if (((Widget)this.SelectionService.PrimarySelection).Parent == container) {
+ foreach (SelectionFrame frame in _selectionFrames)
+ frame.OnPaint (gfx);
+ }
+ }
+
+
+ private void DrawSelectionRectangle (Graphics gfx, Rectangle frame, Color color)
+ {
+ Pen pen = new Pen (color);
+ pen.DashStyle = DashStyle.Dash;
+ gfx.DrawRectangle (pen, frame);
+ }
+
+
+ private void OnSelectionChanged (object sender, EventArgs args)
+ {
+ ICollection selection = this.SelectionService.GetSelectedComponents ();
+
+ if (_selectionFrames.Count == 0) {
+ foreach (Component component in selection) {
+ _selectionFrames.Add (new SelectionFrame ((Widget) component));
+ } // this code should get executed only once! (when initial primary selection is set)
+ } else {
+ int i = 0;
+ foreach (Component component in selection) {
+ if (i >= _selectionFrames.Count)
+ _selectionFrames.Add (new SelectionFrame ((Widget) component));
+ else
+ ((SelectionFrame)_selectionFrames[i]).Widget = (Widget) component;
+ i++;
+ }
+ if (i < _selectionFrames.Count)
+ _selectionFrames.RemoveRange (i, _selectionFrames.Count - i);
+ }
+ // Refresh the whole design surface (including the view)
+ //
+ IDesignerHost host = this.GetService (typeof (IDesignerHost)) as IDesignerHost;
+ Widget root = host.RootComponent as Widget;
+ if (root != null) {
+ if (root.Parent != null)
+ root.Parent.Refresh ();
+ else
+ root.Refresh ();
+ }
+ }
+
+ private ICollection GetWidgetsIn (Rectangle rect)
+ {
+ ArrayList selectedWidgets = new ArrayList ();
+
+ foreach (Widget control in _selectionContainer.Widgets) {
+ if (rect.Contains (control.Bounds) || rect.IntersectsWith (control.Bounds))
+ selectedWidgets.Add (control);
+ }
+ return selectedWidgets;
+ }
+
+ }
+}
diff --git a/source/ShiftUI/Design/WindowsFormsComponentEditor.cs b/source/ShiftUI/Design/WindowsFormsComponentEditor.cs
new file mode 100644
index 0000000..9dbfc7a
--- /dev/null
+++ b/source/ShiftUI/Design/WindowsFormsComponentEditor.cs
@@ -0,0 +1,65 @@
+// Permission is hereby granted, free of charge, to any person obtaining
+// a copy of this software and associated documentation files (the
+// "Software"), to deal in the Software without restriction, including
+// without limitation the rights to use, copy, modify, merge, publish,
+// distribute, sublicense, and/or sell copies of the Software, and to
+// permit persons to whom the Software is furnished to do so, subject to
+// the following conditions:
+//
+// The above copyright notice and this permission notice shall be
+// included in all copies or substantial portions of the Software.
+//
+// THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND,
+// EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF
+// MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND
+// NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE
+// LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION
+// OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION
+// WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
+//
+// Copyright (c) 2004 Novell, Inc.
+//
+// Authors:
+// Andreas Nahr ([email protected])
+//
+
+using System.ComponentModel;
+using System;
+
+namespace ShiftUI.Design
+{
+ public abstract class WindowsFormsComponentEditor : ComponentEditor
+ {
+ protected WindowsFormsComponentEditor ()
+ {
+ }
+
+ public override bool EditComponent (ITypeDescriptorContext context, object component)
+ {
+ return EditComponent (context, component, null);
+ }
+
+ public virtual bool EditComponent (ITypeDescriptorContext context, object component, IWin32Window owner)
+ {
+ ComponentEditorForm f = new ComponentEditorForm (component, GetComponentEditorPages ());
+ if (f.ShowForm (owner, GetInitialComponentEditorPageIndex ()) == DialogResult.OK)
+ return true;
+ return false;
+ }
+
+ public bool EditComponent (object component, IWin32Window owner)
+ {
+ return EditComponent (null, component, owner);
+ }
+
+ protected virtual Type[] GetComponentEditorPages ()
+ {
+ return null;
+ }
+
+ protected virtual int GetInitialComponentEditorPageIndex ()
+ {
+ return 0;
+ }
+ }
+}
diff --git a/source/ShiftUI/Design/WndProcRouter.cs b/source/ShiftUI/Design/WndProcRouter.cs
new file mode 100644
index 0000000..83c3f1d
--- /dev/null
+++ b/source/ShiftUI/Design/WndProcRouter.cs
@@ -0,0 +1,117 @@
+//
+// ShiftUI.Design.WndProcRouter
+//
+// Authors:
+// Ivan N. Zlatev (contact i-nZ.net)
+//
+// (C) 2006-2007 Ivan N. Zlatev
+
+//
+// Permission is hereby granted, free of charge, to any person obtaining
+// a copy of this software and associated documentation files (the
+// "Software"), to deal in the Software without restriction, including
+// without limitation the rights to use, copy, modify, merge, publish,
+// distribute, sublicense, and/or sell copies of the Software, and to
+// permit persons to whom the Software is furnished to do so, subject to
+// the following conditions:
+//
+// The above copyright notice and this permission notice shall be
+// included in all copies or substantial portions of the Software.
+//
+// THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND,
+// EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF
+// MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND
+// NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE
+// LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION
+// OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION
+// WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
+//
+
+using System;
+using System.ComponentModel;
+using System.ComponentModel.Design;
+using ShiftUI;
+using System.Drawing;
+using System.Drawing.Design;
+using System.Collections;
+
+ // Automatically reroutes Messages to the designer
+ //
+
+namespace ShiftUI.Design
+{
+
+ internal class WndProcRouter : IWindowTarget, IDisposable
+ {
+ private IWindowTarget _oldTarget;
+ private IMessageReceiver _receiver;
+ private Widget _control;
+
+ public WndProcRouter (Widget control, IMessageReceiver receiver)
+ {
+ if (control == null)
+ throw new ArgumentNullException ("control");
+ if (receiver == null)
+ throw new ArgumentNullException ("receiver");
+
+ _oldTarget = control.WindowTarget;
+ _control = control;
+ _receiver = receiver;
+ }
+
+ public Widget Widget {
+ get { return _control; }
+ }
+
+ public IWindowTarget OldWindowTarget {
+ get { return _oldTarget; }
+ }
+
+ // Route the message to the control
+ //
+ public void ToWidget (ref Message m)
+ {
+ //Console.WriteLine ("Widget: " + ((Native.Msg)m.Msg).ToString ());
+ if (_oldTarget != null)
+ _oldTarget.OnMessage (ref m);
+ }
+
+ public void ToSystem (ref Message m)
+ {
+ //Console.WriteLine ("System: " + ((Native.Msg)m.Msg).ToString ());
+ Native.DefWndProc (ref m);
+ }
+
+ // Just pass it to the old IWindowTarget
+ //
+ void IWindowTarget.OnHandleChange (IntPtr newHandle)
+ {
+ if (_oldTarget != null)
+ _oldTarget.OnHandleChange (newHandle);
+ }
+
+ // Route the msg to the designer if available, else to
+ // control itself.
+ //
+ void IWindowTarget.OnMessage (ref Message m)
+ {
+ //Console.WriteLine ("Message: " + ((Native.Msg)m.Msg).ToString ());
+ if (_receiver != null)
+ _receiver.WndProc (ref m);
+ else
+ this.ToWidget (ref m);
+ }
+
+ // Disposes and puts back the old IWindowTarget
+ //
+ public void Dispose ()
+ {
+ if (_control != null)
+ _control.WindowTarget = _oldTarget;
+
+ _control = null;
+ _oldTarget = null;
+ }
+
+ }
+}