]> O.S.I.I.S - jp/crow.git/commitdiff
split graphic objects dir RearangeDirs
authorjpbruyere <jp.bruyere@hotmail.com>
Wed, 15 Mar 2017 04:59:51 +0000 (05:59 +0100)
committerjpbruyere <jp.bruyere@hotmail.com>
Wed, 15 Mar 2017 04:59:51 +0000 (05:59 +0100)
78 files changed:
Crow.csproj
src/GraphicObjects/Base/Border.cs [new file with mode: 0644]
src/GraphicObjects/Base/Button.cs [new file with mode: 0644]
src/GraphicObjects/Base/CheckBox.cs [new file with mode: 0644]
src/GraphicObjects/Base/ComboBox.cs [new file with mode: 0644]
src/GraphicObjects/Base/Container.cs [new file with mode: 0644]
src/GraphicObjects/Base/Expandable.cs [new file with mode: 0644]
src/GraphicObjects/Base/GenericStack.cs [new file with mode: 0644]
src/GraphicObjects/Base/GraphicObject.cs [new file with mode: 0644]
src/GraphicObjects/Base/Group.cs [new file with mode: 0644]
src/GraphicObjects/Base/GroupBox.cs [new file with mode: 0644]
src/GraphicObjects/Base/HorizontalStack.cs [new file with mode: 0644]
src/GraphicObjects/Base/Image.cs [new file with mode: 0644]
src/GraphicObjects/Base/Label.cs [new file with mode: 0644]
src/GraphicObjects/Base/ListBox.cs [new file with mode: 0644]
src/GraphicObjects/Base/Menu.cs [new file with mode: 0644]
src/GraphicObjects/Base/MenuItem.cs [new file with mode: 0644]
src/GraphicObjects/Base/MessageBox.cs [new file with mode: 0644]
src/GraphicObjects/Base/NumericControl.cs [new file with mode: 0644]
src/GraphicObjects/Base/Popper.cs [new file with mode: 0644]
src/GraphicObjects/Base/PrivateContainer.cs [new file with mode: 0644]
src/GraphicObjects/Base/ProgressBar.cs [new file with mode: 0644]
src/GraphicObjects/Base/RadioButton.cs [new file with mode: 0644]
src/GraphicObjects/Base/ScrollBar.cs [new file with mode: 0644]
src/GraphicObjects/Base/Scroller.cs [new file with mode: 0644]
src/GraphicObjects/Base/Slider.cs [new file with mode: 0644]
src/GraphicObjects/Base/Spinner.cs [new file with mode: 0644]
src/GraphicObjects/Base/Splitter.cs [new file with mode: 0644]
src/GraphicObjects/Base/TabItem.cs [new file with mode: 0644]
src/GraphicObjects/Base/TabView.cs [new file with mode: 0644]
src/GraphicObjects/Base/TemplatedContainer.cs [new file with mode: 0644]
src/GraphicObjects/Base/TemplatedControl.cs [new file with mode: 0644]
src/GraphicObjects/Base/TemplatedGroup.cs [new file with mode: 0644]
src/GraphicObjects/Base/TextBox.cs [new file with mode: 0644]
src/GraphicObjects/Base/TextRun.cs [new file with mode: 0644]
src/GraphicObjects/Base/TreeView.cs [new file with mode: 0644]
src/GraphicObjects/Base/VerticalStack.cs [new file with mode: 0644]
src/GraphicObjects/Base/Window.cs [new file with mode: 0644]
src/GraphicObjects/Base/Wrapper.cs [new file with mode: 0644]
src/GraphicObjects/Border.cs [deleted file]
src/GraphicObjects/Button.cs [deleted file]
src/GraphicObjects/CheckBox.cs [deleted file]
src/GraphicObjects/ComboBox.cs [deleted file]
src/GraphicObjects/Container.cs [deleted file]
src/GraphicObjects/Expandable.cs [deleted file]
src/GraphicObjects/GenericStack.cs [deleted file]
src/GraphicObjects/GraphicObject.cs [deleted file]
src/GraphicObjects/Group.cs [deleted file]
src/GraphicObjects/GroupBox.cs [deleted file]
src/GraphicObjects/HorizontalStack.cs [deleted file]
src/GraphicObjects/Image.cs [deleted file]
src/GraphicObjects/Label.cs [deleted file]
src/GraphicObjects/ListBox.cs [deleted file]
src/GraphicObjects/Menu.cs [deleted file]
src/GraphicObjects/MenuItem.cs [deleted file]
src/GraphicObjects/MessageBox.cs [deleted file]
src/GraphicObjects/NumericControl.cs [deleted file]
src/GraphicObjects/Popper.cs [deleted file]
src/GraphicObjects/PrivateContainer.cs [deleted file]
src/GraphicObjects/ProgressBar.cs [deleted file]
src/GraphicObjects/RadioButton.cs [deleted file]
src/GraphicObjects/ScrollBar.cs [deleted file]
src/GraphicObjects/Scroller.cs [deleted file]
src/GraphicObjects/Slider.cs [deleted file]
src/GraphicObjects/Spinner.cs [deleted file]
src/GraphicObjects/Splitter.cs [deleted file]
src/GraphicObjects/TabItem.cs [deleted file]
src/GraphicObjects/TabView.cs [deleted file]
src/GraphicObjects/TemplatedContainer.cs [deleted file]
src/GraphicObjects/TemplatedControl.cs [deleted file]
src/GraphicObjects/TemplatedGroup.cs [deleted file]
src/GraphicObjects/TextBox.cs [deleted file]
src/GraphicObjects/TextRun.cs [deleted file]
src/GraphicObjects/TreeView.cs [deleted file]
src/GraphicObjects/VerticalStack.cs [deleted file]
src/GraphicObjects/Window.cs [deleted file]
src/GraphicObjects/Wrapper.cs [deleted file]
src/Size.cs

index 20b38cf86c3aa7a8ae5408ada88f8b392fc06238..0b6f22f421b5f5b8e8c326e9e14d94e632513523 100644 (file)
     <Compile Include="src\Rectangle.cs" />
     <Compile Include="src\Rectangles.cs" />
     <Compile Include="src\Size.cs" />
-    <Compile Include="src\GraphicObjects\GraphicObject.cs" />
-    <Compile Include="src\GraphicObjects\Container.cs" />
-    <Compile Include="src\GraphicObjects\Group.cs" />
-    <Compile Include="src\GraphicObjects\HorizontalStack.cs" />
-    <Compile Include="src\GraphicObjects\Image.cs" />
-    <Compile Include="src\GraphicObjects\Label.cs" />
-    <Compile Include="src\GraphicObjects\TextBox.cs" />
-    <Compile Include="src\GraphicObjects\ProgressBar.cs" />
-    <Compile Include="src\GraphicObjects\VerticalStack.cs" />
     <Compile Include="src\Cairo\CairoHelpers.cs" />
     <Compile Include="src\win32\Win32.cs" />
     <Compile Include="src\win32\winApi.cs" />
-    <Compile Include="src\GraphicObjects\Button.cs" />
     <Compile Include="src\GraphicObjects\GraduatedSlider.cs" />
-    <Compile Include="src\GraphicObjects\Slider.cs" />
-    <Compile Include="src\GraphicObjects\NumericControl.cs" />
-    <Compile Include="src\GraphicObjects\Scroller.cs" />
     <Compile Include="src\GraphicObjects\ILayoutable.cs" />
     <Compile Include="src\Enums.cs" />
-    <Compile Include="src\GraphicObjects\GenericStack.cs" />
     <Compile Include="src\CompilerServices\CompilerServices.cs" />
     <Compile Include="src\GraphicObjects\AnalogMeter.cs" />
-    <Compile Include="src\GraphicObjects\Border.cs" />
     <Compile Include="src\Font.cs" />
-    <Compile Include="src\GraphicObjects\Window.cs" />
-    <Compile Include="src\GraphicObjects\ListBox.cs" />
     <Compile Include="src\ExtensionsMethods.cs" />
     <Compile Include="src\Interface.cs" />
     <Compile Include="src\LayoutingQueueItem.cs" />
-    <Compile Include="src\GraphicObjects\Spinner.cs" />
     <Compile Include="src\DynAttribute.cs" />
     <Compile Include="src\GraphicObjects\IValueChange.cs" />
     <Compile Include="src\Picture.cs" />
     <Compile Include="src\SvgPicture.cs" />
     <Compile Include="src\BmpPicture.cs" />
-    <Compile Include="src\GraphicObjects\TemplatedControl.cs" />
-    <Compile Include="src\GraphicObjects\RadioButton.cs" />
-    <Compile Include="src\GraphicObjects\Expandable.cs" />
-    <Compile Include="src\GraphicObjects\PrivateContainer.cs" />
-    <Compile Include="src\GraphicObjects\TemplatedContainer.cs" />
-    <Compile Include="src\GraphicObjects\Popper.cs" />
     <Compile Include="src\TextChangeEventArgs.cs" />
     <Compile Include="src\ReflexionExtensions.cs" />
     <Compile Include="src\XCursor.cs" />
     <Compile Include="src\GraphicObjects\Grid.cs" />
-    <Compile Include="src\GraphicObjects\TextRun.cs" />
-    <Compile Include="src\GraphicObjects\MessageBox.cs" />
     <Compile Include="src\SelectionChangeEventArgs.cs" />
     <Compile Include="src\ValueChangeEventArgs.cs" />
     <Compile Include="src\GraphicObjects\FileDialog.cs" />
-    <Compile Include="src\GraphicObjects\CheckBox.cs" />
-    <Compile Include="src\GraphicObjects\ComboBox.cs" />
-    <Compile Include="src\GraphicObjects\GroupBox.cs" />
-    <Compile Include="src\GraphicObjects\ScrollBar.cs" />
     <Compile Include="src\BubblingMouseButtonEventArgs.cs" />
     <Compile Include="src\SolidColor.cs" />
     <Compile Include="src\Gradient.cs" />
     <Compile Include="src\LayoutingEventArgs.cs" />
     <Compile Include="src\ScrollingEventArgs.cs" />
     <Compile Include="src\GraphicObjects\Trend.cs" />
-    <Compile Include="src\GraphicObjects\Splitter.cs" />
-    <Compile Include="src\GraphicObjects\TreeView.cs" />
-    <Compile Include="src\GraphicObjects\TabView.cs" />
-    <Compile Include="src\GraphicObjects\TabItem.cs" />
     <Compile Include="src\GraphicObjects\DummyTemplate.cs" />
     <Compile Include="src\Input\KeyboardKeyEventArgs.cs" />
     <Compile Include="src\Input\Buttons.cs" />
     <Compile Include="src\Instantiator.cs" />
     <Compile Include="src\ItemTemplate.cs" />
     <Compile Include="src\Style.cs" />
-    <Compile Include="src\GraphicObjects\Wrapper.cs" />
-    <Compile Include="src\GraphicObjects\TemplatedGroup.cs" />
-    <Compile Include="src\GraphicObjects\MenuItem.cs" />
-    <Compile Include="src\GraphicObjects\Menu.cs" />
     <Compile Include="src\Command.cs" />
     <Compile Include="src\GraphicObjects\DataSourceChangeEventArgs.cs" />
     <Compile Include="src\IML\Context.cs" />
     <Compile Include="src\PerformanceMeasure.cs" />
     <Compile Include="src\IML\BindingMember.cs" />
     <Compile Include="src\CrowThread.cs" />
+    <Compile Include="src\GraphicObjects\Base\Border.cs" />
+    <Compile Include="src\GraphicObjects\Base\Button.cs" />
+    <Compile Include="src\GraphicObjects\Base\CheckBox.cs" />
+    <Compile Include="src\GraphicObjects\Base\ComboBox.cs" />
+    <Compile Include="src\GraphicObjects\Base\Container.cs" />
+    <Compile Include="src\GraphicObjects\Base\Expandable.cs" />
+    <Compile Include="src\GraphicObjects\Base\GenericStack.cs" />
+    <Compile Include="src\GraphicObjects\Base\GraphicObject.cs" />
+    <Compile Include="src\GraphicObjects\Base\Group.cs" />
+    <Compile Include="src\GraphicObjects\Base\GroupBox.cs" />
+    <Compile Include="src\GraphicObjects\Base\HorizontalStack.cs" />
+    <Compile Include="src\GraphicObjects\Base\Image.cs" />
+    <Compile Include="src\GraphicObjects\Base\Label.cs" />
+    <Compile Include="src\GraphicObjects\Base\ListBox.cs" />
+    <Compile Include="src\GraphicObjects\Base\Menu.cs" />
+    <Compile Include="src\GraphicObjects\Base\MenuItem.cs" />
+    <Compile Include="src\GraphicObjects\Base\MessageBox.cs" />
+    <Compile Include="src\GraphicObjects\Base\NumericControl.cs" />
+    <Compile Include="src\GraphicObjects\Base\Popper.cs" />
+    <Compile Include="src\GraphicObjects\Base\PrivateContainer.cs" />
+    <Compile Include="src\GraphicObjects\Base\ProgressBar.cs" />
+    <Compile Include="src\GraphicObjects\Base\RadioButton.cs" />
+    <Compile Include="src\GraphicObjects\Base\ScrollBar.cs" />
+    <Compile Include="src\GraphicObjects\Base\Scroller.cs" />
+    <Compile Include="src\GraphicObjects\Base\Slider.cs" />
+    <Compile Include="src\GraphicObjects\Base\Spinner.cs" />
+    <Compile Include="src\GraphicObjects\Base\Splitter.cs" />
+    <Compile Include="src\GraphicObjects\Base\Wrapper.cs" />
+    <Compile Include="src\GraphicObjects\Base\Window.cs" />
+    <Compile Include="src\GraphicObjects\Base\VerticalStack.cs" />
+    <Compile Include="src\GraphicObjects\Base\TreeView.cs" />
+    <Compile Include="src\GraphicObjects\Base\TextBox.cs" />
+    <Compile Include="src\GraphicObjects\Base\TextRun.cs" />
+    <Compile Include="src\GraphicObjects\Base\TabItem.cs" />
+    <Compile Include="src\GraphicObjects\Base\TabView.cs" />
+    <Compile Include="src\GraphicObjects\Base\TemplatedContainer.cs" />
+    <Compile Include="src\GraphicObjects\Base\TemplatedControl.cs" />
+    <Compile Include="src\GraphicObjects\Base\TemplatedGroup.cs" />
   </ItemGroup>
   <ItemGroup>
     <Reference Include="System" />
     <Folder Include="src\rsvg\" />
     <Folder Include="src\IML\" />
     <Folder Include="Icons\" />
+    <Folder Include="src\GraphicObjects\Base\" />
   </ItemGroup>
   <ItemGroup>
     <EmbeddedResource Include="Images\Icons\updown.svg" />
diff --git a/src/GraphicObjects/Base/Border.cs b/src/GraphicObjects/Base/Border.cs
new file mode 100644 (file)
index 0000000..672d5ab
--- /dev/null
@@ -0,0 +1,100 @@
+//
+// Border.cs
+//
+// Author:
+//       Jean-Philippe Bruyère <jp.bruyere@hotmail.com>
+//
+// Copyright (c) 2013-2017 Jean-Philippe Bruyère
+//
+// 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.Xml.Serialization;
+using System.ComponentModel;
+using System.Diagnostics;
+
+namespace Crow
+{
+       public class Border : Container
+       {
+               #region CTOR
+               public Border () : base(){}
+               #endregion
+
+               #region private fields
+               int _borderWidth;
+               #endregion
+
+               #region public properties
+               [XmlAttributeAttribute()][DefaultValue(1)]
+               public virtual int BorderWidth {
+                       get { return _borderWidth; }
+                       set {
+                               _borderWidth = value;
+                               RegisterForGraphicUpdate ();
+                       }
+               }
+               #endregion
+
+               #region GraphicObject override
+               [XmlIgnore]public override Rectangle ClientRectangle {
+                       get {
+                               Rectangle cb = base.ClientRectangle;
+                               cb.Inflate (- BorderWidth);
+                               return cb;
+                       }
+               }
+
+               protected override int measureRawSize (LayoutingType lt)
+               {
+                       int tmp = base.measureRawSize (lt);
+                       return tmp < 0 ? tmp : tmp + 2 * BorderWidth;
+               }
+               protected override void onDraw (Cairo.Context gr)
+               {
+                       Rectangle rBack = new Rectangle (Slot.Size);
+
+                       //rBack.Inflate (-Margin);
+//                     if (BorderWidth > 0) 
+//                             rBack.Inflate (-BorderWidth / 2);                       
+
+                       Background.SetAsSource (gr, rBack);
+                       CairoHelpers.CairoRectangle(gr, rBack, CornerRadius);
+                       gr.Fill ();
+
+                       if (BorderWidth > 0) {                          
+                               Foreground.SetAsSource (gr, rBack);
+                               CairoHelpers.CairoRectangle(gr, rBack, CornerRadius, BorderWidth);
+                       }
+
+                       gr.Save ();
+                       if (ClipToClientRect) {
+                               //clip to client zone
+                               CairoHelpers.CairoRectangle (gr, ClientRectangle,Math.Max(0.0, CornerRadius-Margin));
+                               gr.Clip ();
+                       }
+
+                       if (child != null)
+                               child.Paint (ref gr);
+                       gr.Restore ();
+               }               
+               #endregion
+       }
+}
+
diff --git a/src/GraphicObjects/Base/Button.cs b/src/GraphicObjects/Base/Button.cs
new file mode 100644 (file)
index 0000000..75f4301
--- /dev/null
@@ -0,0 +1,124 @@
+//
+// Button.cs
+//
+// Author:
+//       Jean-Philippe Bruyère <jp.bruyere@hotmail.com>
+//
+// Copyright (c) 2013-2017 Jean-Philippe Bruyère
+//
+// 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.Generic;
+using System.Linq;
+using System.Text;
+//using OpenTK.Graphics.OpenGL;
+
+using System.Diagnostics;
+
+using System.Xml.Serialization;
+using Cairo;
+using System.ComponentModel;
+
+namespace Crow
+{
+    public class Button : TemplatedContainer
+    {
+               string image;
+               bool isPressed;
+               Container _contentContainer;
+
+               #region CTOR
+        public Button() : base()
+        {}
+               #endregion
+
+               public event EventHandler Pressed;
+               public event EventHandler Released;
+
+               #region TemplatedContainer overrides
+               public override GraphicObject Content {
+                       get {
+                               return _contentContainer == null ? null : _contentContainer.Child;
+                       }
+                       set {
+                               if (_contentContainer != null)
+                                       _contentContainer.SetChild(value);
+                       }
+               }
+               protected override void loadTemplate(GraphicObject template = null)
+               {
+                       base.loadTemplate (template);
+
+                       _contentContainer = this.child.FindByName ("Content") as Container;
+               }
+               #endregion
+
+               #region GraphicObject Overrides
+               public override void onMouseDown (object sender, MouseButtonEventArgs e)
+               {
+                       IsPressed = true;
+
+                       base.onMouseDown (sender, e);
+
+                       //TODO:remove
+                       NotifyValueChanged ("State", "pressed");
+               }
+               public override void onMouseUp (object sender, MouseButtonEventArgs e)
+               {
+                       IsPressed = false;
+
+                       base.onMouseUp (sender, e);
+
+                       //TODO:remove
+                       NotifyValueChanged ("State", "normal");
+               }
+               #endregion
+
+               [XmlAttributeAttribute][DefaultValue("#Crow.Images.button.svg")]
+               public string Image {
+                       get { return image; }
+                       set {
+                               if (image == value)
+                                       return;
+                               image = value;
+                               NotifyValueChanged ("Image", image);
+                       }
+               }
+               [XmlAttributeAttribute][DefaultValue(false)]
+               public bool IsPressed
+               {
+                       get { return isPressed; }
+                       set
+                       {
+                               if (isPressed == value)
+                                       return;
+
+                               isPressed = value;
+
+                               NotifyValueChanged ("IsPressed", isPressed);
+
+                               if (isPressed)
+                                       Pressed.Raise (this, null);
+                               else
+                                       Released.Raise (this, null);
+                       }
+               }
+       }
+}
diff --git a/src/GraphicObjects/Base/CheckBox.cs b/src/GraphicObjects/Base/CheckBox.cs
new file mode 100644 (file)
index 0000000..0a40d26
--- /dev/null
@@ -0,0 +1,71 @@
+//
+// CheckBox.cs
+//
+// Author:
+//       Jean-Philippe Bruyère <jp.bruyere@hotmail.com>
+//
+// Copyright (c) 2013-2017 Jean-Philippe Bruyère
+//
+// 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.Xml.Serialization;
+
+namespace Crow
+{
+       public class CheckBox : TemplatedControl
+       {
+               bool isChecked;
+
+               #region CTOR
+               public CheckBox() : base()
+               {}
+               #endregion
+
+               public event EventHandler Checked;
+               public event EventHandler Unchecked;
+
+               [XmlAttributeAttribute()][DefaultValue(false)]
+               public bool IsChecked
+               {
+                       get { return isChecked; }
+                       set
+                       {
+                               if (isChecked == value)
+                                       return;
+
+                               isChecked = value;
+
+                               NotifyValueChanged ("IsChecked", value);
+
+                               if (isChecked)
+                                       Checked.Raise (this, null);
+                               else
+                                       Unchecked.Raise (this, null);
+                       }
+               }
+
+               public override void onMouseClick (object sender, MouseButtonEventArgs e)
+               {
+                       IsChecked = !IsChecked;
+                       base.onMouseClick (sender, e);
+               }
+       }
+}
diff --git a/src/GraphicObjects/Base/ComboBox.cs b/src/GraphicObjects/Base/ComboBox.cs
new file mode 100644 (file)
index 0000000..15b49db
--- /dev/null
@@ -0,0 +1,55 @@
+//
+// ComboBox.cs
+//
+// Author:
+//       Jean-Philippe Bruyère <jp.bruyere@hotmail.com>
+//
+// Copyright (c) 2013-2017 Jean-Philippe Bruyère
+//
+// 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.Xml.Serialization;
+
+namespace Crow
+{
+       public class ComboBox : ListBox
+    {          
+               #region CTOR
+               public ComboBox() : base(){     }       
+               #endregion
+
+               Size minimumPopupSize = "10,10";
+               [XmlIgnore]public Size MinimumPopupSize{
+                       get { return minimumPopupSize; }
+                       set {
+                               minimumPopupSize = value;
+                               NotifyValueChanged ("MinimumPopupSize", minimumPopupSize);
+                       }
+               }
+
+               public override void OnLayoutChanges (LayoutingType layoutType)
+               {
+                       base.OnLayoutChanges (layoutType);
+
+                       if (layoutType == LayoutingType.Width)
+                               MinimumPopupSize = new Size (this.Slot.Width, minimumPopupSize.Height);                 
+               }
+       }
+}
diff --git a/src/GraphicObjects/Base/Container.cs b/src/GraphicObjects/Base/Container.cs
new file mode 100644 (file)
index 0000000..aac3594
--- /dev/null
@@ -0,0 +1,109 @@
+//
+// Container.cs
+//
+// Author:
+//       Jean-Philippe Bruyère <jp.bruyere@hotmail.com>
+//
+// Copyright (c) 2013-2017 Jean-Philippe Bruyère
+//
+// 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.Xml.Serialization;
+using System.Reflection;
+using System.ComponentModel;
+using System.Linq;
+using System.Threading;
+
+namespace Crow
+{
+    public class Container : PrivateContainer, IXmlSerializable
+    {
+               #region CTOR
+               public Container()
+                       : base()
+               {
+               }
+               #endregion
+
+               [XmlIgnore]
+               public GraphicObject Child {
+                       get { return child; }
+                       set { child = value; }
+               }
+               public virtual void SetChild(GraphicObject _child)
+               {
+                       base.SetChild (_child);
+               }
+
+               #region IXmlSerializable
+
+        public override System.Xml.Schema.XmlSchema GetSchema()
+        {
+            return null;
+        }
+        public override void ReadXml(System.Xml.XmlReader reader)
+        {
+                       //only read attributes in GraphicObject IXmlReader implementation
+            base.ReadXml(reader);
+
+
+            using (System.Xml.XmlReader subTree = reader.ReadSubtree())
+            {
+                subTree.Read(); //skip current node
+                subTree.Read(); //read first child
+
+                if (!subTree.IsStartElement())
+                    return;
+
+                Type t = Type.GetType("Crow." + subTree.Name);
+                               if (t == null) {
+                                       Assembly a = Assembly.GetEntryAssembly ();
+                                       foreach (Type expT in a.GetExportedTypes ()) {
+                                               if (expT.Name == subTree.Name) {
+                                                       t = expT;
+                                                       break;
+                                               }
+                                       }
+                               }
+                               GraphicObject go = (GraphicObject)Activator.CreateInstance(t);
+
+                               (go as IXmlSerializable).ReadXml(subTree);
+
+                               SetChild(go);
+
+                subTree.Read();//closing tag
+            }
+        }
+        public override void WriteXml(System.Xml.XmlWriter writer)
+        {
+            base.WriteXml(writer);
+
+            if (Child == null)
+                return;
+
+            writer.WriteStartElement(Child.GetType().Name);
+            (Child as IXmlSerializable).WriteXml(writer);
+            writer.WriteEndElement();
+        }
+    
+               #endregion
+       }
+}
+
diff --git a/src/GraphicObjects/Base/Expandable.cs b/src/GraphicObjects/Base/Expandable.cs
new file mode 100644 (file)
index 0000000..1cb3645
--- /dev/null
@@ -0,0 +1,141 @@
+//
+// Expandable.cs
+//
+// Author:
+//       Jean-Philippe Bruyère <jp.bruyere@hotmail.com>
+//
+// Copyright (c) 2013-2017 Jean-Philippe Bruyère
+//
+// 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.Xml.Serialization;
+
+namespace Crow
+{
+    public class Expandable : TemplatedContainer
+    {
+               #region CTOR
+               public Expandable() : base()
+               {
+               }
+               #endregion
+
+               #region Private fields
+               bool _isExpanded;
+               string image;
+               Container _contentContainer;
+               #endregion
+
+               #region Event Handlers
+               public event EventHandler Expand;
+               public event EventHandler Collapse;
+               #endregion
+
+               public BooleanTestOnInstance GetIsExpandable;
+
+               public void onClickForExpand (object sender, MouseButtonEventArgs e)
+               {
+                       IsExpanded = !IsExpanded;
+               }
+
+               public override GraphicObject Content {
+                       get {
+                               return _contentContainer == null ? null : _contentContainer.Child;
+                       }
+                       set {
+                               _contentContainer.SetChild(value);
+                               NotifyValueChanged ("HasContent", HasContent);
+                       }
+               }
+               //TODO: move loadTemplate and ResolveBinding in TemplatedContainer
+               protected override void loadTemplate(GraphicObject template = null)
+               {
+                       base.loadTemplate (template);
+
+                       _contentContainer = this.child.FindByName ("Content") as Container;
+               }
+
+               #region Public properties
+               [XmlAttributeAttribute][DefaultValue("#Crow.Images.Icons.expandable.svg")]
+               public string Image {
+                       get { return image; }
+                       set {
+                               if (image == value)
+                                       return;
+                               image = value;
+                               NotifyValueChanged ("Image", image);
+                       }
+               }
+               [XmlAttributeAttribute][DefaultValue(false)]
+        public bool IsExpanded
+        {
+                       get { return _isExpanded; }
+            set
+            {
+                               if (value == _isExpanded)
+                                       return;
+
+                               _isExpanded = value;
+
+                               bool isExp = IsExpandable;
+                               NotifyValueChanged ("IsExpandable", isExp);
+                               if (!(HasContent & isExp))
+                                       _isExpanded = false;
+
+                               NotifyValueChanged ("IsExpanded", _isExpanded);
+
+                               if (_isExpanded)
+                                       onExpand (this, null);
+                               else
+                                       onCollapse (this, null);
+            }
+        }
+               [XmlIgnore]public bool HasContent {
+                       get { return _contentContainer == null ? false : _contentContainer.Child != null; }
+               }
+               [XmlIgnore]public bool IsExpandable {
+                       get {
+                               try {
+                                       return GetIsExpandable == null ? true : GetIsExpandable (this);
+                               } catch (Exception ex) {
+                                       System.Diagnostics.Debug.WriteLine ("Not Expandable error: " + ex.ToString ());
+                                       return false;
+                               }
+                       }
+               }
+               #endregion
+
+               public virtual void onExpand(object sender, EventArgs e)
+               {
+                       if (_contentContainer != null)
+                               _contentContainer.Visible = true;
+
+                       Expand.Raise (this, e);
+               }
+               public virtual void onCollapse(object sender, EventArgs e)
+               {
+                       if (_contentContainer != null)
+                               _contentContainer.Visible = false;
+
+                       Collapse.Raise (this, e);
+               }
+       }
+}
diff --git a/src/GraphicObjects/Base/GenericStack.cs b/src/GraphicObjects/Base/GenericStack.cs
new file mode 100644 (file)
index 0000000..cecdaff
--- /dev/null
@@ -0,0 +1,228 @@
+//
+// GenericStack.cs
+//
+// Author:
+//       Jean-Philippe Bruyère <jp.bruyere@hotmail.com>
+//
+// Copyright (c) 2013-2017 Jean-Philippe Bruyère
+//
+// 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.ComponentModel;
+using System.Diagnostics;
+using System.Xml.Serialization;
+using System;
+
+namespace Crow
+{
+       public class GenericStack : Group
+    {
+               #region CTOR
+               public GenericStack()
+                       : base()
+               {            
+               }
+               #endregion
+
+               #region Private fields
+        int _spacing;
+        Orientation _orientation;
+               #endregion
+
+               #region Public Properties
+        [XmlAttributeAttribute()][DefaultValue(2)]
+        public int Spacing
+        {
+                       get { return _spacing; }
+            set { 
+                               if (_spacing == value)
+                                       return;
+                               _spacing = value; 
+                               NotifyValueChanged ("Spacing", Spacing);
+                               RegisterForLayouting (LayoutingType.Sizing|LayoutingType.ArrangeChildren);
+                       }
+        }
+        [XmlAttributeAttribute()][DefaultValue(Orientation.Horizontal)]
+        public virtual Orientation Orientation
+        {
+            get { return _orientation; }
+            set { _orientation = value; }
+        }
+               #endregion
+
+               #region GraphicObject Overrides
+               public override bool ArrangeChildren { get { return true; } }
+               public override void ChildrenLayoutingConstraints (ref LayoutingType layoutType)
+               {
+                       //Prevent child repositionning in the direction of stacking
+                       if (Orientation == Orientation.Horizontal)
+                               layoutType &= (~LayoutingType.X);
+                       else
+                               layoutType &= (~LayoutingType.Y);                       
+               }
+               protected override int measureRawSize (LayoutingType lt)
+               {
+                       int totSpace = 0;
+                       for (int i = 0; i < Children.Count; i++) {
+                               if (Children [i].Visible)
+                                       totSpace += Spacing;
+                       }
+                       if (totSpace > 0)
+                               totSpace -= Spacing;
+                       if (lt == LayoutingType.Width) {
+                               if (Orientation == Orientation.Horizontal)
+                                       return contentSize.Width + totSpace + 2 * Margin;
+                       }else if (Orientation == Orientation.Vertical)
+                               return contentSize.Height + totSpace + 2 * Margin;                                                      
+                       
+                       return base.measureRawSize (lt);
+               }
+               public virtual void ComputeChildrenPositions()
+               {
+                       int d = 0;
+                       if (Orientation == Orientation.Horizontal) {
+                               foreach (GraphicObject c in Children) {
+                                       if (!c.Visible)
+                                               continue;
+                                       c.Slot.X = d;
+                                       d += c.Slot.Width + Spacing;
+                               }
+                       } else {
+                               foreach (GraphicObject c in Children) {
+                                       if (!c.Visible)
+                                               continue;                                       
+                                       c.Slot.Y = d;
+                                       d += c.Slot.Height + Spacing;
+                               }
+                       }
+                       IsDirty = true;
+               }
+               GraphicObject stretchedGO = null;
+               public override bool UpdateLayout (LayoutingType layoutType)
+        {
+                       RegisteredLayoutings &= (~layoutType);
+
+                       if (layoutType == LayoutingType.ArrangeChildren) {
+                               //allow 1 child to have size to 0 if stack has fixed or streched size policy,
+                               //this child will occupy remaining space
+                               //if stack size policy is Fit, no child may have stretch enabled
+                               //in the direction of stacking.
+                               ComputeChildrenPositions ();
+
+                               //if no layouting remains in queue for item, registre for redraw
+                               if (RegisteredLayoutings == LayoutingType.None && IsDirty)
+                                       CurrentInterface.EnqueueForRepaint (this);
+
+                               return true;
+                       }
+
+                       return base.UpdateLayout(layoutType);
+        }
+
+               public override void OnChildLayoutChanges (object sender, LayoutingEventArgs arg)
+               {
+                       GraphicObject go = sender as GraphicObject;
+                       //Debug.WriteLine ("child layout change: " + go.LastSlots.ToString() + " => " + go.Slot.ToString());
+                       switch (arg.LayoutType) {
+                       case LayoutingType.Width:
+                               if (Orientation == Orientation.Horizontal) {
+                                       if (go.Width == Measure.Stretched) {
+                                               if (stretchedGO == null && Width != Measure.Fit)
+                                                       stretchedGO = go;
+                                               else if (stretchedGO != go) {
+                                                       go.Slot.Width = 0;
+                                                       go.Width = Measure.Fit;
+                                                       return;
+                                               }
+                                       } else
+                                               contentSize.Width += go.Slot.Width - go.LastSlots.Width;
+
+                                       if (stretchedGO != null) {
+                                               int newW = Math.Max (
+                                                                  this.ClientRectangle.Width - contentSize.Width - Spacing * (Children.Count - 1),
+                                                                  stretchedGO.MinimumSize.Width);
+                                               if (stretchedGO.MaximumSize.Width > 0)
+                                                       newW = Math.Min (newW, stretchedGO.MaximumSize.Width);
+                                               if (newW != stretchedGO.Slot.Width) {                                                   
+                                                       stretchedGO.Slot.Width = newW;
+                                                       stretchedGO.IsDirty = true;
+#if DEBUG_LAYOUTING
+                                       Debug.WriteLine ("\tAdjusting Width of " + stretchedGO.ToString());
+#endif
+                                                       stretchedGO.LayoutChanged -= OnChildLayoutChanges;
+                                                       stretchedGO.OnLayoutChanges (LayoutingType.Width);
+                                                       stretchedGO.LayoutChanged += OnChildLayoutChanges;
+                                                       stretchedGO.LastSlots.Width = stretchedGO.Slot.Width;
+                                               }
+                                       }
+                                       
+                                       if (Width == Measure.Fit)
+                                               this.RegisterForLayouting (LayoutingType.Width);
+                                       
+                                       this.RegisterForLayouting (LayoutingType.ArrangeChildren);
+                                       return;
+                               }
+                               break;
+                       case LayoutingType.Height:
+                               if (Orientation == Orientation.Vertical) {
+                                       if (go.Height == Measure.Stretched) {
+                                               if (stretchedGO == null && Height != Measure.Fit)
+                                                       stretchedGO = go;
+                                               else if (stretchedGO != go){
+                                                       go.Slot.Height = 0;
+                                                       go.Height = Measure.Fit;
+                                                       return;
+                                               }
+                                       } else
+                                               contentSize.Height += go.Slot.Height - go.LastSlots.Height;
+                                       
+                                       if (stretchedGO != null) {
+                                               int newH = Math.Max (
+                                                       this.ClientRectangle.Height - contentSize.Height - Spacing * (Children.Count - 1),
+                                                       stretchedGO.MinimumSize.Height);
+                                               if (stretchedGO.MaximumSize.Height > 0)
+                                                       newH = Math.Min (newH, stretchedGO.MaximumSize.Height);
+                                               if (newH != stretchedGO.Slot.Height) {
+                                                       stretchedGO.Slot.Height = newH;
+                                                       stretchedGO.IsDirty = true;
+#if DEBUG_LAYOUTING
+                                       Debug.WriteLine ("\tAdjusting Height of " + stretchedGO.ToString());
+#endif
+                                                       stretchedGO.LayoutChanged -= OnChildLayoutChanges;
+                                                       stretchedGO.OnLayoutChanges (LayoutingType.Height);
+                                                       stretchedGO.LayoutChanged += OnChildLayoutChanges;
+                                                       stretchedGO.LastSlots.Height = stretchedGO.Slot.Height;
+                                               }
+                                       }
+
+                                       if (Height == Measure.Fit)
+                                               this.RegisterForLayouting (LayoutingType.Height);
+
+                                       this.RegisterForLayouting (LayoutingType.ArrangeChildren);
+                                       return;
+                               }
+                               break;
+                       }
+                       base.OnChildLayoutChanges (sender, arg);
+               }
+               #endregion
+
+    
+       }
+}
diff --git a/src/GraphicObjects/Base/GraphicObject.cs b/src/GraphicObjects/Base/GraphicObject.cs
new file mode 100644 (file)
index 0000000..2afbe33
--- /dev/null
@@ -0,0 +1,1555 @@
+//
+// GraphicObject.cs
+//
+// Author:
+//       Jean-Philippe Bruyère <jp.bruyere@hotmail.com>
+//
+// Copyright (c) 2013-2017 Jean-Philippe Bruyère
+//
+// 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.Generic;
+using System.ComponentModel;
+using System.Xml.Serialization;
+using System.Reflection;
+using System.Reflection.Emit;
+using System.Runtime.CompilerServices;
+using Cairo;
+using System.Linq;
+using System.Diagnostics;
+using System.IO;
+
+namespace Crow
+{
+       public class GraphicObject : IXmlSerializable, ILayoutable, IValueChange, ICloneable
+       {
+               internal static ulong currentUid = 0;
+               internal ulong uid = 0;
+
+               Interface currentInterface = null;
+
+               [XmlIgnore]public Interface CurrentInterface {
+                       get {
+                               if (currentInterface == null) {
+                                       currentInterface = Interface.CurrentInterface;
+                                       Initialize ();
+                               }
+                               return currentInterface;
+                       }
+                       set {
+                               currentInterface = value;
+                       }
+               }
+
+               Rectangles clipping = new Rectangles();
+               public Rectangles Clipping { get { return clipping; }}
+
+               #region IValueChange implementation
+               public event EventHandler<ValueChangeEventArgs> ValueChanged;
+               public virtual void NotifyValueChanged(string MemberName, object _value)
+               {
+                       //Debug.WriteLine ("Value changed: {0}->{1} = {2}", this, MemberName, _value);
+                       ValueChanged.Raise(this, new ValueChangeEventArgs(MemberName, _value));
+               }
+               #endregion
+
+               #region CTOR
+               public GraphicObject ()
+               {
+                       #if DEBUG
+                       uid = currentUid;
+                       currentUid++;
+                       #endif
+               }
+               #endregion
+
+               /// <summary>
+               /// Initialize this Graphic object instance by setting style and default values and loading template if required
+               /// </summary>
+               public virtual void Initialize(){
+                       if (currentInterface == null)
+                               currentInterface = Interface.CurrentInterface;
+                       loadDefaultValues ();
+               }
+               #region private fields
+               LayoutingType registeredLayoutings = LayoutingType.All;
+               ILayoutable logicalParent;
+               ILayoutable parent;
+               string name;
+               Fill background = Color.Transparent;
+               Fill foreground = Color.White;
+               Font font = "droid, 10";
+               Measure width, height;
+               int left, top;
+               double cornerRadius = 0;
+               int margin = 0;
+               bool focusable = false;
+               bool hasFocus = false;
+               bool isActive = false;
+               bool mouseRepeat;
+               protected bool isVisible = true;
+               bool isEnabled = true;
+               VerticalAlignment verticalAlignment = VerticalAlignment.Center;
+               HorizontalAlignment horizontalAlignment = HorizontalAlignment.Center;
+               Size maximumSize = "0,0";
+               Size minimumSize = "0,0";
+               bool cacheEnabled = false;
+               bool clipToClientRect = true;
+               protected object dataSource;
+               string style;
+               object tag;
+               #endregion
+
+               #region public fields
+               /// <summary>
+               /// Current size and position computed during layouting pass
+               /// </summary>
+               public Rectangle Slot = new Rectangle ();
+               /// <summary>
+               /// keep last slot components for each layouting pass to track
+               /// changes and trigger update of other component accordingly
+               /// </summary>
+               public Rectangle LastSlots;
+               /// <summary>
+               /// keep last slot painted on screen to clear traces if moved or resized
+               /// TODO: we should ensure the whole parsed widget tree is the last painted
+               /// version to clear effective oldslot if parents have been moved or resized.
+               /// IDEA is to add a ScreenCoordinates function that use only lastPaintedSlots
+               /// </summary>
+               public Rectangle LastPaintedSlot;
+               /// <summary>Prevent requeuing multiple times the same widget</summary>
+               public bool IsQueueForRedraw = false;
+               /// <summary>drawing Cache, if null, a redraw is done, cached or not</summary>
+               public byte[] bmp;
+               public bool IsDirty = true;
+               /// <summary>
+               /// This size is computed on each child' layout changes.
+               /// In stacking widget, it is used to compute the remaining space for the stretched
+               /// widget inside the stack, which is never added to the contentSize, instead, its size
+               /// is deducted from (parent.ClientRectangle - contentSize)
+               /// </summary>
+               internal Size contentSize;
+               #endregion
+
+               #region ILayoutable
+               [XmlIgnore]public LayoutingType RegisteredLayoutings { get { return registeredLayoutings; } set { registeredLayoutings = value; } }
+               //TODO: it would save the recurent cost of a cast in event bubbling if parent type was GraphicObject
+               //              or we could add to the interface the mouse events
+               /// <summary>
+               /// Parent in the graphic tree, used for rendering and layouting
+               /// </summary>
+               [XmlIgnore]public virtual ILayoutable Parent {
+                       get { return parent; }
+                       set {
+                               if (parent == value)
+                                       return;
+                               DataSourceChangeEventArgs e = new DataSourceChangeEventArgs (parent, value);
+                               lock (this)
+                                       parent = value;
+
+                               onParentChanged (this, e);
+                       }
+               }
+               [XmlIgnore]public ILayoutable LogicalParent {
+                       get { return logicalParent == null ? Parent : logicalParent; }
+                       set {
+                               if (logicalParent == value)
+                                       return;
+                               if (logicalParent != null)
+                                       (logicalParent as GraphicObject).DataSourceChanged -= onLogicalParentDataSourceChanged;
+                               DataSourceChangeEventArgs dsce = new DataSourceChangeEventArgs (LogicalParent, null);
+                               logicalParent = value;
+                               dsce.NewDataSource = LogicalParent;
+                               if (logicalParent != null)
+                                       (logicalParent as GraphicObject).DataSourceChanged += onLogicalParentDataSourceChanged;
+                               onLogicalParentChanged (this, dsce);
+                       }
+               }
+               [XmlIgnore]public virtual Rectangle ClientRectangle {
+                       get {
+                               Rectangle cb = Slot.Size;
+                               cb.Inflate ( - Margin);
+                               return cb;
+                       }
+               }
+               public virtual Rectangle ContextCoordinates(Rectangle r){
+                       GraphicObject go = Parent as GraphicObject;
+                       if (go == null)
+                               return r + Parent.ClientRectangle.Position;
+                       return go.CacheEnabled ?
+                               r + Parent.ClientRectangle.Position :
+                               Parent.ContextCoordinates (r);
+               }
+               public virtual Rectangle ScreenCoordinates (Rectangle r){
+                       return
+                               Parent.ScreenCoordinates(r) + Parent.getSlot().Position + Parent.ClientRectangle.Position;
+               }
+               public virtual Rectangle getSlot () { return Slot;}
+               #endregion
+
+               #region EVENT HANDLERS
+               public event EventHandler<MouseWheelEventArgs> MouseWheelChanged;
+               public event EventHandler<MouseButtonEventArgs> MouseUp;
+               public event EventHandler<MouseButtonEventArgs> MouseDown;
+               public event EventHandler<MouseButtonEventArgs> MouseClick;
+               public event EventHandler<MouseButtonEventArgs> MouseDoubleClick;
+               public event EventHandler<MouseMoveEventArgs> MouseMove;
+               public event EventHandler<MouseMoveEventArgs> MouseEnter;
+               public event EventHandler<MouseMoveEventArgs> MouseLeave;
+               public event EventHandler<KeyboardKeyEventArgs> KeyDown;
+               public event EventHandler<KeyboardKeyEventArgs> KeyUp;
+               public event EventHandler<KeyPressEventArgs> KeyPress;
+               public event EventHandler Focused;
+               public event EventHandler Unfocused;
+               public event EventHandler Enabled;
+               public event EventHandler Disabled;
+               public event EventHandler<LayoutingEventArgs> LayoutChanged;
+               public event EventHandler<DataSourceChangeEventArgs> DataSourceChanged;
+               public event EventHandler<DataSourceChangeEventArgs> ParentChanged;
+               public event EventHandler<DataSourceChangeEventArgs> LogicalParentChanged;
+               #endregion
+
+               #region public properties
+               /// <summary>Random value placeholder</summary>
+               [XmlAttributeAttribute]
+               public object Tag {
+                       get { return tag; }
+                       set {
+                               if (tag == value)
+                                       return;
+                               tag = value;
+                               NotifyValueChanged ("Tag", tag);
+                       }
+               }
+               /// <summary>
+               /// If enabled, resulting bitmap of graphic object is cached in an byte array
+               /// speeding up rendering of complex object. Default is enabled.
+               /// </summary>
+               [XmlAttributeAttribute][DefaultValue(true)]
+               public virtual bool CacheEnabled {
+                       get { return cacheEnabled; }
+                       set {
+                               if (cacheEnabled == value)
+                                       return;
+                               cacheEnabled = value;
+                               NotifyValueChanged ("CacheEnabled", cacheEnabled);
+                       }
+               }
+               /// <summary>
+               /// If true, rendering of GraphicObject is clipped inside client rectangle
+               /// </summary>
+               [XmlAttributeAttribute][DefaultValue(true)]
+               public virtual bool ClipToClientRect {
+                       get { return clipToClientRect; }
+                       set {
+                               if (clipToClientRect == value)
+                                       return;
+                               clipToClientRect = value;
+                               NotifyValueChanged ("ClipToClientRect", clipToClientRect);
+                               this.RegisterForRedraw ();
+                       }
+               }
+               /// <summary>
+               /// Name is used in binding to reference other GraphicObjects inside the graphic tree
+               /// </summary>
+               [XmlAttributeAttribute][DefaultValue(null)]
+               public virtual string Name {
+                       get {
+                               #if DEBUG
+                               return string.IsNullOrEmpty(name) ? this.GetType().Name + uid.ToString () : name;
+                               #else
+                               return name;
+                               #endif
+                       }
+                       set {
+                               if (name == value)
+                                       return;
+                               name = value;
+                               NotifyValueChanged("Name", name);
+                       }
+               }
+               [XmlAttributeAttribute  ()][DefaultValue(VerticalAlignment.Center)]
+               public virtual VerticalAlignment VerticalAlignment {
+                       get { return verticalAlignment; }
+                       set {
+                               if (verticalAlignment == value)
+                                       return;
+
+                               verticalAlignment = value;
+                               NotifyValueChanged("VerticalAlignment", verticalAlignment);
+                               RegisterForLayouting (LayoutingType.Y);
+                       }
+               }
+               [XmlAttributeAttribute()][DefaultValue(HorizontalAlignment.Center)]
+               public virtual HorizontalAlignment HorizontalAlignment {
+                       get { return horizontalAlignment; }
+                       set {
+                               if (horizontalAlignment == value)
+                                       return;
+                               horizontalAlignment = value;
+                               NotifyValueChanged("HorizontalAlignment", horizontalAlignment);
+                               RegisterForLayouting (LayoutingType.X);
+                       }
+               }
+               [XmlAttributeAttribute()][DefaultValue(0)]
+               public virtual int Left {
+                       get { return left; }
+                       set {
+                               if (left == value)
+                                       return;
+                               left = value;
+                               NotifyValueChanged ("Left", left);
+                               this.RegisterForLayouting (LayoutingType.X);
+                       }
+               }
+               [XmlAttributeAttribute()][DefaultValue(0)]
+               public virtual int Top {
+                       get { return top; }
+                       set {
+                               if (top == value)
+                                       return;
+                               top = value;
+                               NotifyValueChanged ("Top", top);
+                               this.RegisterForLayouting (LayoutingType.Y);
+                       }
+               }
+               /// <summary>
+               /// When set to True, the <see cref="T:Crow.GraphicObject"/>'s width and height will be set to Fit.
+               /// </summary>
+               [XmlAttributeAttribute()][DefaultValue(false)]
+               public virtual bool Fit {
+                       get { return Width == Measure.Fit && Height == Measure.Fit ? true : false; }
+                       set {
+                               if (value == Fit)
+                                       return;
+
+                               Width = Height = Measure.Fit;
+                       }
+               }
+               [XmlAttributeAttribute()][DefaultValue("Inherit")]
+               public virtual Measure Width {
+                       get {
+                               return width.Units == Unit.Inherit ?
+                                       Parent is GraphicObject ? (Parent as GraphicObject).WidthPolicy :
+                                       Measure.Stretched : width;
+                       }
+                       set {
+                               if (width == value)
+                                       return;
+                               if (value.IsFixed) {
+                                       if (value < MinimumSize.Width || (value > MaximumSize.Width && MaximumSize.Width > 0))
+                                               return;
+                               }
+                               Measure lastWP = WidthPolicy;
+                               width = value;
+                               NotifyValueChanged ("Width", width);
+                               if (WidthPolicy != lastWP) {
+                                       NotifyValueChanged ("WidthPolicy", WidthPolicy);
+                                       //contentSize in Stacks are only update on childLayoutChange, and the single stretched
+                                       //child of the stack is not counted in contentSize, so when changing size policy of a child
+                                       //we should adapt contentSize
+                                       //TODO:check case when child become stretched, and another stretched item already exists.
+                                       if (parent is GenericStack) {//TODO:check if I should test Group instead
+                                               if ((parent as GenericStack).Orientation == Orientation.Horizontal) {
+                                                       if (lastWP == Measure.Fit)
+                                                               (parent as GenericStack).contentSize.Width -= this.LastSlots.Width;
+                                                       else
+                                                               (parent as GenericStack).contentSize.Width += this.LastSlots.Width;
+                                               }
+                                       }
+                               }
+
+                               this.RegisterForLayouting (LayoutingType.Width);
+                       }
+               }
+               [XmlAttributeAttribute()][DefaultValue("Inherit")]
+               public virtual Measure Height {
+                       get {
+                               return height.Units == Unit.Inherit ?
+                                       Parent is GraphicObject ? (Parent as GraphicObject).HeightPolicy :
+                                       Measure.Stretched : height;
+                       }
+                       set {
+                               if (height == value)
+                                       return;
+                               if (value.IsFixed) {
+                                       if (value < MinimumSize.Height || (value > MaximumSize.Height && MaximumSize.Height > 0))
+                                               return;
+                               }
+                               Measure lastHP = HeightPolicy;
+                               height = value;
+                               NotifyValueChanged ("Height", height);
+                               if (HeightPolicy != lastHP) {
+                                       NotifyValueChanged ("HeightPolicy", HeightPolicy);
+                                       if (parent is GenericStack) {
+                                               if ((parent as GenericStack).Orientation == Orientation.Vertical) {
+                                                       if (lastHP == Measure.Fit)
+                                                               (parent as GenericStack).contentSize.Height -= this.LastSlots.Height;
+                                                       else
+                                                               (parent as GenericStack).contentSize.Height += this.LastSlots.Height;
+                                               }
+                                       }
+                               }
+
+                               this.RegisterForLayouting (LayoutingType.Height);
+                       }
+               }
+               /// <summary>
+               /// Used for binding on dimensions, this property will never hold fixed size, but instead only
+               /// Fit or Stretched
+               /// </summary>
+               [XmlIgnore]public virtual Measure WidthPolicy { get {
+                               return Width.IsFit ? Measure.Fit : Measure.Stretched; } }
+               /// <summary>
+               /// Used for binding on dimensions, this property will never hold fixed size, but instead only
+               /// Fit or Stretched
+               /// </summary>
+               [XmlIgnore]public virtual Measure HeightPolicy { get {
+                               return Height.IsFit ? Measure.Fit : Measure.Stretched; } }
+               [XmlAttributeAttribute()][DefaultValue(false)]
+               public virtual bool Focusable {
+                       get { return focusable; }
+                       set {
+                               if (focusable == value)
+                                       return;
+                               focusable = value;
+                               NotifyValueChanged ("Focusable", focusable);
+                       }
+               }
+               [XmlIgnore]public virtual bool HasFocus {
+                       get { return hasFocus; }
+                       set {
+                               if (value == hasFocus)
+                                       return;
+
+                               hasFocus = value;
+                               if (hasFocus)
+                                       onFocused (this, null);
+                               else
+                                       onUnfocused (this, null);
+                               NotifyValueChanged ("HasFocus", hasFocus);
+                       }
+               }
+               [XmlIgnore]public virtual bool IsActive {
+                       get { return isActive; }
+                       set {
+                               if (value == isActive)
+                                       return;
+
+                               isActive = value;
+                               NotifyValueChanged ("IsActive", isActive);
+                       }
+               }
+               [XmlAttributeAttribute()][DefaultValue(false)]
+               public virtual bool MouseRepeat {
+                       get { return mouseRepeat; }
+                       set {
+                               if (mouseRepeat == value)
+                                       return;
+                               mouseRepeat = value;
+                               NotifyValueChanged ("MouseRepeat", mouseRepeat);
+                       }
+               }
+               bool clearBackground = false;
+               [XmlAttributeAttribute()][DefaultValue("Transparent")]
+               public virtual Fill Background {
+                       get { return background; }
+                       set {
+                               if (background == value)
+                                       return;
+                               clearBackground = false;
+                               if (value == null)
+                                       return;
+                               background = value;
+                               NotifyValueChanged ("Background", background);
+                               RegisterForRedraw ();
+                               if (background is SolidColor) {
+                                       if ((Background as SolidColor).Equals (Color.Clear))
+                                               clearBackground = true;
+                               }
+                       }
+               }
+               [XmlAttributeAttribute()][DefaultValue("White")]
+               public virtual Fill Foreground {
+                       get { return foreground; }
+                       set {
+                               if (foreground == value)
+                                       return;
+                               foreground = value;
+                               NotifyValueChanged ("Foreground", foreground);
+                               RegisterForRedraw ();
+                       }
+               }
+               [XmlAttributeAttribute()][DefaultValue("sans,10")]
+               public virtual Font Font {
+                       get { return font; }
+                       set {
+                               if (value == font)
+                                       return;
+                               font = value;
+                               NotifyValueChanged ("Font", font);
+                               RegisterForGraphicUpdate ();
+                       }
+               }
+               [XmlAttributeAttribute()][DefaultValue(0.0)]
+               public virtual double CornerRadius {
+                       get { return cornerRadius; }
+                       set {
+                               if (value == cornerRadius)
+                                       return;
+                               cornerRadius = value;
+                               NotifyValueChanged ("CornerRadius", cornerRadius);
+                               RegisterForRedraw ();
+                       }
+               }
+               [XmlAttributeAttribute()][DefaultValue(0)]
+               public virtual int Margin {
+                       get { return margin; }
+                       set {
+                               if (value == margin)
+                                       return;
+                               margin = value;
+                               NotifyValueChanged ("Margin", margin);
+                               RegisterForGraphicUpdate ();
+                       }
+               }
+               [XmlAttributeAttribute][DefaultValue(true)]
+               public virtual bool Visible {
+                       get { return isVisible; }
+                       set {
+                               if (value == isVisible)
+                                       return;
+
+                               isVisible = value;
+
+                               if (isVisible)
+                                       RegisterForLayouting (LayoutingType.Sizing);
+                               else {
+                                       lock (CurrentInterface.UpdateMutex) {
+                                               Slot.Width = 0;
+                                               LayoutChanged.Raise (this, new LayoutingEventArgs (LayoutingType.Width));
+                                               Slot.Height = 0;
+                                               LayoutChanged.Raise (this, new LayoutingEventArgs (LayoutingType.Height));
+                                               if (this.parent != null)
+                                                       CurrentInterface.EnqueueForRepaint (this);
+                                               LastSlots.Width = LastSlots.Height = 0;
+                                       }
+                               }
+
+                               //trigger a mouse to handle possible hover changes
+                               CurrentInterface.ProcessMouseMove (CurrentInterface.Mouse.X, CurrentInterface.Mouse.Y);
+
+                               NotifyValueChanged ("Visible", isVisible);
+                       }
+               }
+               [XmlAttributeAttribute][DefaultValue(true)]
+               public virtual bool IsEnabled {
+                       get { return isEnabled; }
+                       set {
+                               if (value == isEnabled)
+                                       return;
+
+                               isEnabled = value;
+
+                               if (isEnabled)
+                                       onEnable (this, null);
+                               else
+                                       onDisable (this, null);
+
+                               NotifyValueChanged ("IsEnabled", isEnabled);
+                               RegisterForRedraw ();
+                       }
+               }
+               [XmlAttributeAttribute()][DefaultValue("1,1")]
+               public virtual Size MinimumSize {
+                       get { return minimumSize; }
+                       set {
+                               if (value == minimumSize)
+                                       return;
+
+                               minimumSize = value;
+
+                               NotifyValueChanged ("MinimumSize", minimumSize);
+                               RegisterForLayouting (LayoutingType.Sizing);
+                       }
+               }
+               [XmlAttributeAttribute()][DefaultValue("0,0")]
+               public virtual Size MaximumSize {
+                       get { return maximumSize; }
+                       set {
+                               if (value == maximumSize)
+                                       return;
+
+                               maximumSize = value;
+
+                               NotifyValueChanged ("MaximumSize", maximumSize);
+                               RegisterForLayouting (LayoutingType.Sizing);
+                       }
+               }
+               /// <summary>
+               /// Seek first logical tree upward if logicalParent is set, or seek graphic tree for
+               /// a not null dataSource that will be active for all descendants having dataSource=null
+               /// </summary>
+               [XmlAttributeAttribute][DefaultValue(null)]
+               public virtual object DataSource {
+                       set {
+                               if (DataSource == value)
+                                       return;
+
+                               DataSourceChangeEventArgs dse = new DataSourceChangeEventArgs (DataSource, null);
+                               dataSource = value;
+                               dse.NewDataSource = DataSource;
+
+                               OnDataSourceChanged (this, dse);
+
+                               NotifyValueChanged ("DataSource", DataSource);
+                       }
+                       get {
+                               return dataSource == null ?
+                                       LogicalParent == null ? null :
+                                       LogicalParent is GraphicObject ? (LogicalParent as GraphicObject).DataSource : null :
+                                       dataSource;
+                       }
+               }
+               protected virtual void onLogicalParentDataSourceChanged(object sender, DataSourceChangeEventArgs e){
+                       if (localDataSourceIsNull)
+                               OnDataSourceChanged (this, e);
+               }
+               internal bool localDataSourceIsNull { get { return dataSource == null; } }
+               internal bool localLogicalParentIsNull { get { return logicalParent == null; } }
+
+               public virtual void OnDataSourceChanged(object sender, DataSourceChangeEventArgs e){
+                       DataSourceChanged.Raise (this, e);
+                       #if DEBUG_BINDING
+                       Debug.WriteLine("New DataSource for => {0} \n\t{1}=>{2}", this.ToString(),e.OldDataSource,e.NewDataSource);
+                       #endif
+               }
+
+               [XmlAttributeAttribute]
+               public virtual string Style {
+                       get { return style; }
+                       set {
+                               if (value == style)
+                                       return;
+
+                               style = value;
+
+                               NotifyValueChanged ("Style", style);
+                       }
+               }
+               #endregion
+
+               #region Default and Style Values loading
+               /// <summary> Loads the default values from XML attributes default </summary>
+               public void loadDefaultValues()
+               {
+                       #if DEBUG_LOAD
+                       Debug.WriteLine ("LoadDefValues for " + this.ToString ());
+                       #endif
+
+                       Type thisType = this.GetType ();
+
+                       if (!string.IsNullOrEmpty (Style)) {
+                               if (Interface.DefaultValuesLoader.ContainsKey (Style)) {
+                                       Interface.DefaultValuesLoader [Style] (this);
+                                       return;
+                               }
+                       } else {
+                               if (Interface.DefaultValuesLoader.ContainsKey (thisType.FullName)) {
+                                       Interface.DefaultValuesLoader [thisType.FullName] (this);
+                                       return;
+                               } else if (!Interface.Styling.ContainsKey (thisType.FullName)) {
+                                       if (Interface.DefaultValuesLoader.ContainsKey (thisType.Name)) {
+                                               Interface.DefaultValuesLoader [thisType.Name] (this);
+                                               return;
+                                       }
+                               }
+                       }
+
+                       List<Style> styling = new List<Style>();
+
+                       //Search for a style matching :
+                       //1: Full class name, with full namespace
+                       //2: class name
+                       //3: style may have been registered with their ressource ID minus .style extention
+                       //   those files being placed in a Styles folder
+                       string styleKey = Style;
+                       if (!string.IsNullOrEmpty (Style)) {
+                               if (Interface.Styling.ContainsKey (Style)) {
+                                       styling.Add (Interface.Styling [Style]);
+                               }
+                       }
+                       if (Interface.Styling.ContainsKey (thisType.FullName)) {
+                               styling.Add (Interface.Styling [thisType.FullName]);
+                               if (string.IsNullOrEmpty (styleKey))
+                                       styleKey = thisType.FullName;
+                       }
+                       if (Interface.Styling.ContainsKey (thisType.Name)) {
+                               styling.Add (Interface.Styling [thisType.Name]);
+                               if (string.IsNullOrEmpty (styleKey))
+                                       styleKey = thisType.Name;
+                       }
+
+                       if (string.IsNullOrEmpty (styleKey))
+                               styleKey = thisType.FullName;
+
+
+                       //Reflexion being very slow compared to dyn method or delegates,
+                       //I compile the initial values coded in the CustomAttribs of the class,
+                       //all other instance of this type would not longer use reflexion to init properly
+                       //but will fetch the  dynamic initialisation method compiled for this precise type
+                       //TODO:measure speed gain.
+                       #region Delfault values Loading dynamic compilation
+                       DynamicMethod dm = null;
+                       ILGenerator il = null;
+
+                       dm = new DynamicMethod("dyn_loadDefValues",
+                               MethodAttributes.Family | MethodAttributes.FamANDAssem | MethodAttributes.NewSlot,
+                               CallingConventions.Standard,
+                               typeof(void),new Type[] {CompilerServices.TObject},thisType,true);
+
+                       il = dm.GetILGenerator(256);
+                       il.DeclareLocal(CompilerServices.TObject);
+                       il.Emit(OpCodes.Nop);
+                       //set local GraphicObject to root object passed as 1st argument
+                       il.Emit (OpCodes.Ldarg_0);
+                       il.Emit (OpCodes.Stloc_0);
+
+                       foreach (EventInfo ei in thisType.GetEvents(BindingFlags.Public | BindingFlags.Instance)) {
+                               string expression;
+                               if (!getDefaultEvent(ei, styling, out expression))
+                                       continue;
+                               //TODO:dynEventHandler could be cached somewhere, maybe a style instanciator class holding the styling delegate and bound to it.
+                               foreach (string exp in CompilerServices.splitOnSemiColumnOutsideAccolades(expression)) {
+                                       string trimed = exp.Trim();
+                                       if (trimed.StartsWith ("{", StringComparison.OrdinalIgnoreCase)){
+                                               il.Emit (OpCodes.Ldloc_0);//load this as 1st arg of event Add
+
+                                               //push eventInfo as 1st arg of compile
+                                               il.Emit (OpCodes.Ldloc_0);
+                                               il.Emit (OpCodes.Call, CompilerServices.miGetType);
+                                               il.Emit (OpCodes.Ldstr, ei.Name);//push event name
+                                               il.Emit (OpCodes.Call, CompilerServices.miGetEvent);
+                                               //push expression as 2nd arg of compile
+                                               il.Emit (OpCodes.Ldstr, trimed.Substring (1, trimed.Length - 2));
+                                               //push null as 3rd arg, currentNode, not known when instanciing
+                                               il.Emit (OpCodes.Ldnull);
+                                               il.Emit (OpCodes.Callvirt, CompilerServices.miCompileDynEventHandler);
+                                               il.Emit (OpCodes.Castclass, ei.EventHandlerType);
+                                               il.Emit (OpCodes.Callvirt, ei.AddMethod);
+                                       }else
+                                               Debug.WriteLine("error in styling, event not handled : " + trimed);
+                               }
+                       }
+
+                       foreach (PropertyInfo pi in thisType.GetProperties(BindingFlags.Public | BindingFlags.Instance)) {
+                               if (pi.GetSetMethod () == null)
+                                       continue;
+                               object defaultValue;
+                               if (!getDefaultValue (pi, styling, out defaultValue))
+                                       continue;
+
+                               CompilerServices.EmitSetValue (il, pi, defaultValue);
+                       }
+                       il.Emit(OpCodes.Ret);
+                       #endregion
+
+                       try {
+                               Interface.DefaultValuesLoader[styleKey] = (Interface.LoaderInvoker)dm.CreateDelegate(typeof(Interface.LoaderInvoker));
+                               Interface.DefaultValuesLoader[styleKey] (this);
+                       } catch (Exception ex) {
+                               throw new Exception ("Error applying style <" + styleKey + ">:", ex);
+                       }
+               }
+               bool getDefaultEvent(EventInfo ei, List<Style> styling,
+                       out string expression){
+                       expression = "";
+                       if (styling.Count > 0){
+                               for (int i = 0; i < styling.Count; i++) {
+                                       if (styling[i].ContainsKey (ei.Name)){
+                                               expression = (string)styling[i] [ei.Name];
+                                               return true;
+                                       }
+                               }
+                       }
+                       return false;
+               }
+               bool getDefaultValue(PropertyInfo pi, List<Style> styling,
+                       out object defaultValue){
+                       defaultValue = null;
+                       string name = "";
+
+                       XmlIgnoreAttribute xia = (XmlIgnoreAttribute)pi.GetCustomAttribute (typeof(XmlIgnoreAttribute));
+                       if (xia != null)
+                               return false;
+                       XmlAttributeAttribute xaa = (XmlAttributeAttribute)pi.GetCustomAttribute (typeof(XmlAttributeAttribute));
+                       if (xaa != null) {
+                               if (string.IsNullOrEmpty (xaa.AttributeName))
+                                       name = pi.Name;
+                               else
+                                       name = xaa.AttributeName;
+                       }
+
+                       int styleIndex = -1;
+                       if (styling.Count > 0){
+                               for (int i = 0; i < styling.Count; i++) {
+                                       if (styling[i].ContainsKey (name)){
+                                               styleIndex = i;
+                                               break;
+                                       }
+                               }
+                       }
+                       if (styleIndex >= 0){
+                               if (pi.PropertyType.IsEnum)//maybe should be in parser..
+                                       defaultValue = Enum.Parse(pi.PropertyType, (string)styling[styleIndex] [name], true);
+                               else
+                                       defaultValue = styling[styleIndex] [name];
+                       }else {
+                               DefaultValueAttribute dv = (DefaultValueAttribute)pi.GetCustomAttribute (typeof (DefaultValueAttribute));
+                               if (dv == null)
+                                       return false;
+                               defaultValue = dv.Value;
+                       }
+                       return true;
+               }
+               #endregion
+
+               public virtual GraphicObject FindByName(string nameToFind){
+                       return string.Equals(nameToFind, name, StringComparison.Ordinal) ? this : null;
+               }
+               public virtual bool Contains(GraphicObject goToFind){
+                       return false;
+               }
+
+               #region Queuing
+               /// <summary>
+               /// Register old and new slot for clipping
+               /// </summary>
+               public virtual void ClippingRegistration(){
+                       IsQueueForRedraw = false;
+                       if (Parent == null)
+                               return;
+                       Parent.RegisterClip (LastPaintedSlot);
+                       Parent.RegisterClip (Slot);
+               }
+               /// <summary>
+               /// Add clip rectangle to this.clipping and propagate up to root
+               /// </summary>
+               /// <param name="clip">Clip rectangle</param>
+               public virtual void RegisterClip(Rectangle clip){
+                       if (CacheEnabled && !IsDirty)
+                               Clipping.AddRectangle (clip + ClientRectangle.Position);
+                       if (Parent == null)
+                               return;
+                       GraphicObject p = Parent as GraphicObject;
+                       if (p?.IsDirty == true && p?.CacheEnabled == true)
+                               return;
+                       Parent.RegisterClip (clip + Slot.Position + ClientRectangle.Position);
+               }
+               /// <summary> Full update, taking care of sizing policy </summary>
+               [MethodImpl(MethodImplOptions.AggressiveInlining)]
+               public void RegisterForGraphicUpdate ()
+               {
+                       IsDirty = true;
+                       if (Width.IsFit || Height.IsFit)
+                               RegisterForLayouting (LayoutingType.Sizing);
+                       else if (RegisteredLayoutings == LayoutingType.None)
+                               CurrentInterface.EnqueueForRepaint (this);
+               }
+               /// <summary> query an update of the content, a redraw </summary>
+               [MethodImpl(MethodImplOptions.AggressiveInlining)]
+               public void RegisterForRedraw ()
+               {
+                       IsDirty = true;
+                       if (RegisteredLayoutings == LayoutingType.None)
+                               CurrentInterface.EnqueueForRepaint (this);
+               }
+               #endregion
+
+               #region Layouting
+
+               /// <summary> return size of content + margins </summary>
+               protected virtual int measureRawSize (LayoutingType lt) {
+                       return lt == LayoutingType.Width ?
+                               contentSize.Width + 2 * Margin: contentSize.Height + 2 * Margin;
+               }
+               /// <summary> By default in groups, LayoutingType.ArrangeChildren is reset </summary>
+               public virtual void ChildrenLayoutingConstraints(ref LayoutingType layoutType){
+               }
+               public virtual bool ArrangeChildren { get { return false; } }
+               public virtual void RegisterForLayouting(LayoutingType layoutType){
+                       if (Parent == null)
+                               return;
+                       lock (CurrentInterface.LayoutMutex) {
+                               //prevent queueing same LayoutingType for this
+                               layoutType &= (~RegisteredLayoutings);
+
+                               if (layoutType == LayoutingType.None)
+                                       return;
+                               //dont set position for stretched item
+                               if (Width == Measure.Stretched)
+                                       layoutType &= (~LayoutingType.X);
+                               if (Height == Measure.Stretched)
+                                       layoutType &= (~LayoutingType.Y);
+
+                               if (!ArrangeChildren)
+                                       layoutType &= (~LayoutingType.ArrangeChildren);
+
+                               //apply constraints depending on parent type
+                               if (Parent is GraphicObject)
+                                       (Parent as GraphicObject).ChildrenLayoutingConstraints (ref layoutType);
+
+//                             //prevent queueing same LayoutingType for this
+//                             layoutType &= (~RegisteredLayoutings);
+
+                               if (layoutType == LayoutingType.None)
+                                       return;
+
+                               //enqueue LQI LayoutingTypes separately
+                               if (layoutType.HasFlag (LayoutingType.Width))
+                                       CurrentInterface.LayoutingQueue.Enqueue (new LayoutingQueueItem (LayoutingType.Width, this));
+                               if (layoutType.HasFlag (LayoutingType.Height))
+                                       CurrentInterface.LayoutingQueue.Enqueue (new LayoutingQueueItem (LayoutingType.Height, this));
+                               if (layoutType.HasFlag (LayoutingType.X))
+                                       CurrentInterface.LayoutingQueue.Enqueue (new LayoutingQueueItem (LayoutingType.X, this));
+                               if (layoutType.HasFlag (LayoutingType.Y))
+                                       CurrentInterface.LayoutingQueue.Enqueue (new LayoutingQueueItem (LayoutingType.Y, this));
+                               if (layoutType.HasFlag (LayoutingType.ArrangeChildren))
+                                       CurrentInterface.LayoutingQueue.Enqueue (new LayoutingQueueItem (LayoutingType.ArrangeChildren, this));
+                       }
+               }
+
+               /// <summary> trigger dependant sizing component update </summary>
+               public virtual void OnLayoutChanges(LayoutingType  layoutType)
+               {
+                       #if DEBUG_LAYOUTING
+                       CurrentInterface.currentLQI.Slot = LastSlots;
+                       CurrentInterface.currentLQI.NewSlot = Slot;
+                       Debug.WriteLine ("\t\t{0} => {1}",LastSlots,Slot);
+                       #endif
+
+                       switch (layoutType) {
+                       case LayoutingType.Width:
+                               RegisterForLayouting (LayoutingType.X);
+                               break;
+                       case LayoutingType.Height:
+                               RegisterForLayouting (LayoutingType.Y);
+                               break;
+                       }
+                       LayoutChanged.Raise (this, new LayoutingEventArgs (layoutType));
+               }
+               internal protected void raiseLayoutChanged(LayoutingEventArgs e){
+                       LayoutChanged.Raise (this, e);
+               }
+               /// <summary> Update layout component only one at a time, this is where the computation of alignement
+               /// and size take place.
+               /// The redrawing will only be triggered if final slot size has changed </summary>
+               /// <returns><c>true</c>, if layouting was possible, <c>false</c> if conditions were not
+               /// met and LQI has to be re-queued</returns>
+               public virtual bool UpdateLayout (LayoutingType layoutType)
+               {
+                       //unset bit, it would be reset if LQI is re-queued
+                       registeredLayoutings &= (~layoutType);
+
+                       switch (layoutType) {
+                       case LayoutingType.X:
+                               if (Left == 0) {
+
+                                       if (Parent.RegisteredLayoutings.HasFlag (LayoutingType.Width) ||
+                                           RegisteredLayoutings.HasFlag (LayoutingType.Width))
+                                               return false;
+
+                                       switch (HorizontalAlignment) {
+                                       case HorizontalAlignment.Left:
+                                               Slot.X = 0;
+                                               break;
+                                       case HorizontalAlignment.Right:
+                                               Slot.X = Parent.ClientRectangle.Width - Slot.Width;
+                                               break;
+                                       case HorizontalAlignment.Center:
+                                               Slot.X = Parent.ClientRectangle.Width / 2 - Slot.Width / 2;
+                                               break;
+                                       }
+                               } else
+                                       Slot.X = Left;
+
+                               if (LastSlots.X == Slot.X)
+                                       break;
+
+                               IsDirty = true;
+
+                               OnLayoutChanges (layoutType);
+
+                               LastSlots.X = Slot.X;
+                               break;
+                       case LayoutingType.Y:
+                               if (Top == 0) {
+
+                                       if (Parent.RegisteredLayoutings.HasFlag (LayoutingType.Height) ||
+                                           RegisteredLayoutings.HasFlag (LayoutingType.Height))
+                                               return false;
+
+                                       switch (VerticalAlignment) {
+                                       case VerticalAlignment.Top://this could be processed even if parent Height is not known
+                                               Slot.Y = 0;
+                                               break;
+                                       case VerticalAlignment.Bottom:
+                                               Slot.Y = Parent.ClientRectangle.Height - Slot.Height;
+                                               break;
+                                       case VerticalAlignment.Center:
+                                               Slot.Y = Parent.ClientRectangle.Height / 2 - Slot.Height / 2;
+                                               break;
+                                       }
+                               } else
+                                       Slot.Y = Top;
+
+                               if (LastSlots.Y == Slot.Y)
+                                       break;
+
+                               IsDirty = true;
+
+                               OnLayoutChanges (layoutType);
+
+                               LastSlots.Y = Slot.Y;
+                               break;
+                       case LayoutingType.Width:
+                               if (Visible) {
+                                       if (Width.IsFixed)
+                                               Slot.Width = Width;
+                                       else if (Width == Measure.Fit) {
+                                               Slot.Width = measureRawSize (LayoutingType.Width);
+                                       } else if (Parent.RegisteredLayoutings.HasFlag (LayoutingType.Width))
+                                               return false;
+                                       else if (Width == Measure.Stretched)
+                                               Slot.Width = Parent.ClientRectangle.Width;
+                                       else
+                                               Slot.Width = (int)Math.Round ((double)(Parent.ClientRectangle.Width * Width) / 100.0);
+
+                                       if (Slot.Width < 0)
+                                               return false;
+
+                                       //size constrain
+                                       if (Slot.Width < MinimumSize.Width) {
+                                               Slot.Width = MinimumSize.Width;
+                                               //NotifyValueChanged ("WidthPolicy", Measure.Stretched);
+                                       } else if (Slot.Width > MaximumSize.Width && MaximumSize.Width > 0) {
+                                               Slot.Width = MaximumSize.Width;
+                                               //NotifyValueChanged ("WidthPolicy", Measure.Stretched);
+                                       }
+                               } else
+                                       Slot.Width = 0;
+
+                               if (LastSlots.Width == Slot.Width)
+                                       break;
+
+                               IsDirty = true;
+
+                               OnLayoutChanges (layoutType);
+
+                               LastSlots.Width = Slot.Width;
+                               break;
+                       case LayoutingType.Height:
+                               if (Visible) {
+                                       if (Height.IsFixed)
+                                               Slot.Height = Height;
+                                       else if (Height == Measure.Fit) {
+                                               Slot.Height = measureRawSize (LayoutingType.Height);
+                                       } else if (Parent.RegisteredLayoutings.HasFlag (LayoutingType.Height))
+                                               return false;
+                                       else if (Height == Measure.Stretched)
+                                               Slot.Height = Parent.ClientRectangle.Height;
+                                       else
+                                               Slot.Height = (int)Math.Round ((double)(Parent.ClientRectangle.Height * Height) / 100.0);
+
+                                       if (Slot.Height < 0)
+                                               return false;
+
+                                       //size constrain
+                                       if (Slot.Height < MinimumSize.Height) {
+                                               Slot.Height = MinimumSize.Height;
+                                               //NotifyValueChanged ("HeightPolicy", Measure.Stretched);
+                                       } else if (Slot.Height > MaximumSize.Height && MaximumSize.Height > 0) {
+                                               Slot.Height = MaximumSize.Height;
+                                               //NotifyValueChanged ("HeightPolicy", Measure.Stretched);
+                                       }
+                               } else
+                                       Slot.Height = 0;
+
+                               if (LastSlots.Height == Slot.Height)
+                                       break;
+
+                               IsDirty = true;
+
+                               OnLayoutChanges (layoutType);
+
+                               LastSlots.Height = Slot.Height;
+                               break;
+                       }
+
+                       //if no layouting remains in queue for item, registre for redraw
+                       if (this.registeredLayoutings == LayoutingType.None && IsDirty)
+                               CurrentInterface.EnqueueForRepaint (this);
+
+                       return true;
+               }
+               #endregion
+
+               #region Rendering
+               /// <summary> This is the common overridable drawing routine to create new widget </summary>
+               protected virtual void onDraw(Context gr)
+               {
+                       Rectangle rBack = new Rectangle (Slot.Size);
+
+                       Background.SetAsSource (gr, rBack);
+                       CairoHelpers.CairoRectangle(gr,rBack,cornerRadius);
+                       gr.Fill ();
+               }
+
+               /// <summary>
+               /// Internal drawing context creation on a cached surface limited to slot size
+               /// this trigger the effective drawing routine </summary>
+               protected virtual void RecreateCache ()
+               {
+                       int stride = 4 * Slot.Width;
+
+                       int bmpSize = Math.Abs (stride) * Slot.Height;
+                       bmp = new byte[bmpSize];
+                       IsDirty = false;
+                       using (ImageSurface draw =
+                new ImageSurface(bmp, Format.Argb32, Slot.Width, Slot.Height, stride)) {
+                               using (Context gr = new Context (draw)) {
+                                       gr.Antialias = Interface.Antialias;
+                                       onDraw (gr);
+                               }
+                               draw.Flush ();
+                       }
+               }
+               protected virtual void UpdateCache(Context ctx){
+                       Rectangle rb = Slot + Parent.ClientRectangle.Position;
+                       using (ImageSurface cache = new ImageSurface (bmp, Format.Argb32, Slot.Width, Slot.Height, 4 * Slot.Width)) {
+                               if (clearBackground) {
+                                               ctx.Save ();
+                                               ctx.Operator = Operator.Clear;
+                                               ctx.Rectangle (rb);
+                                               ctx.Fill ();
+                                               ctx.Restore ();
+                               }
+                               ctx.SetSourceSurface (cache, rb.X, rb.Y);
+                               ctx.Paint ();
+                       }
+                       //Clipping.clearAndClip (ctx);
+                       Clipping.Reset();
+               }
+               /// <summary> Chained painting routine on the parent context of the actual cached version
+               /// of the widget </summary>
+               public virtual void Paint (ref Context ctx)
+               {
+                       //TODO:this test should not be necessary
+                       if (Slot.Height < 0 || Slot.Width < 0 || parent == null)
+                               return;
+                       lock (this) {
+                               if (cacheEnabled) {
+                                       if (Slot.Width > Interface.MaxCacheSize || Slot.Height > Interface.MaxCacheSize)
+                                               cacheEnabled = false;
+                               }
+
+                               if (cacheEnabled) {
+                                       if (IsDirty)
+                                               RecreateCache ();
+
+                                       UpdateCache (ctx);
+                                       if (!isEnabled)
+                                               paintDisabled (ctx, Slot + Parent.ClientRectangle.Position);
+                               } else {
+                                       Rectangle rb = Slot + Parent.ClientRectangle.Position;
+                                       ctx.Save ();
+
+                                       ctx.Translate (rb.X, rb.Y);
+
+                                       onDraw (ctx);
+                                       if (!isEnabled)
+                                               paintDisabled (ctx, Slot);
+
+                                       ctx.Restore ();
+                               }
+                               LastPaintedSlot = Slot;
+                       }
+               }
+               void paintDisabled(Context gr, Rectangle rb){
+                       gr.Operator = Operator.Xor;
+                       gr.SetSourceRGBA (0.6, 0.6, 0.6, 0.3);
+                       gr.Rectangle (rb);
+                       gr.Fill ();
+                       gr.Operator = Operator.Over;
+               }
+               #endregion
+
+        #region Keyboard handling
+               public virtual void onKeyDown(object sender, KeyboardKeyEventArgs e){
+                       KeyDown.Raise (sender, e);
+               }
+               public virtual void onKeyUp(object sender, KeyboardKeyEventArgs e){
+                       KeyUp.Raise (sender, e);
+               }
+               public virtual void onKeyPress(object sender, KeyPressEventArgs e){
+                       KeyPress.Raise (sender, e);
+               }
+        #endregion
+
+               #region Mouse handling
+               public virtual bool MouseIsIn(Point m)
+               {
+                       try {
+                               if (!(Visible & isEnabled))
+                                       return false;
+                               if (ScreenCoordinates (Slot).ContainsOrIsEqual (m)) {
+                                       Scroller scr = Parent as Scroller;
+                                       if (scr == null) {
+                                               if (Parent is GraphicObject)
+                                                       return (Parent as GraphicObject).MouseIsIn (m);
+                                               else return true;
+                                       }
+                                       return scr.MouseIsIn (scr.savedMousePos);
+                               }
+                       } catch (Exception ex) {
+                               return false;
+                       }
+                       return false;
+               }
+               public virtual void checkHoverWidget(MouseMoveEventArgs e)
+               {
+                       if (CurrentInterface.HoverWidget != this) {
+                               CurrentInterface.HoverWidget = this;
+                               onMouseEnter (this, e);
+                       }
+
+                       this.onMouseMove (this, e);//without this, window border doesn't work, should be removed
+               }
+               public virtual void onMouseMove(object sender, MouseMoveEventArgs e)
+               {
+                       //bubble event to the top
+                       GraphicObject p = Parent as GraphicObject;
+                       if (p != null)
+                               p.onMouseMove(sender,e);
+
+                       MouseMove.Raise (this, e);
+               }
+               public virtual void onMouseDown(object sender, MouseButtonEventArgs e){
+                       if (CurrentInterface.eligibleForDoubleClick == this && CurrentInterface.clickTimer.ElapsedMilliseconds < Interface.DoubleClick)
+                               onMouseDoubleClick (this, e);
+                       else
+                               currentInterface.clickTimer.Restart();
+                       CurrentInterface.eligibleForDoubleClick = null;
+
+                       if (CurrentInterface.ActiveWidget == null)
+                               CurrentInterface.ActiveWidget = this;
+                       if (this.Focusable && !Interface.FocusOnHover) {
+                               BubblingMouseButtonEventArg be = e as BubblingMouseButtonEventArg;
+                               if (be.Focused == null) {
+                                       be.Focused = this;
+                                       CurrentInterface.FocusedWidget = this;
+                               }
+                       }
+                       //bubble event to the top
+                       GraphicObject p = Parent as GraphicObject;
+                       if (p != null)
+                               p.onMouseDown(sender,e);
+
+                       MouseDown.Raise (this, e);
+               }
+               public virtual void onMouseUp(object sender, MouseButtonEventArgs e){
+                       //bubble event to the top
+                       GraphicObject p = Parent as GraphicObject;
+                       if (p != null)
+                               p.onMouseUp(sender,e);
+
+                       MouseUp.Raise (this, e);
+
+                       if (MouseIsIn (e.Position) && IsActive) {
+                               if (CurrentInterface.clickTimer.ElapsedMilliseconds < Interface.DoubleClick)
+                                       CurrentInterface.eligibleForDoubleClick = this;
+                               onMouseClick (this, e);
+                       }
+               }
+               public virtual void onMouseClick(object sender, MouseButtonEventArgs e){
+                       GraphicObject p = Parent as GraphicObject;
+                       if (p != null)
+                               p.onMouseClick(sender,e);
+                       MouseClick.Raise (this, e);
+               }
+               public virtual void onMouseDoubleClick(object sender, MouseButtonEventArgs e){
+                       GraphicObject p = Parent as GraphicObject;
+                       if (p != null)
+                               p.onMouseDoubleClick(sender,e);
+                       MouseDoubleClick.Raise (this, e);
+               }
+               public virtual void onMouseWheel(object sender, MouseWheelEventArgs e){
+                       GraphicObject p = Parent as GraphicObject;
+                       if (p != null)
+                               p.onMouseWheel(sender,e);
+
+                       MouseWheelChanged.Raise (this, e);
+               }
+               public virtual void onMouseEnter(object sender, MouseMoveEventArgs e)
+               {
+                       #if DEBUG_FOCUS
+                       Debug.WriteLine("MouseEnter => " + this.ToString());
+                       #endif
+                       MouseEnter.Raise (this, e);
+               }
+               public virtual void onMouseLeave(object sender, MouseMoveEventArgs e)
+               {
+                       #if DEBUG_FOCUS
+                       Debug.WriteLine("MouseLeave => " + this.ToString());
+                       #endif
+                       MouseLeave.Raise (this, e);
+               }
+               #endregion
+
+               protected virtual void onFocused(object sender, EventArgs e){
+                       #if DEBUG_FOCUS
+                       Debug.WriteLine("Focused => " + this.ToString());
+                       #endif
+                       Focused.Raise (this, e);
+               }
+               protected virtual void onUnfocused(object sender, EventArgs e){
+                       #if DEBUG_FOCUS
+                       Debug.WriteLine("UnFocused => " + this.ToString());
+                       #endif
+                       Unfocused.Raise (this, e);
+               }
+               public virtual void onEnable(object sender, EventArgs e){
+                       Enabled.Raise (this, e);
+               }
+               public virtual void onDisable(object sender, EventArgs e){
+                       Disabled.Raise (this, e);
+               }
+               protected virtual void onParentChanged(object sender, DataSourceChangeEventArgs e) {
+                       ParentChanged.Raise (this, e);
+                       if (logicalParent == null)
+                               LogicalParentChanged.Raise (this, e);
+               }
+               protected virtual void onLogicalParentChanged(object sender, DataSourceChangeEventArgs e) {
+                       LogicalParentChanged.Raise (this, e);
+               }
+               #region IXmlSerializable
+               public virtual System.Xml.Schema.XmlSchema GetSchema ()
+               {
+                       return null;
+               }
+//             void affectMember(string name, string value){
+//                     Type thisType = this.GetType ();
+//
+//                     if (string.IsNullOrEmpty (value))
+//                             return;
+//
+//                     MemberInfo mi = thisType.GetMember (name).FirstOrDefault();
+//                     if (mi == null) {
+//                             Debug.WriteLine ("XML: Unknown attribute in " + thisType.ToString() + " : " + name);
+//                             return;
+//                     }
+//                     if (mi.MemberType == MemberTypes.Event) {
+//                             this.Bindings.Add (new Binding (new MemberReference(this, mi), value));
+//                             return;
+//                     }
+//                     if (mi.MemberType == MemberTypes.Property) {
+//                             PropertyInfo pi = mi as PropertyInfo;
+//
+//                             if (pi.GetSetMethod () == null) {
+//                                     Debug.WriteLine ("XML: Read only property in " + thisType.ToString() + " : " + name);
+//                                     return;
+//                             }
+//
+//                             XmlAttributeAttribute xaa = (XmlAttributeAttribute)pi.GetCustomAttribute (typeof(XmlAttributeAttribute));
+//                             if (xaa != null) {
+//                                     if (!string.IsNullOrEmpty (xaa.AttributeName))
+//                                             name = xaa.AttributeName;
+//                             }
+//                             if (value.StartsWith("{",StringComparison.Ordinal)) {
+//                                     //binding
+//                                     if (!value.EndsWith("}", StringComparison.Ordinal))
+//                                             throw new Exception (string.Format("XML:Malformed binding: {0}", value));
+//
+//                                     this.Bindings.Add (new Binding (new MemberReference(this, pi), value.Substring (1, value.Length - 2)));
+//                                     return;
+//                             }
+//                             if (pi.GetCustomAttribute (typeof(XmlIgnoreAttribute)) != null)
+//                                     return;
+//                             if (xaa == null)//not define as xmlAttribute
+//                                     return;
+//
+//                             if (pi.PropertyType == typeof(string)) {
+//                                     pi.SetValue (this, value, null);
+//                                     return;
+//                             }
+//
+//                             if (pi.PropertyType.IsEnum) {
+//                                     pi.SetValue (this, Enum.Parse (pi.PropertyType, value), null);
+//                             } else {
+//                                     MethodInfo me = pi.PropertyType.GetMethod ("Parse", new Type[] { typeof(string) });
+//                                     pi.SetValue (this, me.Invoke (null, new string[] { value }), null);
+//                             }
+//                     }
+//             }
+               public virtual void ReadXml (System.Xml.XmlReader reader)
+               {
+                       if (reader.HasAttributes) {
+
+                               style = reader.GetAttribute ("Style");
+
+                               loadDefaultValues ();
+
+                               while (reader.MoveToNextAttribute ()) {
+                                       if (reader.Name == "Style")
+                                               continue;
+
+                                       //affectMember (reader.Name, reader.Value);
+                               }
+                               reader.MoveToElement ();
+                       }else
+                               loadDefaultValues ();
+               }
+               public virtual void WriteXml (System.Xml.XmlWriter writer)
+               {
+                       foreach (PropertyInfo pi in this.GetType().GetProperties(BindingFlags.Public | BindingFlags.Instance)) {
+                               if (pi.GetSetMethod () == null)
+                                       continue;
+
+                               bool isAttribute = false;
+                               bool hasDefaultValue = false;
+                               bool ignore = false;
+                               string name = "";
+                               object value = null;
+                               Type valueType = null;
+
+
+                               MemberInfo mi = pi.GetGetMethod ();
+
+                               if (mi == null)
+                                       continue;
+
+                               value = pi.GetValue (this, null);
+                               valueType = pi.PropertyType;
+                               name = pi.Name;
+
+
+
+                               object[] att = pi.GetCustomAttributes (false);
+
+                               foreach (object o in att) {
+                                       XmlAttributeAttribute xaa = o as XmlAttributeAttribute;
+                                       if (xaa != null) {
+                                               isAttribute = true;
+                                               if (string.IsNullOrEmpty (xaa.AttributeName))
+                                                       name = pi.Name;
+                                               else
+                                                       name = xaa.AttributeName;
+                                               continue;
+                                       }
+
+                                       XmlIgnoreAttribute xia = o as XmlIgnoreAttribute;
+                                       if (xia != null) {
+                                               ignore = true;
+                                               continue;
+                                       }
+
+                                       DefaultValueAttribute dv = o as DefaultValueAttribute;
+                                       if (dv != null) {
+                                               if (dv.Value.Equals (value))
+                                                       hasDefaultValue = true;
+                                               if (dv.Value.ToString () == value.ToString ())
+                                                       hasDefaultValue = true;
+
+                                               continue;
+                                       }
+
+
+                               }
+
+                               if (hasDefaultValue || ignore || value==null)
+                                       continue;
+
+                               if (isAttribute)
+                                       writer.WriteAttributeString (name, value.ToString ());
+                               else {
+                                       if (valueType.GetInterface ("IXmlSerializable") == null)
+                                               continue;
+
+                                       (pi.GetValue (this, null) as IXmlSerializable).WriteXml (writer);
+                               }
+                       }
+                       foreach (EventInfo ei in this.GetType().GetEvents()) {
+                               FieldInfo fi = this.GetType().GetField(ei.Name,
+                                       BindingFlags.NonPublic |
+                                       BindingFlags.Instance |
+                                       BindingFlags.GetField);
+
+                               Delegate dg = (System.Delegate)fi.GetValue (this);
+
+                               if (dg == null)
+                                       continue;
+
+                               foreach (Delegate d in dg.GetInvocationList()) {
+                                       if (!d.Method.Name.StartsWith ("<"))//Skipping empty handler, not clear it's trikky
+                                               writer.WriteAttributeString (ei.Name, d.Method.Name);
+                               }
+                       }
+               }
+               #endregion
+
+               #region ICloneable implementation
+               public object Clone ()
+               {
+                       Type type = this.GetType ();
+                       GraphicObject result = (GraphicObject)Activator.CreateInstance (type);
+                       result.CurrentInterface = CurrentInterface;
+
+                       foreach (PropertyInfo pi in type.GetProperties(BindingFlags.Public | BindingFlags.Instance)) {
+                               if (pi.GetSetMethod () == null)
+                                       continue;
+
+                               if (pi.GetCustomAttribute<XmlIgnoreAttribute> () != null)
+                                       continue;
+                               if (pi.Name == "DataSource")
+                                       continue;
+
+                               pi.SetValue(result, pi.GetValue(this));
+                       }
+                       return result;
+               }
+               #endregion
+               /// <summary>
+               /// full GraphicTree clone with binding definition
+               /// </summary>
+
+               public override string ToString ()
+               {
+                       string tmp ="";
+
+                       if (Parent != null)
+                               tmp = Parent.ToString () + tmp;
+                       #if DEBUG_LAYOUTING
+                       return Name == "unamed" ? tmp + "." + this.GetType ().Name + uid.ToString(): tmp + "." + Name;
+                       #else
+                       return Name == "unamed" ? tmp + "." + this.GetType ().Name : tmp + "." + Name;
+                       #endif
+               }
+       }
+}
diff --git a/src/GraphicObjects/Base/Group.cs b/src/GraphicObjects/Base/Group.cs
new file mode 100644 (file)
index 0000000..d00449c
--- /dev/null
@@ -0,0 +1,408 @@
+//
+// Group.cs
+//
+// Author:
+//       Jean-Philippe Bruyère <jp.bruyere@hotmail.com>
+//
+// Copyright (c) 2013-2017 Jean-Philippe Bruyère
+//
+// 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.Generic;
+using System.ComponentModel;
+using System.Xml.Serialization;
+using Cairo;
+using OpenTK.Input;
+using System.Diagnostics;
+using System.Reflection;
+
+
+namespace Crow
+{
+       public class Group : GraphicObject, IXmlSerializable
+    {
+               #region CTOR
+               public Group()
+                       : base(){}
+               #endregion
+
+               #region EVENT HANDLERS
+               public event EventHandler<EventArgs> ChildrenCleared;
+               #endregion
+
+               internal GraphicObject largestChild = null;
+               internal GraphicObject tallestChild = null;
+
+        bool _multiSelect = false;
+               List<GraphicObject> children = new List<GraphicObject>();
+
+        public virtual List<GraphicObject> Children {
+                       get { return children; }
+               }
+               [XmlAttributeAttribute()][DefaultValue(false)]
+        public bool MultiSelect
+        {
+            get { return _multiSelect; }
+            set { _multiSelect = value; }
+        }
+               public virtual void AddChild(GraphicObject g){
+                       lock (children) {
+                               g.Parent = this;
+                               Children.Add (g);
+                       }
+                       g.RegisteredLayoutings = LayoutingType.None;
+                       g.RegisterForLayouting (LayoutingType.Sizing | LayoutingType.ArrangeChildren);
+                       g.LayoutChanged += OnChildLayoutChanges;
+               }
+        public virtual void RemoveChild(GraphicObject child)        
+               {
+                       child.LayoutChanged -= OnChildLayoutChanges;
+                       //child.Parent = null;
+                       lock (children)
+               Children.Remove(child);
+
+                       if (child == largestChild && Width == Measure.Fit)
+                               searchLargestChild ();
+                       if (child == tallestChild && Height == Measure.Fit)
+                               searchTallestChild ();
+                       
+                       this.RegisterForLayouting (LayoutingType.Sizing | LayoutingType.ArrangeChildren);
+        }
+               public virtual void ClearChildren()
+               {
+                       lock (children) {
+                               while (Children.Count > 0) {
+                                       GraphicObject g = Children [Children.Count - 1];
+                                       g.LayoutChanged -= OnChildLayoutChanges;
+                                       g.Parent = null;
+                                       Children.RemoveAt (Children.Count - 1);
+                               }
+                       }
+
+                       resetChildrenMaxSize ();
+
+                       this.RegisterForLayouting (LayoutingType.Sizing);
+                       ChildrenCleared.Raise (this, new EventArgs ());
+               }
+
+               public void putWidgetOnTop(GraphicObject w)
+               {
+                       if (Children.Contains(w))
+                       {
+                               lock (children) {
+                                       Children.Remove (w);
+                                       Children.Add (w);
+                               }
+                       }
+               }
+               public void putWidgetOnBottom(GraphicObject w)
+               {
+                       if (Children.Contains(w))
+                       {
+                               lock (children) {
+                                       Children.Remove (w);
+                                       Children.Insert (0, w);
+                               }
+                       }
+               }
+
+               #region GraphicObject overrides
+               public override void OnDataSourceChanged (object sender, DataSourceChangeEventArgs e)
+               {
+                       base.OnDataSourceChanged (this, e);
+                       lock (children) {
+                               foreach (GraphicObject g in children)
+                                       if (g.localDataSourceIsNull & g.localLogicalParentIsNull)
+                                               g.OnDataSourceChanged (sender, e);
+                       }
+               }
+               public override GraphicObject FindByName (string nameToFind)
+               {
+                       if (Name == nameToFind)
+                               return this;
+                       GraphicObject tmp = null;
+                       lock (children) {
+                               foreach (GraphicObject w in Children) {
+                                       tmp = w.FindByName (nameToFind);
+                                       if (tmp != null)
+                                               break;
+                               }
+                       }
+                       return tmp;
+               }
+               public override bool Contains (GraphicObject goToFind)
+               {
+                       foreach (GraphicObject w in Children) {
+                               if (w == goToFind)
+                                       return true;
+                               if (w.Contains (goToFind))
+                                       return true;
+                       }
+                       return false;
+               }
+               protected override int measureRawSize (LayoutingType lt)
+               {
+                       if (Children.Count > 0) {
+                               if (lt == LayoutingType.Width) {
+                                       if (largestChild == null)
+                                               searchLargestChild ();
+                                       if (largestChild == null) {
+                                               //if still null, not possible to determine a width
+                                               //because all children are stretched, force first one to fit
+                                               Children [0].Width = Measure.Fit;
+                                               return -1;//cancel actual sizing to let child computation take place
+                                       }
+                               } else {
+                                       if (tallestChild == null)
+                                               searchTallestChild ();
+                                       if (tallestChild == null) {
+                                               Children [0].Height = Measure.Fit;
+                                               return -1;
+                                       }
+                               }
+                       }
+                       return base.measureRawSize (lt);
+               }
+                       
+               public override void OnLayoutChanges (LayoutingType layoutType)
+               {
+                       base.OnLayoutChanges (layoutType);
+
+                       //position smaller objects in group when group size is fit
+                       switch (layoutType) {
+                       case LayoutingType.Width:
+                               foreach (GraphicObject c in Children){
+                                       if (c.Width.Units == Unit.Percent)
+                                               c.RegisterForLayouting (LayoutingType.Width);
+                                       else
+                                               c.RegisterForLayouting (LayoutingType.X);
+                               }
+                               break;
+                       case LayoutingType.Height:
+                               foreach (GraphicObject c in Children) {
+                                       if (c.Height.Units == Unit.Percent)
+                                               c.RegisterForLayouting (LayoutingType.Height);
+                                       else
+                                               c.RegisterForLayouting (LayoutingType.Y);
+                               }
+                               break;
+                       }
+               }
+               protected override void onDraw (Context gr)
+               {
+                       base.onDraw (gr);
+
+                       gr.Save ();
+
+                       if (ClipToClientRect) {
+                               //clip to client zone
+                               CairoHelpers.CairoRectangle (gr, ClientRectangle, CornerRadius);
+                               gr.Clip ();
+                       }
+
+                       lock (children) {
+                               foreach (GraphicObject g in Children) {
+                                       g.Paint (ref gr);
+                               }
+                       }
+                       gr.Restore ();
+               }
+               protected override void UpdateCache (Context ctx)
+               {
+                       Rectangle rb = Slot + Parent.ClientRectangle.Position;
+
+                       using (ImageSurface cache = new ImageSurface (bmp, Format.Argb32, Slot.Width, Slot.Height, 4 * Slot.Width)) {
+                               Context gr = new Context (cache);
+
+                               if (Clipping.count > 0) {
+                                       Clipping.clearAndClip (gr);
+                                       base.onDraw (gr);
+
+                                       //clip to client zone
+                                       CairoHelpers.CairoRectangle (gr, ClientRectangle, CornerRadius);
+                                       gr.Clip ();
+
+                                       lock (Children) {
+                                               foreach (GraphicObject c in Children) {
+                                                       if (!c.Visible)
+                                                               continue;
+                                                       if (Clipping.intersect (c.Slot + ClientRectangle.Position))
+                                                               c.Paint (ref gr);
+                                               }
+                                       }
+
+                                       #if DEBUG_CLIP_RECTANGLE
+                                       Clipping.stroke (gr, Color.Amaranth.AdjustAlpha (0.8));
+                                       #endif
+                               }
+                               gr.Dispose ();
+
+                               ctx.SetSourceSurface (cache, rb.X, rb.Y);
+                               ctx.Paint ();
+                       }
+                       Clipping.Reset();
+               }
+               #endregion
+
+               public virtual void OnChildLayoutChanges (object sender, LayoutingEventArgs arg)
+               {
+                       GraphicObject g = sender as GraphicObject;
+
+                       switch (arg.LayoutType) {
+                       case LayoutingType.Width:
+                               if (Width != Measure.Fit)
+                                       return;
+                               if (g.Slot.Width > contentSize.Width) {
+                                       largestChild = g;
+                                       contentSize.Width = g.Slot.Width;
+                               } else if (g == largestChild)
+                                       searchLargestChild ();
+
+                               this.RegisterForLayouting (LayoutingType.Width);
+                               break;
+                       case LayoutingType.Height:
+                               if (Height != Measure.Fit)
+                                       return;
+                               if (g.Slot.Height > contentSize.Height) {
+                                       tallestChild = g;
+                                       contentSize.Height = g.Slot.Height;
+                               } else if (g == tallestChild)
+                                       searchTallestChild ();
+
+                               this.RegisterForLayouting (LayoutingType.Height);
+                               break;
+                       }
+               }
+               //TODO: x,y position should be taken in account for computation of width and height
+               void resetChildrenMaxSize(){
+                       largestChild = null;
+                       tallestChild = null;
+                       contentSize = 0;
+               }
+               void searchLargestChild(){
+                       #if DEBUG_LAYOUTING
+                       Debug.WriteLine("\tSearch largest child");
+                       #endif
+                       largestChild = null;
+                       contentSize.Width = 0;
+                       for (int i = 0; i < Children.Count; i++) {
+                               if (!Children [i].Visible)
+                                       continue;
+                               if (children [i].RegisteredLayoutings.HasFlag (LayoutingType.Width))
+                                       continue;
+                               if (Children [i].Slot.Width > contentSize.Width) {
+                                       contentSize.Width = Children [i].Slot.Width;
+                                       largestChild = Children [i];
+                               }
+                       }
+               }
+               void searchTallestChild(){
+                       #if DEBUG_LAYOUTING
+                       Debug.WriteLine("\tSearch tallest child");
+                       #endif
+                       tallestChild = null;
+                       contentSize.Height = 0;
+                       for (int i = 0; i < Children.Count; i++) {
+                               if (!Children [i].Visible)
+                                       continue;
+                               if (children [i].RegisteredLayoutings.HasFlag (LayoutingType.Height))
+                                       continue;
+                               if (Children [i].Slot.Height > contentSize.Height) {
+                                       contentSize.Height = Children [i].Slot.Height;
+                                       tallestChild = Children [i];
+                               }
+                       }
+               }
+
+       
+               #region Mouse handling
+               public override void checkHoverWidget (MouseMoveEventArgs e)
+               {
+                       if (CurrentInterface.HoverWidget != this) {
+                               CurrentInterface.HoverWidget = this;
+                               onMouseEnter (this, e);
+                       }
+                       for (int i = Children.Count - 1; i >= 0; i--) {
+                               if (Children[i].MouseIsIn(e.Position))
+                               {
+                                       Children[i].checkHoverWidget (e);
+                                       return;
+                               }
+                       }
+                       base.checkHoverWidget (e);
+               }
+               #endregion
+
+
+               #region IXmlSerializable
+
+        public override System.Xml.Schema.XmlSchema GetSchema()
+        {
+            return null;
+        }
+        public override void ReadXml(System.Xml.XmlReader reader)
+        {
+            base.ReadXml(reader);
+
+            using (System.Xml.XmlReader subTree = reader.ReadSubtree())
+            {
+                subTree.Read();
+
+                while (!subTree.EOF)
+                {
+                    subTree.Read();
+
+                    if (!subTree.IsStartElement())
+                        break;
+
+                    Type t = Type.GetType("Crow." + subTree.Name);
+                                       if (t == null) {
+                                               Assembly a = Assembly.GetEntryAssembly ();
+                                               foreach (Type expT in a.GetExportedTypes ()) {
+                                                       if (expT.Name == subTree.Name) {
+                                                               t = expT;
+                                                               break;
+                                                       }
+                                               }
+                                       }
+                                       if (t == null)
+                                               throw new Exception (subTree.Name + " type not found");
+                    GraphicObject go = (GraphicObject)Activator.CreateInstance(t);
+                    (go as IXmlSerializable).ReadXml(subTree);                    
+                    AddChild(go);
+                }
+            }
+        }
+        public override void WriteXml(System.Xml.XmlWriter writer)
+        {
+            base.WriteXml(writer);
+
+            foreach (GraphicObject go in Children)
+            {
+                writer.WriteStartElement(go.GetType().Name);
+                (go as IXmlSerializable).WriteXml(writer);
+                writer.WriteEndElement();
+            }
+        }
+    
+               #endregion
+
+       }
+}
diff --git a/src/GraphicObjects/Base/GroupBox.cs b/src/GraphicObjects/Base/GroupBox.cs
new file mode 100644 (file)
index 0000000..9cabbb5
--- /dev/null
@@ -0,0 +1,58 @@
+//
+// GroupBox.cs
+//
+// Author:
+//       Jean-Philippe Bruyère <jp.bruyere@hotmail.com>
+//
+// Copyright (c) 2013-2017 Jean-Philippe Bruyère
+//
+// 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.Xml.Serialization;
+using System.ComponentModel;
+
+namespace Crow
+{
+    public class GroupBox : TemplatedContainer
+    {
+               Container _contentContainer;
+
+               #region CTOR
+               public GroupBox() : base(){}
+               #endregion
+
+               #region Template overrides
+               public override GraphicObject Content {
+                       get {
+                               return _contentContainer == null ? null : _contentContainer.Child;
+                       }
+                       set {
+                               _contentContainer.SetChild(value);
+                       }
+               }
+               protected override void loadTemplate(GraphicObject template = null)
+               {
+                       base.loadTemplate (template);
+
+                       _contentContainer = this.child.FindByName ("Content") as Container;
+               }
+               #endregion
+       }
+}
diff --git a/src/GraphicObjects/Base/HorizontalStack.cs b/src/GraphicObjects/Base/HorizontalStack.cs
new file mode 100644 (file)
index 0000000..620dab2
--- /dev/null
@@ -0,0 +1,48 @@
+//
+// HorizontalStack.cs
+//
+// Author:
+//       Jean-Philippe Bruyère <jp.bruyere@hotmail.com>
+//
+// Copyright (c) 2013-2017 Jean-Philippe Bruyère
+//
+// 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.Generic;
+using System.Linq;
+using System.Text;
+using System.Xml.Serialization;
+
+namespace Crow
+{
+    public class HorizontalStack : GenericStack
+    {
+        public HorizontalStack()
+            : base()
+        {            
+        }
+
+        [XmlIgnore]
+        public override Orientation Orientation
+        {
+            get { return Orientation.Horizontal; }
+        }
+    }
+}
diff --git a/src/GraphicObjects/Base/Image.cs b/src/GraphicObjects/Base/Image.cs
new file mode 100644 (file)
index 0000000..6a4c590
--- /dev/null
@@ -0,0 +1,181 @@
+//
+// Image.cs
+//
+// Author:
+//       Jean-Philippe Bruyère <jp.bruyere@hotmail.com>
+//
+// Copyright (c) 2013-2017 Jean-Philippe Bruyère
+//
+// 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 Cairo;
+using System.Xml.Serialization;
+using System.ComponentModel;
+using System.Diagnostics;
+
+
+namespace Crow
+{
+       public class Image : GraphicObject
+       {
+               Picture _pic;
+               string _svgSub;
+               bool scaled, keepProps;
+               double opacity;
+
+               #region Public properties
+               [XmlAttributeAttribute][DefaultValue(true)]
+               public virtual bool Scaled {
+                       get { return scaled; }
+                       set {
+                               if (scaled == value)
+                                       return;
+                               scaled = value;
+                               NotifyValueChanged ("Scaled", scaled);
+                               if (_pic == null)
+                                       return;
+                               _pic.Scaled = scaled;
+                               RegisterForGraphicUpdate ();
+                       }
+               }
+               [XmlAttributeAttribute][DefaultValue(true)]
+               public virtual bool KeepProportions {
+                       get { return keepProps; }
+                       set {
+                               if (keepProps == value)
+                                       return;
+                               keepProps = value;
+                               NotifyValueChanged ("KeepProportions", keepProps);
+                               if (_pic == null)
+                                       return;
+                               _pic.KeepProportions = keepProps;
+                               RegisterForGraphicUpdate ();
+                       }
+               }
+        [XmlAttributeAttribute]
+               public string Path {
+                       get { return _pic == null ? "" : _pic.Path; }
+                       set {
+                               if (value == Path)
+                                       return;
+                               try {
+                                       if (string.IsNullOrEmpty(value))
+                                               Picture = null;
+                                       else {
+                                               lock(CurrentInterface.LayoutMutex){
+                                                       LoadImage (value);
+                                               }
+                                       }
+                               } catch (Exception ex) {
+                                       Debug.WriteLine (ex.Message);
+                                       _pic = null;
+                               }
+                               NotifyValueChanged ("Path", Path);
+                       }
+               }
+               [XmlAttributeAttribute]
+               public string SvgSub {
+                       get { return _svgSub; }
+                       set {
+                               if (_svgSub == value)
+                                       return;
+                               _svgSub = value;
+                               RegisterForGraphicUpdate ();
+                       }
+               }
+               [XmlAttributeAttribute]
+               public Picture Picture {
+                       get { return _pic; }
+                       set {
+                               if (_pic == value)
+                                       return;
+                               _pic = value;
+                               NotifyValueChanged ("Picture", _pic);
+                               RegisterForGraphicUpdate ();
+                       }
+               }
+               [XmlAttributeAttribute()][DefaultValue(1.0)]
+               public virtual double Opacity {
+                       get { return opacity; }
+                       set {
+                               if (opacity == value)
+                                       return;
+                               opacity = value;
+                               NotifyValueChanged ("Faded", opacity);
+                               RegisterForRedraw ();
+                       }
+               }
+               #endregion
+
+               #region CTOR
+               public Image () : base()
+               {
+               }
+               #endregion
+
+               #region Image Loading
+               public void LoadImage (string path)
+               {
+                       Picture pic;
+                       if (path.EndsWith (".svg", true, System.Globalization.CultureInfo.InvariantCulture))
+                               pic = new SvgPicture ();
+                       else
+                               pic = new BmpPicture ();
+
+                       pic.LoadImage (path);
+                       pic.Scaled = scaled;
+                       pic.KeepProportions = keepProps;
+
+                       Picture = pic;
+               }
+               #endregion
+
+               #region GraphicObject overrides
+               protected override int measureRawSize (LayoutingType lt)
+               {
+                       if (_pic == null)
+                               return 2 * Margin;
+                               //_pic = "#Crow.Images.Icons.IconAlerte.svg";
+                       //TODO:take scalling in account
+                       if (lt == LayoutingType.Width)
+                               return _pic.Dimensions.Width + 2 * Margin;
+                       else
+                               return _pic.Dimensions.Height + 2 * Margin;
+               }
+               protected override void onDraw (Context gr)
+               {
+                       base.onDraw (gr);
+
+                       if (_pic == null)
+                               return;
+
+                       _pic.Paint (gr, ClientRectangle, _svgSub);
+
+                       if (Opacity<1.0) {
+                               gr.SetSourceRGBA (0.0, 0.0, 0.0, 1.0-Opacity);
+                               gr.Operator = Operator.DestOut;
+                               gr.Rectangle (ClientRectangle);
+                               gr.Fill ();
+                               gr.Operator = Operator.Over;
+                       }
+               }
+               #endregion
+       }
+}
diff --git a/src/GraphicObjects/Base/Label.cs b/src/GraphicObjects/Base/Label.cs
new file mode 100644 (file)
index 0000000..64ee968
--- /dev/null
@@ -0,0 +1,825 @@
+//
+// Label.cs
+//
+// Author:
+//       Jean-Philippe Bruyère <jp.bruyere@hotmail.com>
+//
+// Copyright (c) 2013-2017 Jean-Philippe Bruyère
+//
+// 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.Generic;
+using System.Linq;
+using System.Diagnostics;
+using Cairo;
+using System.Text.RegularExpressions;
+using System.Xml.Serialization;
+using System.ComponentModel;
+
+namespace Crow
+{
+    public class Label : GraphicObject
+    {
+               #region CTOR
+               public Label()
+               {
+
+               }
+               public Label(string _text)
+                       : base()
+               {
+                       Text = _text;
+               }
+               #endregion
+
+               public event EventHandler<TextChangeEventArgs> TextChanged;
+
+               public virtual void OnTextChanged(Object sender, TextChangeEventArgs e)
+               {
+                       NotifyValueChanged ("Text", Text);
+                       TextChanged.Raise (this, e);
+               }
+        //TODO:change protected to private
+
+               #region private and protected fields
+               string _text = "label";
+        Alignment _textAlignment;
+               bool horizontalStretch;
+               bool verticalStretch;
+               bool _selectable;
+               bool _multiline;
+               Color selBackground;
+               Color selForeground;
+               Point mouseLocalPos = -1;//mouse coord in widget space, filled only when clicked
+               int _currentCol;        //0 based cursor position in string
+               int _currentLine;
+               Point _selBegin = -1;   //selection start (row,column)
+               Point _selRelease = -1; //selection end (row,column)
+               double textCursorPos;   //cursor position in cairo units in widget client coord.
+               double SelStartCursorPos = -1;
+               double SelEndCursorPos = -1;
+               bool SelectionInProgress = false;
+
+        protected Rectangle rText;
+               protected float widthRatio = 1f;
+               protected float heightRatio = 1f;
+               protected FontExtents fe;
+               protected TextExtents te;
+               #endregion
+
+               [XmlAttributeAttribute][DefaultValue("BlueGray")]
+               public virtual Color SelectionBackground {
+                       get { return selBackground; }
+                       set {
+                               if (value == selBackground)
+                                       return;
+                               selBackground = value;
+                               NotifyValueChanged ("SelectionBackground", selBackground);
+                               RegisterForRedraw ();
+                       }
+               }
+               [XmlAttributeAttribute][DefaultValue("White")]
+               public virtual Color SelectionForeground {
+                       get { return selForeground; }
+                       set {
+                               if (value == selForeground)
+                                       return;
+                               selForeground = value;
+                               NotifyValueChanged ("SelectionForeground", selForeground);
+                               RegisterForRedraw ();
+                       }
+               }
+               [XmlAttributeAttribute][DefaultValue(Alignment.Left)]
+               public Alignment TextAlignment
+        {
+            get { return _textAlignment; }
+            set {
+                               if (value == _textAlignment)
+                                       return;
+                               _textAlignment = value;
+                               RegisterForRedraw ();
+                               NotifyValueChanged ("TextAlignment", _textAlignment);
+                       }
+        }
+               [XmlAttributeAttribute][DefaultValue(false)]
+               public virtual bool HorizontalStretch {
+                       get { return horizontalStretch; }
+                       set {
+                               if (horizontalStretch == value)
+                                       return;
+                               horizontalStretch = value;
+                               RegisterForRedraw ();
+                               NotifyValueChanged ("HorizontalStretch", horizontalStretch);
+                       }
+               }
+               [XmlAttributeAttribute][DefaultValue(false)]
+               public virtual bool VerticalStretch {
+                       get { return verticalStretch; }
+                       set {
+                               if (verticalStretch == value)
+                                       return;
+                               verticalStretch = value;
+                               RegisterForRedraw ();
+                               NotifyValueChanged ("VerticalStretch", verticalStretch);
+                       }
+               }
+               [XmlAttributeAttribute][DefaultValue("label")]
+        public string Text
+        {
+            get {
+                               return lines == null ?
+                                       _text : lines.Aggregate((i, j) => i + Interface.LineBreak + j);
+                       }
+            set
+            {
+                               if (string.Equals (value, _text, StringComparison.Ordinal))
+                    return;
+
+                _text = value;
+
+                               if (string.IsNullOrEmpty(_text))
+                                       _text = "";
+
+                               lines = getLines;
+
+                               OnTextChanged (this, new TextChangeEventArgs (Text));
+                               RegisterForGraphicUpdate ();
+            }
+        }
+               [XmlAttributeAttribute][DefaultValue(false)]
+               public bool Selectable
+               {
+                       get { return _selectable; }
+                       set
+                       {
+                               if (value == _selectable)
+                                       return;
+                               _selectable = value;
+                               NotifyValueChanged ("Selectable", _selectable);
+                               SelBegin = -1;
+                               SelRelease = -1;
+                               RegisterForRedraw ();
+                       }
+               }
+               [XmlAttributeAttribute][DefaultValue(false)]
+               public bool Multiline
+               {
+                       get { return _multiline; }
+                       set
+                       {
+                               if (value == _multiline)
+                                       return;
+                               _multiline = value;
+                               NotifyValueChanged ("Multiline", _multiline);
+                               RegisterForGraphicUpdate();
+                       }
+               }
+               [XmlAttributeAttribute][DefaultValue(0)]
+               public int CurrentColumn{
+                       get { return _currentCol; }
+                       set {
+                               if (value == _currentCol)
+                                       return;
+                               if (value < 0)
+                                       _currentCol = 0;
+                               else if (value > lines [_currentLine].Length)
+                                       _currentCol = lines [_currentLine].Length;
+                               else
+                                       _currentCol = value;
+                               NotifyValueChanged ("CurrentColumn", _currentCol);
+                       }
+               }
+               [XmlAttributeAttribute][DefaultValue(0)]
+               public int CurrentLine{
+                       get { return _currentLine; }
+                       set {
+                               if (value == _currentLine)
+                                       return;
+                               if (value >= lines.Count)
+                                       _currentLine = lines.Count-1;
+                               else if (value < 0)
+                                       _currentLine = 0;
+                               else
+                                       _currentLine = value;
+                               //force recheck of currentCol for bounding
+                               int cc = _currentCol;
+                               _currentCol = 0;
+                               CurrentColumn = cc;
+                               NotifyValueChanged ("CurrentLine", _currentLine);
+                       }
+               }
+               [XmlIgnore]public Point CurrentPosition {
+                       get { return new Point(_currentCol, CurrentLine); }
+               }
+               //TODO:using HasFocus for drawing selection cause SelBegin and Release binding not to work
+               /// <summary>
+               /// Selection begin position in char units
+               /// </summary>
+               [XmlAttributeAttribute][DefaultValue("-1")]
+               public Point SelBegin {
+                       get {
+                               return _selBegin;
+                       }
+                       set {
+                               if (value == _selBegin)
+                                       return;
+                               _selBegin = value;
+                               NotifyValueChanged ("SelBegin", _selBegin);
+                               NotifyValueChanged ("SelectedText", SelectedText);
+                       }
+               }
+               [XmlAttributeAttribute][DefaultValue("-1")]
+               public Point SelRelease {
+                       get {
+                               return _selRelease;
+                       }
+                       set {
+                               if (value == _selRelease)
+                                       return;
+                               _selRelease = value;
+                               NotifyValueChanged ("SelRelease", _selRelease);
+                               NotifyValueChanged ("SelectedText", SelectedText);
+                       }
+               }
+               /// <summary>
+               /// return char at CurrentLine, CurrentColumn
+               /// </summary>
+               [XmlIgnore]protected Char CurrentChar
+               {
+                       get {
+                               return lines [CurrentLine] [CurrentColumn];
+                       }
+               }
+               /// <summary>
+               /// ordered selection start and end positions in char units
+               /// </summary>
+               [XmlIgnore]protected Point selectionStart
+               {
+                       get {
+                               return SelRelease < 0 || SelBegin.Y < SelRelease.Y ? SelBegin :
+                                       SelBegin.Y > SelRelease.Y ? SelRelease :
+                                       SelBegin.X < SelRelease.X ? SelBegin : SelRelease;
+                       }
+               }
+               [XmlIgnore]public Point selectionEnd
+               {
+                       get {
+                               return SelRelease < 0 || SelBegin.Y > SelRelease.Y ? SelBegin :
+                                       SelBegin.Y < SelRelease.Y ? SelRelease :
+                                       SelBegin.X > SelRelease.X ? SelBegin : SelRelease;
+                       }
+               }
+               [XmlIgnore]public string SelectedText
+               {
+                       get {
+
+                               if (SelRelease < 0 || SelBegin < 0)
+                                       return "";
+                               if (selectionStart.Y == selectionEnd.Y)
+                                       return lines [selectionStart.Y].Substring (selectionStart.X, selectionEnd.X - selectionStart.X);
+                               string tmp = "";
+                               tmp = lines [selectionStart.Y].Substring (selectionStart.X);
+                               for (int l = selectionStart.Y + 1; l < selectionEnd.Y; l++) {
+                                       tmp += Interface.LineBreak + lines [l];
+                               }
+                               tmp += Interface.LineBreak + lines [selectionEnd.Y].Substring (0, selectionEnd.X);
+                               return tmp;
+                       }
+               }
+               [XmlIgnore]public bool selectionIsEmpty
+               { get { return SelRelease < 0; } }
+
+               List<string> lines;
+               List<string> getLines {
+                       get {
+                               return _multiline ?
+                                       Regex.Split (_text, "\r\n|\r|\n|\\\\n").ToList() :
+                                       new List<string>(new string[] { _text });
+                       }
+               }
+               /// <summary>
+               /// Moves cursor one char to the left.
+               /// </summary>
+               /// <returns><c>true</c> if move succeed</returns>
+               public bool MoveLeft(){
+                       int tmp = _currentCol - 1;
+                       if (tmp < 0) {
+                               if (_currentLine == 0)
+                                       return false;
+                               CurrentLine--;
+                               CurrentColumn = int.MaxValue;
+                       } else
+                               CurrentColumn = tmp;
+                       return true;
+               }
+               /// <summary>
+               /// Moves cursor one char to the right.
+               /// </summary>
+               /// <returns><c>true</c> if move succeed</returns>
+               public bool MoveRight(){
+                       int tmp = _currentCol + 1;
+                       if (tmp > lines [_currentLine].Length){
+                               if (CurrentLine == lines.Count - 1)
+                                       return false;
+                               CurrentLine++;
+                               CurrentColumn = 0;
+                       } else
+                               CurrentColumn = tmp;
+                       return true;
+               }
+               public void GotoWordStart(){
+                       CurrentColumn--;
+                       //skip white spaces
+                       while (!char.IsLetterOrDigit (this.CurrentChar) && CurrentColumn > 0)
+                               CurrentColumn--;
+                       while (char.IsLetterOrDigit (lines [CurrentLine] [CurrentColumn]) && CurrentColumn > 0)
+                               CurrentColumn--;
+                       if (!char.IsLetterOrDigit (this.CurrentChar))
+                               CurrentColumn++;
+               }
+               public void GotoWordEnd(){
+                       //skip white spaces
+                       if (CurrentColumn >= lines [CurrentLine].Length - 1)
+                               return;
+                       while (!char.IsLetterOrDigit (this.CurrentChar) && CurrentColumn < lines [CurrentLine].Length-1)
+                               CurrentColumn++;
+                       while (char.IsLetterOrDigit (this.CurrentChar) && CurrentColumn < lines [CurrentLine].Length-1)
+                               CurrentColumn++;
+                       if (char.IsLetterOrDigit (this.CurrentChar))
+                               CurrentColumn++;
+               }
+               public void DeleteChar()
+               {
+                       if (selectionIsEmpty) {
+                               if (CurrentColumn == 0) {
+                                       if (CurrentLine == 0 && lines.Count == 1)
+                                               return;
+                                       CurrentLine--;
+                                       CurrentColumn = lines [CurrentLine].Length;
+                                       lines [CurrentLine] += lines [CurrentLine + 1];
+                                       lines.RemoveAt (CurrentLine + 1);
+
+                                       OnTextChanged (this, new TextChangeEventArgs (Text));
+                                       return;
+                               }
+                               CurrentColumn--;
+                               lines [CurrentLine] = lines [CurrentLine].Remove (CurrentColumn, 1);
+                       } else {
+                               int linesToRemove = selectionEnd.Y - selectionStart.Y + 1;
+                               int l = selectionStart.Y;
+
+                               if (linesToRemove > 0) {
+                                       lines [l] = lines [l].Remove (selectionStart.X, lines [l].Length - selectionStart.X) +
+                                               lines [selectionEnd.Y].Substring (selectionEnd.X, lines [selectionEnd.Y].Length - selectionEnd.X);
+                                       l++;
+                                       for (int c = 0; c < linesToRemove-1; c++)
+                                               lines.RemoveAt (l);
+                                       CurrentLine = selectionStart.Y;
+                                       CurrentColumn = selectionStart.X;
+                               } else
+                                       lines [l] = lines [l].Remove (selectionStart.X, selectionEnd.X - selectionStart.X);
+                               CurrentColumn = selectionStart.X;
+                               SelBegin = -1;
+                               SelRelease = -1;
+                       }
+                       OnTextChanged (this, new TextChangeEventArgs (Text));
+               }
+               /// <summary>
+               /// Insert new string at caret position, should be sure no line break is inside.
+               /// </summary>
+               /// <param name="str">String.</param>
+               protected void Insert(string str)
+               {
+                       if (!selectionIsEmpty)
+                               this.DeleteChar ();
+                       if (_multiline) {
+                               string[] strLines = Regex.Split (str, "\r\n|\r|\n|" + @"\\n").ToArray();
+                               lines [CurrentLine] = lines [CurrentLine].Insert (CurrentColumn, strLines[0]);
+                               CurrentColumn += strLines[0].Length;
+                               for (int i = 1; i < strLines.Length; i++) {
+                                       InsertLineBreak ();
+                                       lines [CurrentLine] = lines [CurrentLine].Insert (CurrentColumn, strLines[i]);
+                                       CurrentColumn += strLines[i].Length;
+                               }
+                       } else {
+                               lines [CurrentLine] = lines [CurrentLine].Insert (CurrentColumn, str);
+                               CurrentColumn += str.Length;
+                       }
+                       OnTextChanged (this, new TextChangeEventArgs (Text));
+               }
+               /// <summary>
+               /// Insert a line break.
+               /// </summary>
+               protected void InsertLineBreak()
+               {
+                       lines.Insert(CurrentLine + 1, lines[CurrentLine].Substring(CurrentColumn));
+                       lines [CurrentLine] = lines [CurrentLine].Substring (0, CurrentColumn);
+                       CurrentLine++;
+                       CurrentColumn = 0;
+                       OnTextChanged (this, new TextChangeEventArgs (Text));
+               }
+
+               #region GraphicObject overrides
+               protected override int measureRawSize(LayoutingType lt)
+        {
+                       if (lines == null)
+                               lines = getLines;
+
+                       using (ImageSurface img = new ImageSurface (Format.Argb32, 10, 10)) {
+                               using (Context gr = new Context (img)) {
+                                       //Cairo.FontFace cf = gr.GetContextFontFace ();
+
+                                       gr.SelectFontFace (Font.Name, Font.Slant, Font.Wheight);
+                                       gr.SetFontSize (Font.Size);
+
+
+                                       fe = gr.FontExtents;
+                                       te = new TextExtents();
+
+                                       if (lt == LayoutingType.Height){
+                                               int lc = lines.Count;
+                                               //ensure minimal height = text line height
+                                               if (lc == 0)
+                                                       lc = 1;
+
+                                               return (int)Math.Ceiling(fe.Height * lc) + Margin * 2;
+                                       }
+                                       try {
+                                               foreach (string s in lines) {
+                                                       string l = s.Replace("\t", new String (' ', Interface.TabSize));
+
+                                                       TextExtents tmp = gr.TextExtents (l);
+
+                                                       if (tmp.XAdvance > te.XAdvance)
+                                                               te = tmp;
+                                               }
+                                       } catch (Exception ex) {
+                                               return -1;
+                                       }
+                                       return (int)Math.Ceiling (te.XAdvance) + Margin * 2;
+                               }
+                       }
+        }
+               protected override void onDraw (Context gr)
+               {
+                       base.onDraw (gr);
+
+                       gr.SelectFontFace (Font.Name, Font.Slant, Font.Wheight);
+                       gr.SetFontSize (Font.Size);
+                       gr.FontOptions = Interface.FontRenderingOptions;
+                       gr.Antialias = Interface.Antialias;
+
+                       rText = new Rectangle(new Size(
+                               measureRawSize(LayoutingType.Width), measureRawSize(LayoutingType.Height)));
+                       rText.Width -= 2 * Margin;
+                       rText.Height -= 2 * Margin;
+
+                       widthRatio = 1f;
+                       heightRatio = 1f;
+
+                       Rectangle cb = ClientRectangle;
+
+                       rText.X = cb.X;
+                       rText.Y = cb.Y;
+
+                       if (horizontalStretch) {
+                               widthRatio = (float)cb.Width / (float)rText.Width;
+                               if (!verticalStretch)
+                                       heightRatio = widthRatio;
+                       }
+
+                       if (verticalStretch) {
+                               heightRatio = (float)cb.Height / (float)rText.Height;
+                               if (!horizontalStretch)
+                                       widthRatio = heightRatio;
+                       }
+
+                       rText.Width = (int)(widthRatio * (float)rText.Width);
+                       rText.Height = (int)(heightRatio * (float)rText.Height);
+
+                       switch (TextAlignment)
+                       {
+                       case Alignment.TopLeft:     //ok
+                               rText.X = cb.X;
+                               rText.Y = cb.Y;
+                               break;
+                       case Alignment.Top:   //ok
+                               rText.Y = cb.Y;
+                               rText.X = cb.X + cb.Width / 2 - rText.Width / 2;
+                               break;
+                       case Alignment.TopRight:    //ok
+                               rText.Y = cb.Y;
+                               rText.X = cb.Right - rText.Width;
+                               break;
+                       case Alignment.Left://ok
+                               rText.X = cb.X;
+                               rText.Y = cb.Y + cb.Height / 2 - rText.Height / 2;
+                               break;
+                       case Alignment.Right://ok
+                               rText.X = cb.X + cb.Width - rText.Width;
+                               rText.Y = cb.Y + cb.Height / 2 - rText.Height / 2;
+                               break;
+                       case Alignment.Bottom://ok
+                               rText.X = cb.Width / 2 - rText.Width / 2;
+                               rText.Y = cb.Height - rText.Height;
+                               break;
+                       case Alignment.BottomLeft://ok
+                               rText.X = cb.X;
+                               rText.Y = cb.Bottom - rText.Height;
+                               break;
+                       case Alignment.BottomRight://ok
+                               rText.Y = cb.Bottom - rText.Height;
+                               rText.X = cb.Right - rText.Width;
+                               break;
+                       case Alignment.Center://ok
+                               rText.X = cb.X + cb.Width / 2 - rText.Width / 2;
+                               rText.Y = cb.Y + cb.Height / 2 - rText.Height / 2;
+                               break;
+                       }
+
+                       gr.FontMatrix = new Matrix(widthRatio * (float)Font.Size, 0, 0, heightRatio * (float)Font.Size, 0, 0);
+                       fe = gr.FontExtents;
+
+                       #region draw text cursor
+                       if (HasFocus && Selectable)
+                       {
+                               if (mouseLocalPos >= 0)
+                               {
+                                       computeTextCursor(gr);
+
+                                       if (SelectionInProgress)
+                                       {
+                                               if (SelBegin < 0){
+                                                       SelBegin = new Point(CurrentColumn, CurrentLine);
+                                                       SelStartCursorPos = textCursorPos;
+                                                       SelRelease = -1;
+                                               }else{
+                                                       SelRelease = new Point(CurrentColumn, CurrentLine);
+                                                       if (SelRelease == SelBegin)
+                                                               SelRelease = -1;
+                                                       else
+                                                               SelEndCursorPos = textCursorPos;
+                                               }
+                                       }else
+                                               computeTextCursorPosition(gr);
+                               }else
+                                       computeTextCursorPosition(gr);
+
+                               Foreground.SetAsSource (gr);
+                               gr.LineWidth = 1.0;
+                               gr.MoveTo (0.5 + textCursorPos + rText.X, rText.Y + CurrentLine * fe.Height);
+                               gr.LineTo (0.5 + textCursorPos + rText.X, rText.Y + (CurrentLine + 1) * fe.Height);
+                               gr.Stroke();
+                       }
+                       #endregion
+
+                       //****** debug selection *************
+//                     if (SelRelease >= 0) {
+//                             new SolidColor(Color.DarkGreen).SetAsSource(gr);
+//                             Rectangle R = new Rectangle (
+//                                                  rText.X + (int)SelEndCursorPos - 3,
+//                                                  rText.Y + (int)(SelRelease.Y * fe.Height),
+//                                                  6,
+//                                                  (int)fe.Height);
+//                             gr.Rectangle (R);
+//                             gr.Fill ();
+//                     }
+//                     if (SelBegin >= 0) {
+//                             new SolidColor(Color.DarkRed).SetAsSource(gr);
+//                             Rectangle R = new Rectangle (
+//                                     rText.X + (int)SelStartCursorPos - 3,
+//                                     rText.Y + (int)(SelBegin.Y * fe.Height),
+//                                     6,
+//                                     (int)fe.Height);
+//                             gr.Rectangle (R);
+//                             gr.Fill ();
+//                     }
+                       //*******************
+
+                       for (int i = 0; i < lines.Count; i++) {
+                               string l = lines [i].Replace ("\t", new String (' ', Interface.TabSize));
+                               int lineLength = (int)gr.TextExtents (l).XAdvance;
+                               Rectangle lineRect = new Rectangle (
+                                       rText.X,
+                                       rText.Y + (int)Math.Ceiling(i * fe.Height),
+                                       lineLength,
+                                       (int)Math.Ceiling(fe.Height));
+
+//                             if (TextAlignment == Alignment.Center ||
+//                                     TextAlignment == Alignment.Top ||
+//                                     TextAlignment == Alignment.Bottom)
+//                                     lineRect.X += (rText.Width - lineLength) / 2;
+//                             else if (TextAlignment == Alignment.Right ||
+//                                     TextAlignment == Alignment.TopRight ||
+//                                     TextAlignment == Alignment.BottomRight)
+//                                     lineRect.X += (rText.Width - lineLength);
+                               if (string.IsNullOrWhiteSpace (l))
+                                       continue;
+
+                               Foreground.SetAsSource (gr);
+                               gr.MoveTo (lineRect.X, rText.Y + fe.Ascent + fe.Height * i);
+                               gr.ShowText (l);
+                               gr.Fill ();
+
+                               if (Selectable) {
+                                       if (SelRelease >= 0 && i >= selectionStart.Y && i <= selectionEnd.Y) {
+                                               gr.SetSourceColor (selBackground);
+
+                                               Rectangle selRect = lineRect;
+
+                                               int cpStart = (int)SelStartCursorPos,
+                                               cpEnd = (int)SelEndCursorPos;
+
+                                               if (SelBegin.Y > SelRelease.Y) {
+                                                       cpStart = cpEnd;
+                                                       cpEnd = (int)SelStartCursorPos;
+                                               }
+
+                                               if (i == selectionStart.Y) {
+                                                       selRect.Width -= cpStart;
+                                                       selRect.Left += cpStart;
+                                               }
+                                               if (i == selectionEnd.Y)
+                                                       selRect.Width -= (lineLength - cpEnd);
+
+                                               gr.Rectangle (selRect);
+                                               gr.FillPreserve ();
+                                               gr.Save ();
+                                               gr.Clip ();
+                                               gr.SetSourceColor (SelectionForeground);
+                                               gr.MoveTo (lineRect.X, rText.Y + fe.Ascent + fe.Height * i);
+                                               gr.ShowText (l);
+                                               gr.Fill ();
+                                               gr.Restore ();
+                                       }
+                               }
+                       }
+               }
+               #endregion
+
+               #region Mouse handling
+               void updatemouseLocalPos(Point mpos){
+                       mouseLocalPos = mpos - ScreenCoordinates(Slot).TopLeft - ClientRectangle.TopLeft;
+                       if (mouseLocalPos.X < 0)
+                               mouseLocalPos.X = 0;
+                       if (mouseLocalPos.Y < 0)
+                               mouseLocalPos.Y = 0;
+               }
+               public override void onMouseEnter (object sender, MouseMoveEventArgs e)
+               {
+                       base.onMouseEnter (sender, e);
+                       if (Selectable)
+                               CurrentInterface.MouseCursor = XCursor.Text;
+               }
+               public override void onMouseLeave (object sender, MouseMoveEventArgs e)
+               {
+                       base.onMouseLeave (sender, e);
+                       CurrentInterface.MouseCursor = XCursor.Default;
+               }
+               protected override void onFocused (object sender, EventArgs e)
+               {
+                       base.onFocused (sender, e);
+
+                       if (!_selectable)
+                               return;
+                       SelBegin = new Point(0,0);
+                       SelRelease = new Point (lines.LastOrDefault ().Length, lines.Count-1);
+                       RegisterForRedraw ();
+               }
+               protected override void onUnfocused (object sender, EventArgs e)
+               {
+                       base.onUnfocused (sender, e);
+
+                       SelBegin = -1;
+                       SelRelease = -1;
+                       RegisterForRedraw ();
+               }
+               public override void onMouseMove (object sender, MouseMoveEventArgs e)
+               {
+                       base.onMouseMove (sender, e);
+
+                       if (!(SelectionInProgress && HasFocus && _selectable))
+                               return;
+
+                       updatemouseLocalPos (e.Position);
+
+                       RegisterForRedraw();
+               }
+               public override void onMouseDown (object sender, MouseButtonEventArgs e)
+               {
+                       if (this.HasFocus && _selectable){
+                               updatemouseLocalPos (e.Position);
+                               SelBegin = -1;
+                               SelRelease = -1;
+                               SelectionInProgress = true;
+                               RegisterForRedraw();//TODO:should put it in properties
+                       }
+
+                       //done at the end to set 'hasFocus' value after testing it
+                       base.onMouseDown (sender, e);
+               }
+               public override void onMouseUp (object sender, MouseButtonEventArgs e)
+               {
+                       base.onMouseUp (sender, e);
+
+                       if (!SelectionInProgress)
+                               return;
+
+                       updatemouseLocalPos (e.Position);
+                       SelectionInProgress = false;
+                       RegisterForRedraw ();
+               }
+               public override void onMouseDoubleClick (object sender, MouseButtonEventArgs e)
+               {
+                       base.onMouseDoubleClick (sender, e);
+
+                       GotoWordStart ();
+                       SelBegin = CurrentPosition;
+                       GotoWordEnd ();
+                       SelRelease = CurrentPosition;
+                       SelectionInProgress = false;
+                       RegisterForRedraw ();
+               }
+               #endregion
+
+               /// <summary>
+               /// Update Current Column, line and TextCursorPos
+               /// from mouseLocalPos
+               /// </summary>
+               void computeTextCursor(Context gr)
+               {
+                       TextExtents te;
+
+                       double cPos = 0f;
+
+                       CurrentLine = (int)(mouseLocalPos.Y / fe.Height);
+
+                       //fix cu
+                       if (CurrentLine >= lines.Count)
+                               CurrentLine = lines.Count - 1;
+
+                       for (int i = 0; i < lines[CurrentLine].Length; i++)
+                       {
+                               string c = lines [CurrentLine].Substring (i, 1);
+                               if (c == "\t")
+                                       c = new string (' ', Interface.TabSize);
+
+                               te = gr.TextExtents(c);
+
+                               double halfWidth = te.XAdvance / 2;
+
+                               if (mouseLocalPos.X <= cPos + halfWidth)
+                               {
+                                       CurrentColumn = i;
+                                       textCursorPos = cPos;
+                                       mouseLocalPos = -1;
+                                       return;
+                               }
+
+                               cPos += te.XAdvance;
+                       }
+                       CurrentColumn = lines[CurrentLine].Length;
+                       textCursorPos = cPos;
+
+                       //reset mouseLocalPos
+                       mouseLocalPos = -1;
+               }
+               /// <summary> Computes offsets in cairo units </summary>
+               void computeTextCursorPosition(Context gr)
+               {
+                       if (SelBegin >= 0)
+                               SelStartCursorPos = GetXFromTextPointer (gr, SelBegin);
+                       if (SelRelease >= 0)
+                               SelEndCursorPos = GetXFromTextPointer (gr, SelRelease);
+                       textCursorPos = GetXFromTextPointer (gr, new Point(CurrentColumn, CurrentLine));
+               }
+               /// <summary> Compute x offset in cairo unit from text position </summary>
+               double GetXFromTextPointer(Context gr, Point pos)
+               {
+                       try {
+                               string l = lines [pos.Y].Substring (0, pos.X).
+                                       Replace ("\t", new String (' ', Interface.TabSize));
+                               return gr.TextExtents (l).XAdvance;
+                       } catch{
+                               return -1;
+                       }
+               }
+    }
+}
diff --git a/src/GraphicObjects/Base/ListBox.cs b/src/GraphicObjects/Base/ListBox.cs
new file mode 100644 (file)
index 0000000..f66edf6
--- /dev/null
@@ -0,0 +1,47 @@
+//
+// ListBox.cs
+//
+// Author:
+//       Jean-Philippe Bruyère <jp.bruyere@hotmail.com>
+//
+// Copyright (c) 2013-2017 Jean-Philippe Bruyère
+//
+// 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.Xml.Serialization;
+using System.ComponentModel;
+using System.IO;
+using System.Diagnostics;
+using System.Xml;
+using System.Collections.Generic;
+using System.Threading;
+
+namespace Crow
+{
+       public class ListBox : TemplatedGroup
+       {
+               #region CTOR
+               public ListBox () : base() {}
+               #endregion
+
+       }
+}
+
diff --git a/src/GraphicObjects/Base/Menu.cs b/src/GraphicObjects/Base/Menu.cs
new file mode 100644 (file)
index 0000000..5049481
--- /dev/null
@@ -0,0 +1,76 @@
+//
+// Menu.cs
+//
+// Author:
+//       Jean-Philippe Bruyère <jp.bruyere@hotmail.com>
+//
+// Copyright (c) 2013-2017 Jean-Philippe Bruyère
+//
+// 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.Xml.Serialization;
+using System.ComponentModel;
+
+namespace Crow
+{
+       public class Menu : TemplatedGroup
+       {
+               #region CTOR
+               public Menu () : base() {}
+               #endregion
+
+               Orientation orientation;
+               bool autoOpen = false;
+
+               #region Public properties
+               [XmlAttributeAttribute][DefaultValue(Orientation.Horizontal)]
+               public Orientation Orientation {
+                       get { return orientation; }
+                       set {
+                               if (orientation == value)
+                                       return;
+                               orientation = value;
+                               NotifyValueChanged ("Orientation", orientation);
+                       }
+               }
+               [XmlIgnore]public bool AutomaticOpenning
+               {
+                       get { return autoOpen; }
+                       set     { autoOpen = value;     }
+               }
+               #endregion
+
+               public override void AddItem (GraphicObject g)
+               {                       
+                       base.AddItem (g);
+
+                       if (orientation == Orientation.Horizontal)
+                               g.NotifyValueChanged ("PopDirection", Alignment.Bottom);
+                       else
+                               g.NotifyValueChanged ("PopDirection", Alignment.Right);
+               }
+               public override void onMouseLeave (object sender, MouseMoveEventArgs e)
+               {
+                       base.onMouseLeave (sender, e);
+                       AutomaticOpenning = false;
+               }
+       }
+}
+
diff --git a/src/GraphicObjects/Base/MenuItem.cs b/src/GraphicObjects/Base/MenuItem.cs
new file mode 100644 (file)
index 0000000..0d99a2e
--- /dev/null
@@ -0,0 +1,174 @@
+//
+// MenuItem.cs
+//
+// Author:
+//       Jean-Philippe Bruyère <jp.bruyere@hotmail.com>
+//
+// Copyright (c) 2013-2017 Jean-Philippe Bruyère
+//
+// 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.Xml.Serialization;
+using System.ComponentModel;
+
+namespace Crow
+{
+       public class MenuItem : Menu
+       {
+               #region CTOR
+               public MenuItem () : base() {}
+               #endregion
+
+               public event EventHandler Open;
+               public event EventHandler Close;
+
+               string caption;
+               Command command;
+               Picture icon;
+               bool isOpened;
+               Measure popWidth, popHeight;
+
+               #region Public properties
+               [XmlAttributeAttribute][DefaultValue(false)]
+               public bool IsOpened {
+                       get { return isOpened; }
+                       set {
+                               if (isOpened == value)
+                                       return;
+                               isOpened = value;
+                               NotifyValueChanged ("IsOpened", isOpened);
+
+                               if (isOpened) {
+                                       onOpen (this, null);
+                                       (LogicalParent as Menu).AutomaticOpenning = true;
+                               }else
+                                       onClose (this, null);
+                       }
+               }
+               [XmlAttributeAttribute][DefaultValue(null)]
+               public virtual Command Command {
+                       get { return command; }
+                       set {
+                               if (command == value)
+                                       return;
+
+                               if (command != null) {
+                                       command.raiseAllValuesChanged ();
+                                       command.ValueChanged -= Command_ValueChanged;
+                               }
+
+                               command = value;
+
+                               if (command != null) {
+                                       command.ValueChanged += Command_ValueChanged;
+                                       command.raiseAllValuesChanged ();
+                               }
+
+                               NotifyValueChanged ("Command", command);
+                       }
+               }
+               [XmlAttributeAttribute]
+               public override bool IsEnabled {
+                       get { return Command == null ? base.IsEnabled : Command.CanExecute; }
+                       set { base.IsEnabled = value; }
+               }
+               [XmlAttributeAttribute]
+               public override string Caption {
+                       get { return Command == null ? base.Caption : Command.Caption; }
+                       set { base.Caption = value; }
+               }
+               [XmlAttributeAttribute]
+               public Picture Icon {
+                       get { return Command == null ? icon : Command.Icon;; }
+                       set {
+                               if (icon == value)
+                                       return;
+                               icon = value;
+                               if (command == null)
+                                       NotifyValueChanged ("Icon", icon);
+                       }
+               }
+               [XmlAttributeAttribute()][DefaultValue("Fit")]
+               public virtual Measure PopWidth {
+                       get { return popWidth; }
+                       set {
+                               if (popWidth == value)
+                                       return;
+                               popWidth = value;
+                               NotifyValueChanged ("PopWidth", popWidth);
+                       }
+               }
+               [XmlAttributeAttribute()][DefaultValue("Fit")]
+               public virtual Measure PopHeight {
+                       get { return popHeight; }
+                       set {
+                               if (popHeight == value)
+                                       return;
+                               popHeight = value;
+                               NotifyValueChanged ("PopHeight", popHeight);
+                       }
+               }
+               #endregion
+
+               public override void AddItem (GraphicObject g)
+               {
+                       base.AddItem (g);
+                       g.NotifyValueChanged ("PopDirection", Alignment.Right);
+               }
+
+               void Command_ValueChanged (object sender, ValueChangeEventArgs e)
+               {
+                       string mName = e.MemberName;
+                       if (mName == "CanExecute")
+                               mName = "IsEnabled";
+                       NotifyValueChanged (mName, e.NewValue);
+               }
+               void onMI_Click (object sender, MouseButtonEventArgs e)
+               {
+                       if (command != null)
+                               command.Execute ();
+                       if(!IsOpened)
+                               (LogicalParent as Menu).AutomaticOpenning = false;
+               }
+               protected virtual void onOpen (object sender, EventArgs e){
+                       Open.Raise (this, null);
+               }
+               protected virtual void onClose (object sender, EventArgs e){
+                       Close.Raise (this, null);
+               }
+               public override bool MouseIsIn (Point m)
+               {
+                       return IsEnabled ? base.MouseIsIn (m) || child.MouseIsIn (m) : false;
+               }
+               public override void onMouseEnter (object sender, MouseMoveEventArgs e)
+               {
+                       base.onMouseEnter (sender, e);
+                       if ((LogicalParent as Menu).AutomaticOpenning && items.Children.Count>0)
+                               IsOpened = true;
+               }
+               public override void onMouseLeave (object sender, MouseMoveEventArgs e)
+               {
+                       if (IsOpened)
+                               IsOpened = false;
+                       base.onMouseLeave (this, e);
+               }
+       }
+}
+
diff --git a/src/GraphicObjects/Base/MessageBox.cs b/src/GraphicObjects/Base/MessageBox.cs
new file mode 100644 (file)
index 0000000..d8ce1da
--- /dev/null
@@ -0,0 +1,150 @@
+//
+// MessageBox.cs
+//
+// Author:
+//       Jean-Philippe Bruyère <jp.bruyere@hotmail.com>
+//
+// Copyright (c) 2013-2017 Jean-Philippe Bruyère
+//
+// 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.Xml.Serialization;
+using System.ComponentModel;
+
+namespace Crow
+{
+       public class MessageBox : Window
+       {
+               public enum Type {
+                       Information,
+                       YesNo,
+                       Alert,
+                       Error
+               }
+               public MessageBox (): base(){}
+
+               protected override void loadTemplate (GraphicObject template)
+               {
+                       base.loadTemplate (template);
+                       NotifyValueChanged ("MsgIcon", "#Crow.Images.Icons.Informations.svg");
+               }
+               string message, okMessage, cancelMessage;
+               Type msgType = Type.Information;
+
+               public event EventHandler Ok;
+               public event EventHandler Cancel;
+
+               [XmlAttributeAttribute][DefaultValue("Informations")]
+               public virtual string Message
+               {
+                       get { return message; }
+                       set {
+                               if (message == value)
+                                       return;
+                               message = value;
+                               NotifyValueChanged ("Message", message);
+                       }
+               }
+               [XmlAttributeAttribute][DefaultValue("Ok")]
+               public virtual string OkMessage
+               {
+                       get { return okMessage; }
+                       set {
+                               if (okMessage == value)
+                                       return;
+                               okMessage = value;
+                               NotifyValueChanged ("OkMessage", okMessage);
+                       }
+               }
+               [XmlAttributeAttribute][DefaultValue("Cancel")]
+               public virtual string CancelMessage
+               {
+                       get { return cancelMessage; }
+                       set {
+                               if (cancelMessage == value)
+                                       return;
+                               cancelMessage = value;
+                               NotifyValueChanged ("CancelMessage", cancelMessage);
+                       }
+               }
+               [XmlAttributeAttribute][DefaultValue("Information")]
+               public virtual Type MsgType
+               {
+                       get { return msgType; }
+                       set {
+                               if (msgType == value)
+                                       return;
+                               msgType = value;
+                               NotifyValueChanged ("MsgType", msgType);
+                               switch (msgType) {
+                               case Type.Information:
+                                       NotifyValueChanged ("MsgIcon", "#Crow.Images.Icons.Informations.svg");
+                                       Caption = "Informations";
+                                       OkMessage = "Ok";
+                                       CancelMessage = "Cancel";
+                                       break;
+                               case Type.YesNo:
+                                       NotifyValueChanged ("MsgIcon", "#Crow.Icons.question.svg");
+                                       Caption = "Choice";
+                                       OkMessage = "Yes";
+                                       CancelMessage = "No";
+                                       break;
+                               case Type.Alert:
+                                       NotifyValueChanged ("MsgIcon", "#Crow.Images.Icons.IconAlerte.svg");
+                                       Caption = "Alert";
+                                       OkMessage = "Ok";
+                                       CancelMessage = "Cancel";
+                                       break;
+                               case Type.Error:
+                                       NotifyValueChanged ("MsgIcon", "#Crow.Images.Icons.exit.svg");
+                                       Caption = "Error";
+                                       OkMessage = "Ok";
+                                       CancelMessage = "Cancel";
+                                       break;
+                               }
+                       }
+               }
+               void onOkButtonClick (object sender, EventArgs e)
+               {
+                       Ok.Raise (this, null);
+                       close ();
+               }
+               void onCancelButtonClick (object sender, EventArgs e)
+               {
+                       Cancel.Raise (this, null);
+                       close ();
+               }
+               public static MessageBox Show (Type msgBoxType, string message, string okMsg = "", string cancelMsg = ""){
+                       lock (Interface.CurrentInterface.UpdateMutex) {
+                               MessageBox mb = new MessageBox ();
+                               mb.Initialize ();
+                               mb.CurrentInterface.AddWidget (mb);
+                               mb.MsgType = msgBoxType;
+                               mb.Message = message;
+                               if (!string.IsNullOrEmpty(okMsg))
+                                       mb.OkMessage = okMsg;
+                               if (!string.IsNullOrEmpty(cancelMsg))
+                                       mb.CancelMessage = cancelMsg;
+                               return mb;
+                       }
+               }
+       }
+}
+
diff --git a/src/GraphicObjects/Base/NumericControl.cs b/src/GraphicObjects/Base/NumericControl.cs
new file mode 100644 (file)
index 0000000..9b51183
--- /dev/null
@@ -0,0 +1,125 @@
+//
+// NumericControl.cs
+//
+// Author:
+//       Jean-Philippe Bruyère <jp.bruyere@hotmail.com>
+//
+// Copyright (c) 2013-2017 Jean-Philippe Bruyère
+//
+// 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.Xml.Serialization;
+using System.ComponentModel;
+
+namespace Crow
+{
+       public abstract class NumericControl : TemplatedControl
+       {
+               #region CTOR
+               public NumericControl () : base()
+               {
+               }
+               public NumericControl(double minimum, double maximum, double step)
+                       : base()
+               {
+               }
+               #endregion
+
+               #region private fields
+               double _actualValue, minValue, maxValue, smallStep, bigStep;
+               #endregion
+
+               #region public properties
+               [XmlAttributeAttribute()][DefaultValue(0.0)]
+               public virtual double Minimum {
+                       get { return minValue; }
+                       set {
+                               if (minValue == value)
+                                       return;
+
+                               minValue = value;
+                               NotifyValueChanged ("Minimum", minValue);
+                               RegisterForRedraw ();
+                       }
+               }
+               [XmlAttributeAttribute()][DefaultValue(100.0)]
+               public virtual double Maximum
+               {
+                       get { return maxValue; }
+                       set {
+                               if (maxValue == value)
+                                       return;
+
+                               maxValue = value;
+                               NotifyValueChanged ("Maximum", maxValue);
+                               RegisterForRedraw ();
+                       }
+               }
+               [XmlAttributeAttribute()][DefaultValue(1.0)]
+               public virtual double SmallIncrement
+               {
+                       get { return smallStep; }
+                       set {
+                               if (smallStep == value)
+                                       return;
+
+                               smallStep = value;
+                               NotifyValueChanged ("SmallIncrement", smallStep);
+                               RegisterForRedraw ();
+                       }
+               }
+               [XmlAttributeAttribute()][DefaultValue(5.0)]
+               public virtual double LargeIncrement
+               {
+                       get { return bigStep; }
+                       set {
+                               if (bigStep == value)
+                                       return;
+
+                               bigStep = value;
+                               NotifyValueChanged ("LargeIncrement", bigStep);
+                               RegisterForRedraw ();
+                       }
+               }
+               [XmlAttributeAttribute()][DefaultValue(0.0)]
+               public double Value
+               {
+                       get { return _actualValue; }
+                       set
+                       {
+                               if (value == _actualValue)
+                                       return;
+
+                               if (value < minValue)
+                                       _actualValue = minValue;
+                               else if (value > maxValue)
+                                       _actualValue = maxValue;
+                               else                    
+                                       _actualValue = value;
+
+                               NotifyValueChanged("Value",  _actualValue);
+                               RegisterForGraphicUpdate();
+                       }
+               }
+               #endregion
+
+       }
+}
+
diff --git a/src/GraphicObjects/Base/Popper.cs b/src/GraphicObjects/Base/Popper.cs
new file mode 100644 (file)
index 0000000..d3f2e7c
--- /dev/null
@@ -0,0 +1,245 @@
+//
+// Popper.cs
+//
+// Author:
+//       Jean-Philippe Bruyère <jp.bruyere@hotmail.com>
+//
+// Copyright (c) 2013-2017 Jean-Philippe Bruyère
+//
+// 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.Xml.Serialization;
+using System.ComponentModel;
+using OpenTK.Input;
+
+namespace Crow
+{
+    public class Popper : TemplatedContainer
+    {
+               #region CTOR
+               public Popper() : base()
+               {
+               }
+               #endregion
+
+               bool _isPopped, _canPop;
+               Alignment popDirection;
+               GraphicObject _content;
+               Measure popWidth, popHeight;
+
+               public event EventHandler Popped;
+               public event EventHandler Unpoped;
+
+               #region Public Properties
+               [XmlAttributeAttribute()][DefaultValue("Fit")]
+               public virtual Measure PopWidth {
+                       get { return popWidth; }
+                       set {
+                               if (popWidth == value)
+                                       return;
+                               popWidth = value;
+                               NotifyValueChanged ("PopWidth", popWidth);
+                       }
+               }
+               [XmlAttributeAttribute()][DefaultValue("Fit")]
+               public virtual Measure PopHeight {
+                       get { return popHeight; }
+                       set {
+                               if (popHeight == value)
+                                       return;
+                               popHeight = value;
+                               NotifyValueChanged ("PopHeight", popHeight);
+                       }
+               }
+               [XmlAttributeAttribute()][DefaultValue(false)]
+               public bool IsPopped
+               {
+                       get { return _isPopped; }
+                       set
+                       {
+                               if (value == _isPopped)
+                                       return;
+
+                               _isPopped = value;
+                               NotifyValueChanged ("IsPopped", _isPopped);
+
+                               if (_isPopped)
+                                       onPop (this, null);
+                               else
+                                       onUnpop (this, null);
+
+                       }
+               }
+               [XmlAttributeAttribute()][DefaultValue(true)]
+               public bool CanPop
+               {
+                       get { return _canPop; }
+                       set
+                       {
+                               if (value == _canPop)
+                                       return;
+
+                               _canPop = value;
+                               NotifyValueChanged ("CanPop", _canPop);
+                       }
+               }
+               [XmlAttributeAttribute()][DefaultValue(Alignment.Bottom)]
+               public virtual Alignment PopDirection {
+                       get { return popDirection; }
+                       set {
+                               if (popDirection == value)
+                                       return;
+                               popDirection = value;
+                               NotifyValueChanged ("PopDirection", popDirection);
+                       }
+               }
+               #endregion
+
+               public override GraphicObject Content {
+                       get { return _content; }
+                       set {
+                               if (_content != null) {
+                                       _content.LogicalParent = null;
+                                       _content.LayoutChanged -= _content_LayoutChanged;
+                               }
+
+                               _content = value;
+
+                               if (_content == null)
+                                       return;
+
+                               _content.LogicalParent = this;
+                               _content.HorizontalAlignment = HorizontalAlignment.Left;
+                               _content.VerticalAlignment = VerticalAlignment.Top;
+                               _content.LayoutChanged += _content_LayoutChanged;
+                       }
+               }
+               void positionContent(LayoutingType lt){
+                       ILayoutable tc = Content.Parent;
+                       if (tc == null)
+                               return;
+                       Rectangle r = this.ScreenCoordinates (this.Slot);
+                       if (lt == LayoutingType.X) {
+                               if (popDirection.HasFlag (Alignment.Right)) {
+                                       if (r.Right + Content.Slot.Width > tc.ClientRectangle.Right)
+                                               Content.Left = r.Left - Content.Slot.Width;
+                                       else
+                                               Content.Left = r.Right;
+                               } else if (popDirection.HasFlag (Alignment.Left)) {
+                                       if (r.Left - Content.Slot.Width < tc.ClientRectangle.Left)
+                                               Content.Left = r.Right;
+                                       else
+                                               Content.Left = r.Left - Content.Slot.Width;
+                               } else {
+                                       if (Content.Slot.Width < tc.ClientRectangle.Width) {
+                                               if (r.Left + Content.Slot.Width > tc.ClientRectangle.Right)
+                                                       Content.Left = tc.ClientRectangle.Right - Content.Slot.Width;
+                                               else
+                                                       Content.Left = r.Left;
+                                       } else
+                                               Content.Left = 0;
+                               }
+                       }else if (lt == LayoutingType.Y) {
+                               if (Content.Slot.Height < tc.ClientRectangle.Height) {
+                                       if (PopDirection.HasFlag (Alignment.Bottom)) {
+                                               if (r.Bottom + Content.Slot.Height > tc.ClientRectangle.Bottom)
+                                                       Content.Top = r.Top - Content.Slot.Height;
+                                               else
+                                                       Content.Top = r.Bottom;
+                                       } else if (PopDirection.HasFlag (Alignment.Top)) {
+                                               if (r.Top - Content.Slot.Height < tc.ClientRectangle.Top)
+                                                       Content.Top = r.Bottom;
+                                               else
+                                                       Content.Top = r.Top - Content.Slot.Height;
+                                       } else
+                                               Content.Top = r.Top;
+                               }else
+                                       Content.Top = 0;
+                       }
+               }
+               protected void _content_LayoutChanged (object sender, LayoutingEventArgs e)
+               {
+                       if (e.LayoutType.HasFlag (LayoutingType.Width))
+                               positionContent (LayoutingType.X);
+                       if (e.LayoutType.HasFlag(LayoutingType.Height))
+                               positionContent (LayoutingType.Y);
+               }
+
+               #region GraphicObject overrides
+               public override void onMouseClick (object sender, MouseButtonEventArgs e)
+               {
+                       if (_canPop)
+                               IsPopped = !IsPopped;
+                       base.onMouseClick (this, e);
+               }
+               public override void onMouseLeave (object sender, MouseMoveEventArgs e)
+               {
+                       base.onMouseLeave (this, e);
+                       IsPopped = false;
+               }
+               public override bool MouseIsIn (Point m)
+               {
+                       bool isInContent = false;
+                       if (Content != null) {
+                               if (Content.Parent != null)
+                                       isInContent = Content.MouseIsIn (m);
+                       }
+                       return base.MouseIsIn (m) || isInContent;
+               }
+               public override void checkHoverWidget (MouseMoveEventArgs e)
+               {
+                       if (CurrentInterface.HoverWidget != this) {
+                               CurrentInterface.HoverWidget = this;
+                               onMouseEnter (this, e);
+                       }
+                       if (Content != null){
+                               if (Content.Parent != null) {
+                                       if (Content.MouseIsIn (e.Position)) {
+                                               Content.checkHoverWidget (e);
+                                               return;
+                                       }
+                               }
+                       }
+                       base.checkHoverWidget (e);
+               }
+               #endregion
+
+               public virtual void onPop(object sender, EventArgs e)
+               {
+                       if (Content != null) {
+                               Content.Visible = true;
+                               if (Content.Parent == null)
+                                       CurrentInterface.AddWidget (Content, true);
+                               if (Content.LogicalParent != this)
+                                       Content.LogicalParent = this;
+                               CurrentInterface.PutOnTop (Content, true);
+                               _content_LayoutChanged (this, new LayoutingEventArgs (LayoutingType.Sizing));
+                       }
+                       Popped.Raise (this, e);
+               }
+               public virtual void onUnpop(object sender, EventArgs e)
+               {
+                       if (Content != null) {
+                               Content.Visible = false;
+                       }
+                       Unpoped.Raise (this, e);
+               }
+       }
+}
diff --git a/src/GraphicObjects/Base/PrivateContainer.cs b/src/GraphicObjects/Base/PrivateContainer.cs
new file mode 100644 (file)
index 0000000..65eacab
--- /dev/null
@@ -0,0 +1,207 @@
+//
+// PrivateContainer.cs
+//
+// Author:
+//       Jean-Philippe Bruyère <jp.bruyere@hotmail.com>
+//
+// Copyright (c) 2013-2017 Jean-Philippe Bruyère
+//
+// 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.Xml.Serialization;
+using System.ComponentModel;
+using Cairo;
+
+namespace Crow
+{
+       /// <summary>
+       /// Implement drawing and layouting for a single child, but
+       /// does not implement IXmlSerialisation to allow reuse of container
+       /// behaviour for widgets that have other xml hierarchy: example
+       /// TemplatedControl may have 3 children (template,templateItem,content) but
+       /// behave exactely as a container for layouting and drawing
+       /// </summary>
+       public class PrivateContainer : GraphicObject
+       {
+               #region CTOR
+               public PrivateContainer()
+                       : base()
+               {
+               }
+               #endregion
+
+               protected GraphicObject child;
+
+               internal virtual void SetChild(GraphicObject _child)
+               {
+
+                       if (child != null) {
+                               contentSize = new Size (0, 0);
+                               child.LayoutChanged -= OnChildLayoutChanges;
+                               child.Parent = null;
+                               this.RegisterForGraphicUpdate ();
+                       }
+
+                       child = _child as GraphicObject;
+
+                       if (child != null) {
+                               child.Parent = this;
+                               child.LayoutChanged += OnChildLayoutChanges;
+                               contentSize = child.Slot.Size;
+                               child.RegisteredLayoutings = LayoutingType.None;
+                               child.RegisterForLayouting (LayoutingType.Sizing);
+                       }
+               }
+
+               #region GraphicObject Overrides
+
+               public override GraphicObject FindByName (string nameToFind)
+               {
+                       if (Name == nameToFind)
+                               return this;
+
+                       return child == null ? null : child.FindByName (nameToFind);
+               }
+               public override bool Contains (GraphicObject goToFind)
+               {
+                       return child == goToFind ? true : 
+                               child == null ? false : child.Contains(goToFind);
+               }
+               public override void OnDataSourceChanged (object sender, DataSourceChangeEventArgs e)
+               {
+                       base.OnDataSourceChanged (this, e);
+                       if (child != null)
+                       if (child.localDataSourceIsNull & child.localLogicalParentIsNull)
+                                       child.OnDataSourceChanged (sender, e);
+               }
+               public override bool UpdateLayout (LayoutingType layoutType)
+               {
+                       if (child != null) {
+                               //force sizing to fit if sizing on children and child has stretched size
+                               switch (layoutType) {
+                               case LayoutingType.Width:
+                                       if (Width == Measure.Fit && child.Width.Units == Unit.Percent)
+                                               child.Width = Measure.Fit;
+                                       break;
+                               case LayoutingType.Height:
+                                       if (Height == Measure.Fit && child.Height.Units == Unit.Percent)
+                                               child.Height = Measure.Fit;
+                                       break;
+                               }
+                       }
+                       return base.UpdateLayout (layoutType);
+               }
+               public override void OnLayoutChanges (LayoutingType layoutType)
+               {
+                       base.OnLayoutChanges (layoutType);
+
+                       if (child == null)
+                               return;
+                       
+                       LayoutingType ltChild = LayoutingType.None;
+
+                       if (layoutType == LayoutingType.Width) {
+                               if (child.Width.Units == Unit.Percent) {
+                                       ltChild |= LayoutingType.Width;
+                                       if (child.Width.Value < 100 && child.Left == 0)
+                                               ltChild |= LayoutingType.X;
+                               } else if (child.Left == 0)
+                                       ltChild |= LayoutingType.X;
+                       } else if (layoutType == LayoutingType.Height) {
+                               if (child.Height.Units == Unit.Percent) {
+                                       ltChild |= LayoutingType.Height;
+                                       if (child.Height.Value < 100 && child.Top == 0)
+                                               ltChild |= LayoutingType.Y;
+                               } else if (child.Top == 0)
+                                               ltChild |= LayoutingType.Y;
+                       }
+                       if (ltChild == LayoutingType.None)
+                               return;
+                       child.RegisterForLayouting (ltChild);
+               }
+               public virtual void OnChildLayoutChanges (object sender, LayoutingEventArgs arg)
+               {                       
+                       GraphicObject g = sender as GraphicObject;
+
+                       if (arg.LayoutType == LayoutingType.Width) {
+                               if (Width != Measure.Fit)
+                                       return;
+                               contentSize.Width = g.Slot.Width;
+                               this.RegisterForLayouting (LayoutingType.Width);
+                       }else if (arg.LayoutType == LayoutingType.Height){
+                               if (Height != Measure.Fit)
+                                       return;
+                               contentSize.Height = g.Slot.Height;
+                               this.RegisterForLayouting (LayoutingType.Height);
+                       }
+               }
+               protected override void onDraw (Context gr)
+               {
+                       base.onDraw (gr);
+
+                       gr.Save ();
+
+                       if (ClipToClientRect) {
+                               //clip to client zone
+                               CairoHelpers.CairoRectangle (gr, ClientRectangle, CornerRadius);
+                               gr.Clip ();
+                       }
+
+                       if (child != null) {
+                               if (child.Visible)
+                                       child.Paint (ref gr);
+                       }
+                       gr.Restore ();
+               }
+               protected override void UpdateCache (Context ctx)
+               {
+                       Rectangle rb = Slot + Parent.ClientRectangle.Position;
+
+                       using (ImageSurface cache = new ImageSurface (bmp, Format.Argb32, Slot.Width, Slot.Height, 4 * Slot.Width)) {
+                               Context gr = new Context (cache);
+
+                               if (Clipping.count > 0) {
+                                       Clipping.clearAndClip (gr);
+
+                                       onDraw (gr);
+                               }
+                                       
+                               gr.Dispose ();
+
+                               ctx.SetSourceSurface (cache, rb.X, rb.Y);
+                               ctx.Paint ();
+                       }
+                       Clipping.Reset();
+               }
+               #endregion
+
+               #region Mouse handling
+               public override void checkHoverWidget (MouseMoveEventArgs e)
+               {
+                       base.checkHoverWidget (e);
+                       if (child != null) 
+                               if (child.MouseIsIn (e.Position)) 
+                                       child.checkHoverWidget (e);
+               }
+               #endregion
+
+       }
+}
+
diff --git a/src/GraphicObjects/Base/ProgressBar.cs b/src/GraphicObjects/Base/ProgressBar.cs
new file mode 100644 (file)
index 0000000..34366ca
--- /dev/null
@@ -0,0 +1,67 @@
+//
+// ProgressBar.cs
+//
+// Author:
+//       Jean-Philippe Bruyère <jp.bruyere@hotmail.com>
+//
+// Copyright (c) 2013-2017 Jean-Philippe Bruyère
+//
+// 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.Generic;
+using System.Linq;
+using System.Text;
+using Cairo;
+using System.Diagnostics;
+using System.Xml.Serialization;
+using System.ComponentModel;
+
+namespace Crow
+{
+       
+       public class ProgressBar : NumericControl
+    {
+               #region CTOR
+               public ProgressBar() : base(){}
+               #endregion
+
+               protected override void loadTemplate (GraphicObject template)
+               {
+                       
+               }
+
+               #region GraphicObject overrides
+               protected override void onDraw (Context gr)
+               {
+                       base.onDraw (gr);
+
+                       if (Maximum == 0)
+                               return;
+
+                       Rectangle rBack = ClientRectangle;
+                       rBack.Width = (int)((double)rBack.Width / Maximum * Value);
+                       Foreground.SetAsSource (gr, rBack);
+
+                       CairoHelpers.CairoRectangle(gr,rBack,CornerRadius);
+                       gr.Fill();
+               }
+               #endregion
+    }
+}
diff --git a/src/GraphicObjects/Base/RadioButton.cs b/src/GraphicObjects/Base/RadioButton.cs
new file mode 100644 (file)
index 0000000..993ead5
--- /dev/null
@@ -0,0 +1,82 @@
+//
+// RadioButton.cs
+//
+// Author:
+//       Jean-Philippe Bruyère <jp.bruyere@hotmail.com>
+//
+// Copyright (c) 2013-2017 Jean-Philippe Bruyère
+//
+// 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.Xml.Serialization;
+
+namespace Crow
+{
+    public class RadioButton : TemplatedControl
+    {                  
+               bool isChecked;
+
+               #region CTOR
+               public RadioButton() : base(){} 
+               #endregion
+
+               public event EventHandler Checked;
+               public event EventHandler Unchecked;
+
+               #region GraphicObject overrides
+               public override void onMouseClick (object sender, MouseButtonEventArgs e)
+               {                                               
+                       Group pg = Parent as Group;
+                       if (pg != null) {
+                               for (int i = 0; i < pg.Children.Count; i++) {
+                                       RadioButton c = pg.Children [i] as RadioButton;
+                                       if (c == null)
+                                               continue;
+                                       c.IsChecked = (c == this);
+                               }
+                       } else
+                               IsChecked = !IsChecked;
+
+                       base.onMouseClick (sender, e);
+               }
+               #endregion
+
+        [XmlAttributeAttribute()][DefaultValue(false)]
+        public bool IsChecked
+        {
+                       get { return isChecked; }
+            set
+            {
+                               if (isChecked == value)
+                                       return;
+                               
+                               isChecked = value;
+
+                               NotifyValueChanged ("IsChecked", value);
+
+                               if (isChecked)
+                                       Checked.Raise (this, null);
+                               else
+                                       Unchecked.Raise (this, null);
+            }
+        }
+       }
+}
diff --git a/src/GraphicObjects/Base/ScrollBar.cs b/src/GraphicObjects/Base/ScrollBar.cs
new file mode 100644 (file)
index 0000000..91ce50e
--- /dev/null
@@ -0,0 +1,68 @@
+//
+// ScrollBar.cs
+//
+// Author:
+//       Jean-Philippe Bruyère <jp.bruyere@hotmail.com>
+//
+// Copyright (c) 2013-2017 Jean-Philippe Bruyère
+//
+// 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.Xml.Serialization;
+using System.ComponentModel;
+using OpenTK.Input;
+
+namespace Crow
+{
+       public class ScrollBar : NumericControl
+       {
+               Orientation _orientation;
+
+               #region CTOR
+               public ScrollBar() : base()     {}
+               #endregion
+
+               [XmlAttributeAttribute()][DefaultValue(Orientation.Vertical)]
+               public virtual Orientation Orientation
+               {
+                       get { return _orientation; }
+                       set {                           
+                               if (_orientation == value)
+                                       return;
+                               _orientation = value;
+                               NotifyValueChanged ("Orientation", _orientation);
+                               RegisterForGraphicUpdate ();
+                       }
+               }
+               public void onScrollBack (object sender, MouseButtonEventArgs e)
+               {
+                       Value -= SmallIncrement;
+               }
+               public void onScrollForth (object sender, MouseButtonEventArgs e)
+               {
+                       Value += SmallIncrement;
+               }
+
+               public void onSliderValueChange(object sender, ValueChangeEventArgs e){
+                       if (e.MemberName == "Value")
+                               Value = Convert.ToDouble(e.NewValue);
+               }
+       }
+}
diff --git a/src/GraphicObjects/Base/Scroller.cs b/src/GraphicObjects/Base/Scroller.cs
new file mode 100644 (file)
index 0000000..640fcfe
--- /dev/null
@@ -0,0 +1,239 @@
+//
+// Scroller.cs
+//
+// Author:
+//       Jean-Philippe Bruyère <jp.bruyere@hotmail.com>
+//
+// Copyright (c) 2013-2017 Jean-Philippe Bruyère
+//
+// 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.Xml.Serialization;
+using System.ComponentModel;
+using System.Diagnostics;
+using Cairo;
+
+namespace Crow
+{
+       public class Scroller : Container
+       {
+               bool _verticalScrolling;
+               bool _horizontalScrolling;
+               bool _scrollbarVisible;
+               double _scrollX = 0.0;
+               double _scrollY = 0.0;
+               int scrollSpeed;
+
+               public event EventHandler<ScrollingEventArgs> Scrolled;
+
+               #region public properties
+               [XmlAttributeAttribute][DefaultValue(true)]
+               public bool VerticalScrolling {
+                       get { return _verticalScrolling; }
+                       set { _verticalScrolling = value; }
+               }
+
+               [XmlAttributeAttribute][DefaultValue(false)]
+        public bool HorizontalScrolling {
+                       get { return _horizontalScrolling; }
+                       set { _horizontalScrolling = value; }
+               }
+               [XmlAttributeAttribute][DefaultValue(true)]
+               public bool ScrollbarVisible {
+                       get { return _scrollbarVisible; }
+                       set { _scrollbarVisible = value; }
+               }
+               [XmlAttributeAttribute][DefaultValue(0.0)]
+               public double ScrollX {
+                       get {
+                               return _scrollX;
+                       }
+                       set {
+                               if (_scrollX == value)
+                                       return;
+                               if (value < 0.0)
+                                       _scrollX = 0.0;
+                               else if (value > Child.Slot.Width - ClientRectangle.Width)
+                                       _scrollX = Math.Max(0.0, Child.Slot.Width - ClientRectangle.Width);
+                               else
+                                       _scrollX = value;
+                               NotifyValueChanged("ScrollX", _scrollX);
+                               RegisterForRedraw ();
+                               Scrolled.Raise (this, new ScrollingEventArgs (Orientation.Horizontal));
+                       }
+               }
+               [XmlAttributeAttribute][DefaultValue(0.0)]
+               public double ScrollY {
+                       get {
+                               return _scrollY;
+                       }
+                       set {
+                               if (_scrollY == value)
+                                       return;
+                               if (value < 0.0)
+                                       _scrollY = 0.0;
+                               else if (value > Child.Slot.Height - ClientRectangle.Height)
+                                       _scrollY = Math.Max(0.0,Child.Slot.Height - ClientRectangle.Height);
+                               else
+                                       _scrollY = value;
+                               NotifyValueChanged("ScrollY", _scrollY);
+                               RegisterForRedraw ();
+                               Scrolled.Raise (this, new ScrollingEventArgs (Orientation.Vertical));
+                       }
+               }
+
+               [XmlIgnore]
+               public int MaximumScroll {
+                       get {
+                               try {
+                                       return VerticalScrolling ?
+                                               Math.Max(Child.Slot.Height - ClientRectangle.Height,0) :
+                                               Math.Max(Child.Slot.Width - ClientRectangle.Width,0);
+                               } catch {
+                                       return 0;
+                               }
+                       }
+               }
+
+               [XmlAttributeAttribute][DefaultValue(30)]
+               public int ScrollSpeed {
+                       get { return scrollSpeed; }
+                       set {
+                               scrollSpeed = value;
+                               NotifyValueChanged("ScrollSpeed", scrollSpeed);
+                       }
+               }
+               #endregion
+
+        public Scroller()
+            : base(){}
+
+               #region GraphicObject Overrides
+               public override void OnLayoutChanges (LayoutingType layoutType)
+               {
+                       base.OnLayoutChanges (layoutType);
+
+                       NotifyValueChanged("MaximumScroll", MaximumScroll);
+               }
+               void OnChildLayoutChanges (object sender, LayoutingEventArgs arg)
+               {
+                       //Debug.WriteLine ("scroller childLayoutChanges");
+                       int maxScroll = MaximumScroll;
+                       //Debug.WriteLine ("maxscroll={0}", maxScroll);
+                       if (_verticalScrolling) {
+                               if (arg.LayoutType == LayoutingType.Height) {
+                                       if (maxScroll < ScrollY) {
+                                               //Debug.WriteLine ("scrolly={0} maxscroll={1}", ScrollY, maxScroll);
+                                               ScrollY = maxScroll;
+                                       }
+                                       NotifyValueChanged("MaximumScroll", maxScroll);
+                               }
+                       } else if (arg.LayoutType == LayoutingType.Width) {
+                               if (maxScroll < ScrollX) {
+                                       //Debug.WriteLine ("scrolly={0} maxscroll={1}", ScrollY, maxScroll);
+                                       ScrollX = maxScroll;
+                               }
+                               NotifyValueChanged("MaximumScroll", maxScroll);
+                       }
+               }
+               void onChildListCleared(object sender, EventArgs e){
+                       ScrollY = 0;
+                       ScrollX = 0;
+               }
+               public override void SetChild (GraphicObject _child)
+               {
+                       GraphicObject c = child as GraphicObject;
+                       Group g = child as Group;
+                       if (c != null) {
+                               c.LayoutChanged -= OnChildLayoutChanges;
+                               if (g != null)
+                                       g.ChildrenCleared -= onChildListCleared;
+                       }
+                       c = _child as GraphicObject;
+                       g = _child as Group;
+                       if (c != null) {
+                               c.LayoutChanged += OnChildLayoutChanges;
+                               if (g != null)
+                                       g.ChildrenCleared += onChildListCleared;
+                       }
+                       base.SetChild (_child);
+               }
+               public override Rectangle ScreenCoordinates (Rectangle r)
+               {
+                       return base.ScreenCoordinates (r) - new Point((int)ScrollX,(int)ScrollY);
+               }
+               protected override void onDraw (Context gr)
+               {
+                       Rectangle rBack = new Rectangle (Slot.Size);
+
+                       Background.SetAsSource (gr, rBack);
+                       CairoHelpers.CairoRectangle(gr,rBack, CornerRadius);
+                       gr.Fill ();
+
+                       gr.Save ();
+                       if (ClipToClientRect) {
+                               //clip to scrolled client zone
+                               CairoHelpers.CairoRectangle (gr, ClientRectangle, CornerRadius);
+                               gr.Clip ();
+                       }
+
+                       gr.Translate (-ScrollX, -ScrollY);
+                       if (child != null)
+                               child.Paint (ref gr);
+                       gr.Restore ();
+               }
+
+               #region Mouse handling
+               internal Point savedMousePos;
+               public override bool MouseIsIn (Point m)
+               {
+                       return Visible ? base.ScreenCoordinates(Slot).ContainsOrIsEqual (m) : false;
+               }
+               public override void checkHoverWidget (MouseMoveEventArgs e)
+               {
+                       savedMousePos = e.Position;
+                       Point m = e.Position - new Point ((int)ScrollX, (int)ScrollY);
+                       base.checkHoverWidget (new MouseMoveEventArgs(m.X,m.Y,e.XDelta,e.YDelta));
+               }
+               public override void onMouseWheel (object sender, MouseWheelEventArgs e)
+               {
+                       if (Child == null)
+                               return;
+
+                       if (VerticalScrolling )
+                               ScrollY -= e.Delta * ScrollSpeed;
+                       if (HorizontalScrolling )
+                               ScrollX -= e.Delta * ScrollSpeed;
+               }
+               public override void onMouseMove (object sender, MouseMoveEventArgs e)
+               {
+                       savedMousePos.X += e.XDelta;
+                       savedMousePos.Y += e.YDelta;
+                       base.onMouseMove (sender, new MouseMoveEventArgs(savedMousePos.X,savedMousePos.Y,e.XDelta,e.YDelta));
+               }
+               public override void RegisterClip (Rectangle clip)
+               {
+                       base.RegisterClip (clip - new Point((int)ScrollX,(int)ScrollY));
+               }
+               #endregion
+
+               #endregion
+    }
+}
diff --git a/src/GraphicObjects/Base/Slider.cs b/src/GraphicObjects/Base/Slider.cs
new file mode 100644 (file)
index 0000000..36f7e73
--- /dev/null
@@ -0,0 +1,219 @@
+//
+// Slider.cs
+//
+// Author:
+//       Jean-Philippe Bruyère <jp.bruyere@hotmail.com>
+//
+// Copyright (c) 2013-2017 Jean-Philippe Bruyère
+//
+// 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 Cairo;
+using System.Xml.Serialization;
+using System.ComponentModel;
+using System.Diagnostics;
+
+namespace Crow
+{
+       public class Slider : NumericControl
+    {
+               #region CTOR
+               public Slider() : base()
+               {}
+               public Slider(double minimum, double maximum, double step)
+                       : base(minimum,maximum,step)
+               {
+               }
+               #endregion
+
+               #region implemented abstract members of TemplatedControl
+
+               protected override void loadTemplate (GraphicObject template = null)
+               {
+                       
+               }
+
+               #endregion
+
+               #region private fields
+        Rectangle cursor;
+               int _cursorSize;
+               Fill _cursorColor;
+               Orientation _orientation;
+               bool holdCursor = false;
+               #endregion
+
+               protected double unity;
+
+               #region Public properties
+               [XmlAttributeAttribute()][DefaultValue("vgradient|0:White|0,1:LightGray|0,9:LightGray|1:DimGray")]
+               public virtual Fill CursorColor {
+                       get { return _cursorColor; }
+                       set {
+                               if (_cursorColor == value)
+                                       return;
+                               _cursorColor = value;
+                               RegisterForRedraw ();
+                               NotifyValueChanged ("CursorColor", _cursorColor);
+                       }
+               }
+               [XmlAttributeAttribute()][DefaultValue(20)]
+               public virtual int CursorSize {
+                       get { return _cursorSize; }
+                       set {
+                               if (_cursorSize == value)
+                                       return;
+                               _cursorSize = value;
+                               RegisterForGraphicUpdate ();
+                               NotifyValueChanged ("CursorSize", _cursorSize);
+                       }
+               }
+               [XmlAttributeAttribute()][DefaultValue(Orientation.Horizontal)]
+               public virtual Orientation Orientation
+               {
+                       get { return _orientation; }
+                       set { 
+                               if (_orientation == value)
+                                       return;
+                               _orientation = value; 
+
+                               RegisterForLayouting (LayoutingType.All);
+                               NotifyValueChanged ("Orientation", _orientation);
+                       }
+               }
+               #endregion
+
+               [XmlAttributeAttribute()][DefaultValue(10.0)]
+               public override double Maximum {
+                       get { return base.Maximum; }
+                       set {                           
+                               if (value == base.Maximum)
+                                       return;
+                               base.Maximum = value;
+                               LargeIncrement = base.Maximum / 10.0;
+                               SmallIncrement = LargeIncrement / 5.0;
+                       }
+               }
+
+               #region GraphicObject Overrides
+               protected override void onDraw (Context gr)
+               {
+                       base.onDraw (gr);
+                       if (Maximum <= 0)
+                               return;
+
+                       computeCursorPosition ();
+
+                       Rectangle r = ClientRectangle;
+                       PointD pStart;
+                       PointD pEnd;
+                       if (_orientation == Orientation.Horizontal) {
+                               pStart = r.TopLeft + new Point (_cursorSize / 2, r.Height / 2);
+                               pEnd = r.TopRight + new Point (-_cursorSize / 2, r.Height / 2);
+                       } else {
+                               pStart = r.TopLeft + new Point (r.Width / 2, _cursorSize / 2);
+                               pEnd = r.BottomLeft + new Point (r.Width / 2,- _cursorSize / 2);
+                       }
+
+                       DrawGraduations (gr, pStart,pEnd);
+
+                       DrawCursor (gr, cursor);
+               }
+               #endregion
+
+               protected virtual void DrawGraduations(Context gr, PointD pStart, PointD pEnd)
+               {
+                       Foreground.SetAsSource (gr);
+
+                       gr.LineWidth = 1;
+                       gr.MoveTo(pStart);
+                       gr.LineTo(pEnd);
+
+                       gr.Stroke();
+
+               }
+               protected virtual void DrawCursor(Context gr, Rectangle _cursor)
+               {
+                       CursorColor.SetAsSource (gr, _cursor);
+                       CairoHelpers.CairoRectangle (gr, _cursor, CornerRadius);
+                       gr.Fill();
+               }
+
+        void computeCursorPosition()
+        {            
+            Rectangle r = ClientRectangle;
+                       PointD p1; 
+
+                       if (_orientation == Orientation.Horizontal) {
+                               cursor = new Rectangle (new Size (_cursorSize, (int)(r.Height)));
+                               p1 = r.TopLeft + new Point (_cursorSize / 2, r.Height / 2);
+                               unity = (double)(r.Width - _cursorSize) / (Maximum - Minimum);
+                               cursor.TopLeft = new Point (r.Left + (int)(Value * unity),
+                                       (int)(p1.Y - cursor.Height / 2));
+                       } else {
+                               cursor = new Rectangle (new Size ((int)(r.Width), _cursorSize));
+                               p1 = r.TopLeft + new Point (r.Width / 2, _cursorSize / 2);
+                               unity = (double)(r.Height - _cursorSize) / (Maximum - Minimum);
+                               cursor.TopLeft = new Point ((int)(p1.X - r.Width / 2),
+                                       r.Top + (int)(Value * unity));                          
+                       }
+                       cursor.Inflate (-1);
+        }
+        
+               #region mouse handling
+               public override void onMouseDown (object sender, MouseButtonEventArgs e)
+               {
+                       base.onMouseDown (sender, e);
+
+                       Rectangle cursInScreenCoord = ScreenCoordinates (cursor + Slot.Position);
+                       if (cursInScreenCoord.ContainsOrIsEqual (e.Position))
+                               holdCursor = true;
+                       else if (_orientation == Orientation.Horizontal) {
+                               if (e.Position.X < cursInScreenCoord.Left)
+                                       Value -= LargeIncrement;
+                               else
+                                       Value += LargeIncrement;
+                       } else {
+                               if (e.Position.Y < cursInScreenCoord.Top)
+                                       Value -= LargeIncrement;
+                               else
+                                       Value += LargeIncrement;
+                       }
+               }
+               public override void onMouseUp (object sender,MouseButtonEventArgs e)
+               {
+                       base.onMouseUp (sender, e);
+
+                       holdCursor = false;
+               }
+               public override void onMouseMove (object sender, MouseMoveEventArgs e)
+               {
+                       if (holdCursor) {
+                               if (_orientation == Orientation.Horizontal)
+                                       Value += (double)e.XDelta / unity;
+                               else
+                                       Value += (double)e.YDelta / unity;
+                       }
+                       
+                       base.onMouseMove (sender, e);
+               }
+               #endregion
+    }
+}
diff --git a/src/GraphicObjects/Base/Spinner.cs b/src/GraphicObjects/Base/Spinner.cs
new file mode 100644 (file)
index 0000000..1bf93a3
--- /dev/null
@@ -0,0 +1,55 @@
+//
+// Spinner.cs
+//
+// Author:
+//       Jean-Philippe Bruyère <jp.bruyere@hotmail.com>
+//
+// Copyright (c) 2013-2017 Jean-Philippe Bruyère
+//
+// 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 Crow
+{
+       public class Spinner : NumericControl
+       {
+               #region CTOR
+               public Spinner () : base()
+               {
+               }
+               public Spinner (double minimum, double maximum, double step) : 
+               base (minimum, maximum, step)
+               {
+
+               }
+               #endregion
+
+               void onUp (object sender, MouseButtonEventArgs e)
+               {
+                       Value += this.SmallIncrement;
+               }
+               void onDown (object sender, MouseButtonEventArgs e)
+               {
+                       Value -= this.SmallIncrement;
+               }
+
+       }
+}
+
diff --git a/src/GraphicObjects/Base/Splitter.cs b/src/GraphicObjects/Base/Splitter.cs
new file mode 100644 (file)
index 0000000..2f5dd15
--- /dev/null
@@ -0,0 +1,218 @@
+//
+// Splitter.cs
+//
+// Author:
+//       Jean-Philippe Bruyère <jp.bruyere@hotmail.com>
+//
+// Copyright (c) 2013-2017 Jean-Philippe Bruyère
+//
+// 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.Xml.Serialization;
+using System.ComponentModel;
+
+namespace Crow
+{
+       public class Splitter : GraphicObject
+       {
+               #region CTOR
+               public Splitter (): base(){}
+               #endregion
+
+               int thickness;
+
+               [XmlAttributeAttribute][DefaultValue(1)]
+               public virtual int Thickness {
+                       get { return thickness; }
+                       set {
+                               if (thickness == value)
+                                       return;
+                               thickness = value; 
+                               NotifyValueChanged ("Thickness", thickness);
+                               RegisterForLayouting (LayoutingType.Sizing);
+                               RegisterForGraphicUpdate ();
+                       }
+               }
+
+               Unit u1, u2;
+               int init1 = -1, init2 = -1, delta = 0, min1, min2, max1 , max2;
+               GraphicObject go1 = null, go2 = null;
+
+               void initSplit(Measure m1, int size1, Measure m2, int size2){
+                       if (m1 != Measure.Stretched) {
+                               init1 = size1;
+                               u1 = m1.Units;
+                       }
+                       if (m2 != Measure.Stretched) {
+                               init2 = size2;
+                               u2 = m2.Units;
+                       }
+               }
+               void convertSizeInPix(GraphicObject g1){
+
+               }
+
+               #region GraphicObject override
+               public override ILayoutable Parent {
+                       get { return base.Parent; }
+                       set {
+                               if (value != null) {                    
+                                       GenericStack gs = value as GenericStack;
+                                       if (gs == null)
+                                               throw new Exception ("Splitter may only be chil of stack");
+                                       
+                               }
+                               base.Parent = value;
+                       }
+               }
+               public override void onMouseEnter (object sender, MouseMoveEventArgs e)
+               {
+                       base.onMouseEnter (sender, e);
+                       if ((Parent as GenericStack).Orientation == Orientation.Horizontal)
+                               CurrentInterface.MouseCursor = XCursor.H;
+                       else
+                               CurrentInterface.MouseCursor = XCursor.V;
+               }
+               public override void onMouseLeave (object sender, MouseMoveEventArgs e)
+               {
+                       base.onMouseLeave (sender, e);
+                       CurrentInterface.MouseCursor = XCursor.Default;
+               }
+               public override void onMouseDown (object sender, MouseButtonEventArgs e)
+               {
+                       base.onMouseDown (sender, e);
+                       go1 = go2 = null;
+                       init1 = init2 = -1;
+                       delta = 0;
+
+                       GenericStack gs = Parent as GenericStack;
+                       int ptrSplit = gs.Children.IndexOf (this);
+                       if (ptrSplit == 0 || ptrSplit == gs.Children.Count - 1)
+                               return;
+
+                       go1 = gs.Children [ptrSplit - 1];
+                       go2 = gs.Children [ptrSplit + 1];
+
+                       if (gs.Orientation == Orientation.Horizontal) {
+                               initSplit (go1.Width, go1.Slot.Width, go2.Width, go2.Slot.Width);
+                               min1 = go1.MinimumSize.Width;
+                               min2 = go2.MinimumSize.Width;
+                               max1 = go1.MaximumSize.Width;
+                               max2 = go2.MaximumSize.Width;
+                               if (init1 >= 0)
+                                       go1.Width = init1;
+                               if (init2 >= 0)
+                                       go2.Width = init2;
+                       } else {
+                               initSplit (go1.Height, go1.Slot.Height, go2.Height, go2.Slot.Height);
+                               min1 = go1.MinimumSize.Height;
+                               min2 = go2.MinimumSize.Height;
+                               max1 = go1.MaximumSize.Height;
+                               max2 = go2.MaximumSize.Height;
+                               if (init1 >= 0)
+                                       go1.Height = init1;
+                               if (init2 >= 0)
+                                       go2.Height = init2;
+                       }
+               }
+               public override void onMouseMove (object sender, MouseMoveEventArgs e)
+               {
+                       base.onMouseMove (sender, e);
+
+                       if (!IsActive)
+                               return;
+
+                       GenericStack gs = Parent as GenericStack;
+                       int newDelta = delta, size1 = init1 , size2 = init2;
+                       if (gs.Orientation == Orientation.Horizontal) {
+                               newDelta -= e.XDelta;
+                               if (size1 < 0)
+                                       size1 = go1.Slot.Width + delta;
+                               if (size2 < 0)
+                                       size2 = go2.Slot.Width - delta;
+                       } else {
+                               newDelta -= e.YDelta;
+                               if (size1 < 0)
+                                       size1 = go1.Slot.Height + delta;
+                               if (size2 < 0)
+                                       size2 = go2.Slot.Height - delta;
+                       }
+
+                       if (size1 - newDelta < min1 || (max1 > 0 && size1 - newDelta > max1) ||
+                               size2 + newDelta < min2 || (max2 > 0 && size2 + newDelta > max2))
+                               return;
+
+                       delta = newDelta;
+
+                       if (gs.Orientation == Orientation.Horizontal) {
+                               if (init1 >= 0)
+                                       go1.Width = init1 - delta;
+                               if (init2 >= 0)
+                                       go2.Width = init2 + delta;
+                       } else {
+                               if (init1 >= 0)
+                                       go1.Height = init1 - delta;
+                               if (init2 >= 0)
+                                       go2.Height = init2 + delta;
+                       }
+               }
+               public override void onMouseUp (object sender, MouseButtonEventArgs e)
+               {
+                       base.onMouseUp (sender, e);
+
+                       GenericStack gs = Parent as GenericStack;
+
+                       if (init1 >= 0 && u1 == Unit.Percent) {
+                               if (gs.Orientation == Orientation.Horizontal)
+                                       go1.Width = new Measure ((int)Math.Ceiling (
+                                               go1.Width.Value * 100.0 / (double)gs.Slot.Width), Unit.Percent);
+                               else
+                                       go1.Height = new Measure ((int)Math.Ceiling (
+                                               go1.Height.Value * 100.0 / (double)gs.Slot.Height), Unit.Percent);
+                       }
+                       if (init2 >= 0 && u2 == Unit.Percent) {
+                               if (gs.Orientation == Orientation.Horizontal)
+                                       go2.Width = new Measure ((int)Math.Floor (
+                                               go2.Width.Value * 100.0 / (double)gs.Slot.Width), Unit.Percent);
+                               else
+                                       go2.Height = new Measure ((int)Math.Floor (
+                                               go2.Height.Value * 100.0 / (double)gs.Slot.Height), Unit.Percent);
+                       }
+               }
+               public override bool UpdateLayout (LayoutingType layoutType)
+               {
+                       GenericStack gs = Parent as GenericStack;
+                       if (layoutType == LayoutingType.Width){
+                               if (gs.Orientation == Orientation.Horizontal)
+                                       Width = thickness;
+                               else
+                                       Width = Measure.Stretched;
+                       } else if (layoutType == LayoutingType.Height){
+                               if (gs.Orientation == Orientation.Vertical)
+                                       Height = thickness;
+                               else
+                                       Height = Measure.Stretched;
+                       }
+                       return base.UpdateLayout (layoutType);
+               }
+               #endregion
+       }
+}
+
diff --git a/src/GraphicObjects/Base/TabItem.cs b/src/GraphicObjects/Base/TabItem.cs
new file mode 100644 (file)
index 0000000..7dac547
--- /dev/null
@@ -0,0 +1,210 @@
+//
+// TabItem.cs
+//
+// Author:
+//       Jean-Philippe Bruyère <jp.bruyere@hotmail.com>
+//
+// Copyright (c) 2013-2017 Jean-Philippe Bruyère
+//
+// 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.Xml.Serialization;
+using System.ComponentModel;
+using System.Diagnostics;
+
+namespace Crow
+{
+       public class TabItem : TemplatedContainer
+       {
+               #region CTOR
+               public TabItem () : base() {}
+               #endregion
+
+               #region Private fields
+               string caption;
+               Container _contentContainer;
+               GraphicObject _tabTitle;
+               int tabOffset;
+               bool isSelected;
+               Measure tabThickness;
+               #endregion
+
+               #region TemplatedControl overrides
+               public override GraphicObject Content {
+                       get {
+                               return _contentContainer == null ? null : _contentContainer.Child;
+                       }
+                       set {
+                               if (Content != null) {
+                                       Content.LogicalParent = null;
+                                       _contentContainer.SetChild (null);
+                               }
+                               _contentContainer.SetChild(value);
+                               if (value != null)
+                                       value.LogicalParent = this;
+                       }
+               }
+               protected override void loadTemplate(GraphicObject template = null)
+               {
+                       base.loadTemplate (template);
+
+                       _contentContainer = this.child.FindByName ("Content") as Container;
+                       _tabTitle = this.child.FindByName ("TabTitle");
+               }
+               internal GraphicObject TabTitle { get { return _tabTitle; }}
+               #endregion
+
+               [XmlAttributeAttribute][DefaultValue("18")]
+               public virtual Measure TabThickness {
+                       get { return tabThickness; }
+                       set {
+                               if (tabThickness == value)
+                                       return;
+                               tabThickness = value;
+                               NotifyValueChanged ("TabThickness", tabThickness);
+                               RegisterForGraphicUpdate ();
+                       }
+               }
+               [XmlAttributeAttribute][DefaultValue(0)]
+               public virtual int TabOffset {
+                       get { return tabOffset; }
+                       set {
+                               if (tabOffset == value)
+                                       return;
+                               tabOffset = value;
+                               NotifyValueChanged ("TabOffset", tabOffset);
+
+                               RegisterForLayouting (LayoutingType.X);
+                               RegisterForGraphicUpdate ();
+                       }
+               }
+
+               [XmlAttributeAttribute][DefaultValue(false)]
+               public virtual bool IsSelected {
+                       get { return isSelected; }
+                       set {
+                               if (isSelected == value)
+                                       return;
+                               isSelected = value;
+                               NotifyValueChanged ("IsSelected", isSelected);
+                       }
+               }
+               protected override void onDraw (Cairo.Context gr)
+               {
+                       gr.Save ();
+
+                       int spacing = (Parent as TabView).Spacing;
+
+                       gr.MoveTo (0.5, TabTitle.Slot.Bottom-0.5);
+                       gr.LineTo (TabTitle.Slot.Left - spacing, TabTitle.Slot.Bottom-0.5);
+                       gr.CurveTo (
+                               TabTitle.Slot.Left - spacing / 2, TabTitle.Slot.Bottom-0.5,
+                               TabTitle.Slot.Left - spacing / 2, 0.5,
+                               TabTitle.Slot.Left, 0.5);
+                       gr.LineTo (TabTitle.Slot.Right, 0.5);
+                       gr.CurveTo (
+                               TabTitle.Slot.Right + spacing / 2, 0.5,
+                               TabTitle.Slot.Right + spacing / 2, TabTitle.Slot.Bottom-0.5,
+                               TabTitle.Slot.Right + spacing, TabTitle.Slot.Bottom-0.5);
+                       gr.LineTo (Slot.Width-0.5, TabTitle.Slot.Bottom-0.5);
+
+
+                       gr.LineTo (Slot.Width-0.5, Slot.Height-0.5);
+                       gr.LineTo (0.5, Slot.Height-0.5);
+                       gr.ClosePath ();
+                       gr.LineWidth = 2;
+                       Foreground.SetAsSource (gr);
+                       gr.StrokePreserve ();
+
+                       gr.Clip ();
+                       base.onDraw (gr);
+                       gr.Restore ();
+               }
+
+               #region Mouse Handling
+               public override bool MouseIsIn (Point m)
+               {
+                       if (!Visible)
+                               return false;
+
+                       bool mouseIsInTitle = TabTitle.ScreenCoordinates (TabTitle.Slot).ContainsOrIsEqual (m);
+                       if (!IsSelected)
+                               return mouseIsInTitle;
+
+                       return _contentContainer.ScreenCoordinates (_contentContainer.Slot).ContainsOrIsEqual (m)
+                               || mouseIsInTitle;
+               }
+               bool holdCursor = false;
+               public override void onMouseDown (object sender, MouseButtonEventArgs e)
+               {
+                       base.onMouseDown (sender, e);
+                       holdCursor = true;
+               }
+               public override void onMouseUp (object sender, MouseButtonEventArgs e)
+               {
+                       base.onMouseUp (sender, e);
+                       holdCursor = false;
+                       (Parent as TabView).UpdateLayout (LayoutingType.ArrangeChildren);
+               }
+               public override void onMouseMove (object sender, MouseMoveEventArgs e)
+               {
+                       base.onMouseMove (sender, e);
+
+                       if (!(HasFocus&&holdCursor))
+                               return;
+                       TabView tv = Parent as TabView;
+                       TabItem previous = null, next = null;
+                       int tmp = TabOffset + e.XDelta;
+                       if (tmp < tv.Spacing)
+                               TabOffset = tv.Spacing;
+                       else if (tmp > Parent.getSlot ().Width - TabTitle.Slot.Width - tv.Spacing)
+                               TabOffset = Parent.getSlot ().Width - TabTitle.Slot.Width - tv.Spacing;
+                       else{
+                               int idx = tv.Children.IndexOf (this);
+                               if (idx > 0 && e.XDelta < 0) {
+                                       previous = tv.Children [idx - 1] as TabItem;
+
+                                       if (tmp < previous.TabOffset + previous.TabTitle.Slot.Width / 2) {
+                                               tv.Children.RemoveAt (idx);
+                                               tv.Children.Insert (idx - 1, this);
+                                               tv.SelectedTab = idx - 1;
+                                               tv.UpdateLayout (LayoutingType.ArrangeChildren);
+                                       }
+
+                               }else if (idx < tv.Children.Count - 1 && e.XDelta > 0) {
+                                       next = tv.Children [idx + 1] as TabItem;
+                                       if (tmp > next.TabOffset - next.TabTitle.Slot.Width / 2){
+                                               tv.Children.RemoveAt (idx);
+                                               tv.Children.Insert (idx + 1, this);
+                                               tv.SelectedTab = idx + 1;
+                                               tv.UpdateLayout (LayoutingType.ArrangeChildren);
+                                       }
+                               }
+                               TabOffset = tmp;
+                       }
+               }
+               public void butCloseTabClick (object sender, MouseButtonEventArgs e){
+                       (Parent as TabView).RemoveChild(this);
+               }
+               #endregion
+
+       }
+}
+
diff --git a/src/GraphicObjects/Base/TabView.cs b/src/GraphicObjects/Base/TabView.cs
new file mode 100644 (file)
index 0000000..ecf38f1
--- /dev/null
@@ -0,0 +1,210 @@
+//
+// TabView.cs
+//
+// Author:
+//       Jean-Philippe Bruyère <jp.bruyere@hotmail.com>
+//
+// Copyright (c) 2013-2017 Jean-Philippe Bruyère
+//
+// 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.Xml.Serialization;
+using System.ComponentModel;
+using Cairo;
+using System.Diagnostics;
+
+namespace Crow
+{      
+       public class TabView : Group
+       {
+               #region CTOR
+               public TabView () : base() {}
+               #endregion
+
+               #region Private fields
+               int _spacing;
+               Measure tabThickness;
+               Orientation _orientation;
+               int selectedTab = 0;
+               #endregion
+
+
+               #region public properties
+               [XmlAttributeAttribute()][DefaultValue(Orientation.Horizontal)]
+               public virtual Orientation Orientation
+               {
+                       get { return _orientation; }
+                       set {
+                               if (_orientation == value)
+                                       return;
+                               _orientation = value;
+                               NotifyValueChanged ("Orientation", _orientation);
+                               if (_orientation == Orientation.Horizontal)
+                                       NotifyValueChanged ("TabOrientation", Orientation.Vertical);
+                               else
+                                       NotifyValueChanged ("TabOrientation", Orientation.Horizontal);
+                       }
+               }
+               [XmlAttributeAttribute()][DefaultValue(16)]
+               public int Spacing
+               {
+                       get { return _spacing; }
+                       set {
+                               if (_spacing == value)
+                                       return;
+                               _spacing = value;
+                               NotifyValueChanged ("Spacing", Spacing);
+                       }
+               }
+               [XmlAttributeAttribute()][DefaultValue(0)]
+               public virtual int SelectedTab {
+                       get { return selectedTab; }
+                       set {
+                               if (selectedTab < Children.Count && SelectedTab >= 0)
+                                       (Children [selectedTab] as TabItem).IsSelected = false;
+
+                               selectedTab = value;
+
+                               if (selectedTab < Children.Count && SelectedTab >= 0)
+                                       (Children [selectedTab] as TabItem).IsSelected = true;
+
+                               NotifyValueChanged ("SelectedTab", selectedTab);
+                               RegisterForRedraw ();
+                       }
+               }
+               #endregion
+
+               public override void AddChild (GraphicObject child)
+               {
+                       TabItem ti = child as TabItem;
+                       if (ti == null)
+                               throw new Exception ("TabView control accept only TabItem as child.");
+
+                       ti.MouseDown += Ti_MouseDown;
+
+                       if (Children.Count == 0) {
+                               ti.IsSelected = true;
+                               SelectedTab = 0;
+                       }
+
+                       base.AddChild (child);
+               }
+               public override void RemoveChild (GraphicObject child)
+               {
+                       base.RemoveChild (child);
+                       if (selectedTab > Children.Count - 1)
+                               SelectedTab--;
+                       else
+                               SelectedTab = selectedTab;
+               }
+               public override bool ArrangeChildren { get { return true; } }
+               public override bool UpdateLayout (LayoutingType layoutType)
+               {
+                       RegisteredLayoutings &= (~layoutType);
+
+                       if (layoutType == LayoutingType.ArrangeChildren) {
+                               int curOffset = Spacing;
+                               for (int i = 0; i < Children.Count; i++) {
+                                       if (!Children [i].Visible)
+                                               continue;
+                                       TabItem ti = Children [i] as TabItem;
+                                       ti.TabOffset = curOffset;
+                                       if (Orientation == Orientation.Horizontal) {
+                                               if (ti.TabTitle.RegisteredLayoutings.HasFlag (LayoutingType.Width))
+                                                       return false;
+                                               curOffset += ti.TabTitle.Slot.Width + Spacing;
+                                       } else {
+                                               if (ti.TabTitle.RegisteredLayoutings.HasFlag (LayoutingType.Height))
+                                                       return false;
+                                               curOffset += ti.TabTitle.Slot.Height + Spacing;
+                                       }
+                               }
+
+                               //if no layouting remains in queue for item, registre for redraw
+                               if (RegisteredLayoutings == LayoutingType.None && IsDirty)
+                                       CurrentInterface.EnqueueForRepaint (this);
+
+                               return true;
+                       }
+
+                       return base.UpdateLayout(layoutType);
+               }
+               protected override void onDraw (Context gr)
+               {
+                       Rectangle rBack = new Rectangle (Slot.Size);
+
+                       Background.SetAsSource (gr, rBack);
+                       CairoHelpers.CairoRectangle(gr,rBack, CornerRadius);
+                       gr.Fill ();
+
+                       gr.Save ();
+
+                       if (ClipToClientRect) {
+                               //clip to client zone
+                               CairoHelpers.CairoRectangle (gr, ClientRectangle, CornerRadius);
+                               gr.Clip ();
+                       }
+
+                       for (int i = 0; i < Children.Count; i++) {
+                               if (i == SelectedTab)
+                                       continue;
+                               Children [i].Paint (ref gr);
+                       }
+
+                       if (SelectedTab < Children.Count && SelectedTab >= 0)
+                               Children [SelectedTab].Paint (ref gr);
+
+                       gr.Restore ();
+               }
+
+               #region Mouse handling
+               public override void checkHoverWidget (MouseMoveEventArgs e)
+               {
+                       if (CurrentInterface.HoverWidget != this) {
+                               CurrentInterface.HoverWidget = this;
+                               onMouseEnter (this, e);
+                       }
+
+                       if (SelectedTab > Children.Count - 1)
+                               return;
+
+                       if (((Children[SelectedTab] as TabItem).Content.Parent as GraphicObject).MouseIsIn(e.Position))
+                       {
+                               Children[SelectedTab].checkHoverWidget (e);
+                               return;
+                       }
+                       for (int i = Children.Count - 1; i >= 0; i--) {
+                               TabItem ti = Children [i] as TabItem;
+                               if (ti.TabTitle.MouseIsIn(e.Position))
+                               {
+                                       Children[i].checkHoverWidget (e);
+                                       return;
+                               }
+                       }
+               }
+               #endregion
+
+               void Ti_MouseDown (object sender, MouseButtonEventArgs e)
+               {
+                       SelectedTab = Children.IndexOf (sender as GraphicObject);
+               }
+       }
+}
+
diff --git a/src/GraphicObjects/Base/TemplatedContainer.cs b/src/GraphicObjects/Base/TemplatedContainer.cs
new file mode 100644 (file)
index 0000000..1ab8cf7
--- /dev/null
@@ -0,0 +1,128 @@
+//
+// TemplatedContainer.cs
+//
+// Author:
+//       Jean-Philippe Bruyère <jp.bruyere@hotmail.com>
+//
+// Copyright (c) 2013-2017 Jean-Philippe Bruyère
+//
+// 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.Xml.Serialization;
+using System.Xml;
+using System.Reflection;
+
+namespace Crow
+{
+       public abstract class TemplatedContainer : TemplatedControl
+       {
+               #region CTOR
+               public TemplatedContainer () : base(){}
+               #endregion
+
+               [XmlAttributeAttribute]public virtual GraphicObject Content{ get; set;}
+
+               #region GraphicObject overrides
+               public override GraphicObject FindByName (string nameToFind)
+               {
+                       if (Name == nameToFind)
+                               return this;
+
+                       return Content == null ? null : Content.FindByName (nameToFind);
+               }
+               public override bool Contains (GraphicObject goToFind)
+               {
+                       if (Content == null)
+                               return base.Contains (goToFind);
+
+                       if (Content == goToFind)
+                               return true;
+                       return Content.Contains (goToFind);
+               }
+               #endregion
+
+               #region IXmlSerialisation Overrides
+               public override void ReadXml(System.Xml.XmlReader reader)
+               {
+                       using (System.Xml.XmlReader subTree = reader.ReadSubtree ()) {
+                               subTree.Read ();
+                               string tmp = subTree.ReadOuterXml ();
+
+                               //seek for template tag
+                               using (XmlReader xr = new XmlTextReader (tmp, XmlNodeType.Element, null)) {
+                                       xr.Read ();
+                                       base.ReadXml (xr);
+                               }
+                               //process content
+                               using (XmlReader xr = new XmlTextReader (tmp, XmlNodeType.Element, null)) {
+                                       xr.Read (); //skip current node
+
+                                       while (!xr.EOF) {
+                                               xr.Read (); //read first child
+
+                                               if (!xr.IsStartElement ())
+                                                       continue;
+
+                                               if (xr.Name == "Template"){
+                                                       xr.Skip ();
+                                                       if (!xr.IsStartElement ())
+                                                               continue;
+                                               }
+
+                                               Type t = Type.GetType ("Crow." + xr.Name);
+                                               if (t == null) {
+                                                       Assembly a = Assembly.GetEntryAssembly ();
+                                                       foreach (Type expT in a.GetExportedTypes ()) {
+                                                               if (expT.Name == xr.Name) {
+                                                                       t = expT;
+                                                                       break;
+                                                               }
+                                                       }
+                                               }
+                                               if (t == null)
+                                                       throw new Exception (xr.Name + " type not found");
+
+                                               GraphicObject go = (GraphicObject)Activator.CreateInstance (t);
+
+                                               (go as IXmlSerializable).ReadXml (xr);
+
+                                               Content = go;
+
+                                               xr.Read (); //closing tag
+                                       }
+
+                               }
+                       }
+               }
+               public override void WriteXml(System.Xml.XmlWriter writer)
+               {
+                       base.WriteXml(writer);
+
+                       if (Content == null)
+                               return;
+                       //TODO: if template is not the default one, we have to save it
+                       writer.WriteStartElement(Content.GetType().Name);
+                       (Content as IXmlSerializable).WriteXml(writer);
+                       writer.WriteEndElement();
+               }
+               #endregion
+       }
+}
+
diff --git a/src/GraphicObjects/Base/TemplatedControl.cs b/src/GraphicObjects/Base/TemplatedControl.cs
new file mode 100644 (file)
index 0000000..082d042
--- /dev/null
@@ -0,0 +1,210 @@
+//
+// TemplatedControl.cs
+//
+// Author:
+//       Jean-Philippe Bruyère <jp.bruyere@hotmail.com>
+//
+// Copyright (c) 2013-2017 Jean-Philippe Bruyère
+//
+// 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.Xml.Serialization;
+using System.ComponentModel;
+using System.IO;
+using System.Xml;
+using System.Diagnostics;
+using System.Linq;
+using System.Collections.Generic;
+using System.Text;
+using System.Reflection;
+
+namespace Crow
+{
+       public abstract class TemplatedControl : PrivateContainer, IXmlSerializable
+       {
+               #region CTOR
+               public TemplatedControl () : base()
+               {
+               }
+               #endregion
+
+               string _template;
+               string caption;
+
+               [XmlAttributeAttribute][DefaultValue(null)]
+               public string Template {
+                       get { return _template; }
+                       set {
+                               if (Template == value)
+                                       return;
+                               _template = value;
+
+                               if (string.IsNullOrEmpty(_template))
+                                       loadTemplate ();
+                               else
+                                       loadTemplate (CurrentInterface.Load (_template));
+                       }
+               }
+               [XmlAttributeAttribute()][DefaultValue("Templated Control")]
+               public virtual string Caption {
+                       get { return caption; }
+                       set {
+                               if (caption == value)
+                                       return;
+                               caption = value;
+                               NotifyValueChanged ("Caption", caption);
+                       }
+               }
+               #region GraphicObject overrides
+               public override void Initialize ()
+               {
+                       loadTemplate ();
+                       base.Initialize ();
+               }
+               public override GraphicObject FindByName (string nameToFind)
+               {
+                       //prevent name searching in template
+                       return nameToFind == this.Name ? this : null;
+               }
+               protected override void onDraw (Cairo.Context gr)
+               {
+                       //onDraw is overrided to prevent default drawing of background, template top container
+                       //may have a binding to root background or a fixed one.
+                       //this allow applying root background to random template's component
+                       gr.Save ();
+
+                       if (ClipToClientRect) {
+                               //clip to client zone
+                               CairoHelpers.CairoRectangle (gr, ClientRectangle, CornerRadius);
+                               gr.Clip ();
+                       }
+
+                       if (child != null)
+                               child.Paint (ref gr);
+                       gr.Restore ();
+               }
+               #endregion
+
+               protected virtual void loadTemplate(GraphicObject template = null)
+               {
+                       if (template == null) {
+                               if (!Interface.DefaultTemplates.ContainsKey (this.GetType ().FullName))
+                                       throw new Exception (string.Format ("No default template found for '{0}'", this.GetType ().FullName));
+                               this.SetChild (CurrentInterface.Load (Interface.DefaultTemplates[this.GetType ().FullName]));
+                       }else
+                               this.SetChild (template);
+               }
+
+               //TODO:IXmlSerializable is not used anymore
+               #region IXmlSerializable
+               public override System.Xml.Schema.XmlSchema GetSchema(){ return null; }
+               public override void ReadXml(System.Xml.XmlReader reader)
+               {
+                       //Template could be either an attribute containing path or expressed inlined
+                       //as a Template Element
+                       using (System.Xml.XmlReader subTree = reader.ReadSubtree())
+                       {
+                               subTree.Read ();
+
+                               string template = reader.GetAttribute ("Template");
+                               string tmp = subTree.ReadOuterXml ();
+
+                               //Load template from path set as attribute in templated control
+                               if (string.IsNullOrEmpty (template)) {
+                                       //seek for template tag first
+                                       using (XmlReader xr = new XmlTextReader (tmp, XmlNodeType.Element, null)) {
+                                               //load template first if inlined
+
+                                               xr.Read (); //read first child
+                                               xr.Read (); //skip root node
+
+                                               while (!xr.EOF) {
+                                                       if (!xr.IsStartElement ()) {
+                                                               xr.Read ();
+                                                               continue;
+                                                       }
+                                                       if (xr.Name == "ItemTemplate") {
+                                                               string dataType = "default", datas = "", itemTmp;
+                                                               while (xr.MoveToNextAttribute ()) {
+                                                                       if (xr.Name == "DataType")
+                                                                               dataType = xr.Value;
+                                                                       else if (xr.Name == "Data")
+                                                                               datas = xr.Value;
+                                                               }
+                                                               xr.MoveToElement ();
+                                                               itemTmp = xr.ReadInnerXml ();
+
+//                                                             if (ItemTemplates == null)
+//                                                                     ItemTemplates = new Dictionary<string, ItemTemplate> ();
+//
+//                                                             using (IMLReader iTmp = new IMLReader (null, itemTmp)) {
+//                                                                     ItemTemplates [dataType] =
+//                                                                             new ItemTemplate (iTmp.RootType, iTmp.GetLoader (), dataType, datas);
+//                                                             }
+//                                                             if (!string.IsNullOrEmpty (datas))
+//                                                                     ItemTemplates [dataType].CreateExpandDelegate(this);
+
+                                                               continue;
+                                                       }
+                                                       if (xr.Name == "Template") {
+                                                               xr.Read ();
+
+                                                               Type t = Type.GetType ("Crow." + xr.Name);
+                                                               if (t == null) {
+                                                                       Assembly a = Assembly.GetEntryAssembly ();
+                                                                       foreach (Type expT in a.GetExportedTypes ()) {
+                                                                               if (expT.Name == xr.Name) {
+                                                                                       t = expT;
+                                                                                       break;
+                                                                               }
+                                                                       }
+                                                               }
+                                                               GraphicObject go = (GraphicObject)Activator.CreateInstance (t);
+                                                               (go as IXmlSerializable).ReadXml (xr);
+
+                                                               loadTemplate (go);
+                                                               continue;
+                                                       }
+                                                       xr.ReadInnerXml ();
+                                               }
+                                       }
+                               } else
+                                       loadTemplate (CurrentInterface.Load (template));
+
+                               //if no template found, load default one
+                               if (this.child == null)
+                                       loadTemplate ();
+
+                               //normal xml read
+                               using (XmlReader xr = new XmlTextReader (tmp, XmlNodeType.Element, null)) {
+                                       xr.Read ();
+                                       base.ReadXml(xr);
+                               }
+                       }
+               }
+               public override void WriteXml(System.Xml.XmlWriter writer)
+               {
+                       //TODO:
+                       throw new NotImplementedException();
+               }
+               #endregion
+       }
+}
+
diff --git a/src/GraphicObjects/Base/TemplatedGroup.cs b/src/GraphicObjects/Base/TemplatedGroup.cs
new file mode 100644 (file)
index 0000000..e444716
--- /dev/null
@@ -0,0 +1,489 @@
+//
+// TemplatedGroup.cs
+//
+// Author:
+//       Jean-Philippe Bruyère <jp.bruyere@hotmail.com>
+//
+// Copyright (c) 2013-2017 Jean-Philippe Bruyère
+//
+// 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.Xml.Serialization;
+using System.Xml;
+using System.Reflection;
+using System.Collections.Generic;
+using System.ComponentModel;
+using System.Collections;
+using System.Threading;
+using System.Linq;
+
+namespace Crow
+{
+       public abstract class TemplatedGroup : TemplatedControl
+       {
+               #region CTOR
+               public TemplatedGroup () : base(){}
+               #endregion
+
+               protected Group items;
+               string _itemTemplate, _dataTest;
+
+               #region events
+               public event EventHandler<SelectionChangeEventArgs> SelectedItemChanged;
+               public event EventHandler Loaded;
+               #endregion
+
+               IList data;
+               int _selectedIndex = -1;
+               Color selBackground, selForeground;
+
+               int itemPerPage = 50;
+               CrowThread loadingThread = null;
+               volatile bool cancelLoading = false;
+
+               bool isPaged = false;
+
+               #region Templating
+               //TODO: dont instantiate ItemTemplates if not used
+               //but then i should test if null in msil gen
+               public Dictionary<string, ItemTemplate> ItemTemplates = new Dictionary<string, Crow.ItemTemplate>();
+
+               /// <summary>
+               /// Default item template
+               /// </summary>
+               [XmlAttributeAttribute][DefaultValue("#Crow.Templates.ItemTemplate.goml")]
+               public string ItemTemplate {
+                       get { return _itemTemplate; }
+                       set {
+                               if (value == _itemTemplate)
+                                       return;
+
+                               _itemTemplate = value;
+
+                               //TODO:reload list with new template?
+                               NotifyValueChanged("ItemTemplate", _itemTemplate);
+                       }
+               }
+               protected override void loadTemplate(GraphicObject template = null)
+               {
+                       base.loadTemplate (template);
+
+                       items = this.child.FindByName ("ItemsContainer") as Group;
+                       if (items == null)
+                               throw new Exception ("TemplatedGroup template Must contain a Group named 'ItemsContainer'");
+                       if (items.Children.Count == 0)
+                               NotifyValueChanged ("HasChildren", false);
+                       else
+                               NotifyValueChanged ("HasChildren", true);
+               }
+               /// <summary>
+               /// Use to define condition on Data item for selecting among ItemTemplates.
+               /// Default value is 'TypeOf' for selecting Template depending on Type of Data.
+               /// Other possible values are properties of Data
+               /// </summary>
+               /// <value>The data property test.</value>
+               [XmlAttributeAttribute][DefaultValue("TypeOf")]
+               public string DataTest {
+                       get { return _dataTest; }
+                       set {
+                               if (value == _dataTest)
+                                       return;
+
+                               _dataTest = value;
+
+                               NotifyValueChanged("DataTest", _dataTest);
+                       }
+               }
+               #endregion
+
+               public virtual List<GraphicObject> Items{
+                       get {
+                               return isPaged ? items.Children.SelectMany(x => (x as Group).Children).ToList()
+                               : items.Children;
+                       }
+               }
+               [XmlAttributeAttribute][DefaultValue(-1)]public int SelectedIndex{
+                       get { return _selectedIndex; }
+                       set {
+                               if (value == _selectedIndex)
+                                       return;
+
+                               if (_selectedIndex >= 0 && Items.Count > _selectedIndex) {
+                                       Items[_selectedIndex].Foreground = Color.Transparent;
+                                       Items[_selectedIndex].Background = Color.Transparent;
+                               }
+
+                               _selectedIndex = value;
+
+                               if (_selectedIndex >= 0 && Items.Count > _selectedIndex) {
+                                       Items[_selectedIndex].Foreground = SelectionForeground;
+                                       Items[_selectedIndex].Background = SelectionBackground;
+                               }
+
+                               NotifyValueChanged ("SelectedIndex", _selectedIndex);
+                               NotifyValueChanged ("SelectedItem", SelectedItem);
+                               SelectedItemChanged.Raise (this, new SelectionChangeEventArgs (SelectedItem));
+                       }
+               }
+               [XmlIgnore]public virtual object SelectedItem{
+                       get { return data == null ? null : _selectedIndex < 0 ? null : data[_selectedIndex]; }
+               }
+               [XmlIgnore]public bool HasItems {
+                       get { return Items.Count > 0; }
+               }
+               [XmlAttributeAttribute]public IList Data {
+                       get { return data; }
+                       set {
+                               if (value == data)
+                                       return;
+
+                               cancelLoadingThread ();
+
+                               data = value;
+
+                               NotifyValueChanged ("Data", data);
+
+                               lock (CurrentInterface.LayoutMutex)
+                                       ClearItems ();
+
+                               if (data == null)
+                                       return;
+
+                               loadingThread = new CrowThread (this, loading);
+                               loadingThread.Finished += (object sender, EventArgs e) => (sender as TemplatedGroup).Loaded.Raise (sender, e);
+                               loadingThread.Start ();
+
+                               NotifyValueChanged ("SelectedIndex", _selectedIndex);
+                               NotifyValueChanged ("SelectedItem", SelectedItem);
+                               SelectedItemChanged.Raise (this, new SelectionChangeEventArgs (SelectedItem));
+                               NotifyValueChanged ("HasItems", HasItems);
+                       }
+               }
+
+               [XmlAttributeAttribute][DefaultValue("SteelBlue")]
+               public virtual Color SelectionBackground {
+                       get { return selBackground; }
+                       set {
+                               if (value == selBackground)
+                                       return;
+                               selBackground = value;
+                               NotifyValueChanged ("SelectionBackground", selBackground);
+                               RegisterForRedraw ();
+                       }
+               }
+               [XmlAttributeAttribute][DefaultValue("White")]
+               public virtual Color SelectionForeground {
+                       get { return selForeground; }
+                       set {
+                               if (value == selForeground)
+                                       return;
+                               selForeground = value;
+                               NotifyValueChanged ("SelectionForeground", selForeground);
+                               RegisterForRedraw ();
+                       }
+               }
+
+               protected void raiseSelectedItemChanged(){
+                       SelectedItemChanged.Raise (this, new SelectionChangeEventArgs (SelectedItem));
+               }
+
+
+               public virtual void AddItem(GraphicObject g){
+                       items.AddChild (g);
+                       g.LogicalParent = this;
+                       NotifyValueChanged ("HasChildren", true);
+               }
+               public virtual void RemoveItem(GraphicObject g)
+               {
+                       g.LogicalParent = null;
+                       items.RemoveChild (g);
+                       if (items.Children.Count == 0)
+                               NotifyValueChanged ("HasChildren", false);
+               }
+
+               public virtual void ClearItems()
+               {
+                       _selectedIndex = -1;
+                       NotifyValueChanged ("SelectedIndex", _selectedIndex);
+                       NotifyValueChanged ("SelectedItem", null);
+
+                       items.ClearChildren ();
+                       NotifyValueChanged ("HasChildren", false);
+               }
+
+
+               #region GraphicObject overrides
+               public override GraphicObject FindByName (string nameToFind)
+               {
+                       if (Name == nameToFind)
+                               return this;
+
+                       foreach (GraphicObject w in Items) {
+                               GraphicObject r = w.FindByName (nameToFind);
+                               if (r != null)
+                                       return r;
+                       }
+                       return null;
+               }
+               public override bool Contains (GraphicObject goToFind)
+               {
+                       foreach (GraphicObject w in Items) {
+                               if (w == goToFind)
+                                       return true;
+                               if (w.Contains (goToFind))
+                                       return true;
+                       }
+                       return base.Contains(goToFind);
+               }
+//             public override void ClearBinding ()
+//             {
+//                     if (items != null)
+//                             items.ClearBinding ();
+//
+//                     base.ClearBinding ();
+//             }
+//             public override void ResolveBindings ()
+//             {
+//                     base.ResolveBindings ();
+//                     if (items != null)
+//                             items.ResolveBindings ();
+//             }
+               #endregion
+
+               #region IXmlSerialisation Overrides
+               public override void ReadXml(System.Xml.XmlReader reader)
+               {
+                       using (System.Xml.XmlReader subTree = reader.ReadSubtree ()) {
+                               subTree.Read ();
+                               string tmp = subTree.ReadOuterXml ();
+
+                               //seek for template tag
+                               using (XmlReader xr = new XmlTextReader (tmp, XmlNodeType.Element, null)) {
+                                       xr.Read ();
+                                       base.ReadXml (xr);
+                               }
+                               //process content
+                               using (XmlReader xr = new XmlTextReader (tmp, XmlNodeType.Element, null)) {
+                                       xr.Read (); //skip current node
+
+                                       while (!xr.EOF) {
+                                               xr.Read (); //read first child
+
+                                               if (!xr.IsStartElement ())
+                                                       continue;
+
+                                               if (xr.Name == "Template" || Name == "ItemTemplate"){
+                                                       xr.Skip ();
+                                                       if (!xr.IsStartElement ())
+                                                               continue;
+                                               }
+
+                                               Type t = Type.GetType ("Crow." + xr.Name);
+                                               if (t == null) {
+                                                       Assembly a = Assembly.GetEntryAssembly ();
+                                                       foreach (Type expT in a.GetExportedTypes ()) {
+                                                               if (expT.Name == xr.Name) {
+                                                                       t = expT;
+                                                                       break;
+                                                               }
+                                                       }
+                                               }
+                                               if (t == null)
+                                                       throw new Exception (xr.Name + " type not found");
+
+                                               GraphicObject go = (GraphicObject)Activator.CreateInstance (t);
+
+                                               (go as IXmlSerializable).ReadXml (xr);
+
+                                               AddItem (go);
+
+                                               xr.Read (); //closing tag
+                                       }
+
+                               }
+                       }
+               }
+               public override void WriteXml(System.Xml.XmlWriter writer)
+               {
+                       throw new NotImplementedException ();
+               }
+               #endregion
+
+               void loading(){
+                       if (ItemTemplates == null)
+                               ItemTemplates = new Dictionary<string, ItemTemplate> ();
+                       if (!ItemTemplates.ContainsKey ("default"))
+                               ItemTemplates ["default"] = Interface.GetItemTemplate (ItemTemplate);
+
+                       for (int i = 1; i <= (data.Count / itemPerPage) + 1; i++) {
+                               if (cancelLoading)
+                                       return;
+                               loadPage (i);
+                               Thread.Sleep (1);
+                       }
+               }
+               void cancelLoadingThread(){
+                       if (loadingThread != null)
+                               loadingThread.Cancel ();
+               }
+               void loadPage(int pageNum)
+               {
+                       #if DEBUG_LOAD
+                       Stopwatch loadingTime = new Stopwatch ();
+                       loadingTime.Start ();
+                       #endif
+
+                       Group page;
+                       if (typeof(Wrapper).IsAssignableFrom (items.GetType ())) {
+                               page = items;
+                               itemPerPage = int.MaxValue;
+                       } else if (typeof(GenericStack).IsAssignableFrom (items.GetType ())) {
+                               GenericStack gs = new GenericStack ();
+                               gs.CurrentInterface = items.CurrentInterface;
+                               gs.Initialize ();
+                               gs.Orientation = (items as GenericStack).Orientation;
+                               gs.Width = items.Width;
+                               gs.Height = items.Height;
+                               gs.VerticalAlignment = items.VerticalAlignment;
+                               gs.HorizontalAlignment = items.HorizontalAlignment;
+                               page = gs;
+                               page.Name = "page" + pageNum;
+                               isPaged = true;
+                       } else {
+                               page = Activator.CreateInstance (items.GetType ()) as Group;
+                               page.Name = "page" + pageNum;
+                               isPaged = true;
+                       }
+
+                       for (int i = (pageNum - 1) * itemPerPage; i < pageNum * itemPerPage; i++) {
+                               if (i >= data.Count)
+                                       break;
+                               if (cancelLoading)
+                                       return;
+
+                               loadItem (i, page);
+                       }
+
+                       if (page == items)
+                               return;
+                       lock (CurrentInterface.LayoutMutex)
+                               items.AddChild (page);
+
+                       #if DEBUG_LOAD
+                       loadingTime.Stop ();
+                       Debug.WriteLine("Listbox {2} Loading: {0} ticks \t, {1} ms",
+                       loadingTime.ElapsedTicks,
+                       loadingTime.ElapsedMilliseconds, this.ToString());
+                       #endif
+               }
+               string getItempKey(Type dataType, object o){
+                       try {
+                               return dataType.GetProperty (_dataTest).GetGetMethod ().Invoke (o, null).ToString();
+                       } catch (Exception ex) {
+                               return dataType.FullName;
+                       }
+               }
+               protected void loadItem(int i, Group page){
+                       if (data [i] == null)//TODO:surely a threading sync problem
+                               return;
+                       GraphicObject g = null;
+                       ItemTemplate iTemp = null;
+                       Type dataType = data [i].GetType ();
+                       string itempKey = dataType.FullName;
+
+                       if (_dataTest != "TypeOf")
+                               itempKey = getItempKey (dataType, data [i]);
+
+                       if (ItemTemplates.ContainsKey (itempKey))
+                               iTemp = ItemTemplates [itempKey];
+                       else {
+                               foreach (string it in ItemTemplates.Keys) {
+                                       Type t = Type.GetType (it);
+                                       if (t == null) {
+                                               Assembly a = Assembly.GetEntryAssembly ();
+                                               foreach (Type expT in a.GetExportedTypes ()) {
+                                                       if (expT.Name == it) {
+                                                               t = expT;
+                                                               break;
+                                                       }
+                                               }
+                                       }
+                                       if (t == null)
+                                               continue;
+                                       if (t.IsAssignableFrom (dataType)) {//TODO:types could be cached
+                                               iTemp = ItemTemplates [it];
+                                               break;
+                                       }
+                               }
+                               if (iTemp == null)
+                                       iTemp = ItemTemplates ["default"];
+                       }
+
+                       lock (CurrentInterface.LayoutMutex) {
+                               g = iTemp.CreateInstance(CurrentInterface);
+                               page.AddChild (g);
+                               //g.LogicalParent = this;
+                               registerItemClick (g);
+                       }
+
+                       if (iTemp.Expand != null && g is Expandable) {
+                               (g as Expandable).Expand += iTemp.Expand;
+                               (g as Expandable).GetIsExpandable = iTemp.HasSubItems;
+                       }
+
+                       g.DataSource = data [i];
+               }
+               protected virtual void registerItemClick(GraphicObject g){
+                       g.MouseClick += itemClick;
+               }
+//             protected void _list_LayoutChanged (object sender, LayoutingEventArgs e)
+//             {
+//                     #if DEBUG_LAYOUTING
+//                     Debug.WriteLine("list_LayoutChanged");
+//                     #endif
+//                     if (_gsList.Orientation == Orientation.Horizontal) {
+//                             if (e.LayoutType == LayoutingType.Width)
+//                                     _gsList.Width = approxSize;
+//                     } else if (e.LayoutType == LayoutingType.Height)
+//                             _gsList.Height = approxSize;
+//             }
+               int approxSize
+               {
+                       get {
+                               if (data == null)
+                                       return -1;
+                               GenericStack page1 = items.FindByName ("page1") as GenericStack;
+                               if (page1 == null)
+                                       return -1;
+
+                               return page1.Orientation == Orientation.Horizontal ?
+                                       data.Count < itemPerPage ?
+                                       -1:
+                                       (int)Math.Ceiling ((double)page1.Slot.Width / (double)itemPerPage * (double)(data.Count+1)):
+                                       data.Count < itemPerPage ?
+                                       -1:
+                                       (int)Math.Ceiling ((double)page1.Slot.Height / (double)itemPerPage * (double)(data.Count+1));
+                       }
+               }
+               internal virtual void itemClick(object sender, MouseButtonEventArgs e){
+                       SelectedIndex = data.IndexOf((sender as GraphicObject).DataSource);
+               }
+       }
+}
diff --git a/src/GraphicObjects/Base/TextBox.cs b/src/GraphicObjects/Base/TextBox.cs
new file mode 100644 (file)
index 0000000..0cbee9f
--- /dev/null
@@ -0,0 +1,228 @@
+//
+// TextBox.cs
+//
+// Author:
+//       Jean-Philippe Bruyère <jp.bruyere@hotmail.com>
+//
+// Copyright (c) 2013-2017 Jean-Philippe Bruyère
+//
+// 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 Cairo;
+using System.Diagnostics;
+using System.Xml.Serialization;
+
+namespace Crow
+{
+    public class TextBox : Label
+    {
+               #region CTOR
+               public TextBox()
+               { }
+               public TextBox(string _initialValue)
+                       : base(_initialValue)
+               {
+
+               }
+               #endregion
+
+               #region GraphicObject overrides
+               [XmlIgnore]public override bool HasFocus   //trigger update when lost focus to errase text beam
+        {
+            get
+            {
+                return base.HasFocus;
+            }
+            set
+            {
+                base.HasFocus = value;
+                RegisterForRedraw();
+            }
+        }
+
+               protected override void onDraw (Context gr)
+               {
+                       base.onDraw (gr);
+                       FontExtents fe = gr.FontExtents;
+               }
+               #endregion
+                       
+        #region Keyboard handling
+               public override void onKeyDown (object sender, KeyboardKeyEventArgs e)
+               {
+                       base.onKeyDown (sender, e);
+
+                       Key key = e.Key;
+
+                       switch (key)
+                       {
+                       case Key.Back:
+                               if (CurrentPosition == 0)
+                                       return;
+                               this.DeleteChar();
+                               break;
+                       case Key.Clear:
+                               break;
+                       case Key.Delete:
+                               if (selectionIsEmpty) {
+                                       if (!MoveRight ())
+                                               return;
+                               }else if (e.Shift)
+                                       CurrentInterface.Clipboard = this.SelectedText;
+                               this.DeleteChar ();
+                               break;
+                       case Key.Enter:
+                       case Key.KeypadEnter:
+                               if (!selectionIsEmpty)
+                                       this.DeleteChar ();
+                               if (Multiline)
+                                       this.InsertLineBreak ();
+                               else
+                                       OnTextChanged(this,new TextChangeEventArgs(Text));
+                               break;
+                       case Key.Escape:
+                               Text = "";
+                               CurrentColumn = 0;
+                               SelRelease = -1;
+                               break;
+                       case Key.Home:
+                               if (e.Shift) {
+                                       if (selectionIsEmpty)
+                                               SelBegin = new Point (CurrentColumn, CurrentLine);
+                                       if (e.Control)
+                                               CurrentLine = 0;
+                                       CurrentColumn = 0;
+                                       SelRelease = new Point (CurrentColumn, CurrentLine);
+                                       break;
+                               }
+                               SelRelease = -1;
+                               if (e.Control)
+                                       CurrentLine = 0;
+                               CurrentColumn = 0;
+                               break;
+                       case Key.End:
+                               if (e.Shift) {
+                                       if (selectionIsEmpty)
+                                               SelBegin = CurrentPosition;
+                                       if (e.Control)
+                                               CurrentLine = int.MaxValue;
+                                       CurrentColumn = int.MaxValue;
+                                       SelRelease = CurrentPosition;
+                                       break;
+                               }
+                               SelRelease = -1;
+                               if (e.Control)
+                                       CurrentLine = int.MaxValue;
+                               CurrentColumn = int.MaxValue;
+                               break;
+                       case Key.Insert:
+                               if (e.Shift)
+                                       this.Insert (CurrentInterface.Clipboard);
+                               else if (e.Control && !selectionIsEmpty)
+                                       CurrentInterface.Clipboard = this.SelectedText;
+                               break;
+                       case Key.Left:
+                               if (e.Shift) {
+                                       if (selectionIsEmpty)
+                                               SelBegin = new Point(CurrentColumn, CurrentLine);
+                                       if (e.Control)
+                                               GotoWordStart ();
+                                       else if (!MoveLeft ())
+                                               return;
+                                       SelRelease = CurrentPosition;
+                                       break;
+                               }
+                               SelRelease = -1;
+                               if (e.Control)
+                                       GotoWordStart ();
+                               else
+                                       MoveLeft();
+                               break;
+                       case Key.Right:
+                               if (e.Shift) {
+                                       if (selectionIsEmpty)
+                                               SelBegin = CurrentPosition;
+                                       if (e.Control)
+                                               GotoWordEnd ();
+                                       else if (!MoveRight ())
+                                               return;
+                                       SelRelease = CurrentPosition;
+                                       break;
+                               }
+                               SelRelease = -1;
+                               if (e.Control)
+                                       GotoWordEnd ();
+                               else
+                                       MoveRight ();
+                               break;
+                       case Key.Up:
+                               if (e.Shift) {
+                                       if (selectionIsEmpty)
+                                               SelBegin = CurrentPosition;
+                                       CurrentLine--;
+                                       SelRelease = CurrentPosition;
+                                       break;
+                               }
+                               SelRelease = -1;
+                               CurrentLine--;
+                               break;
+                       case Key.Down:
+                               if (e.Shift) {
+                                       if (selectionIsEmpty)
+                                               SelBegin = CurrentPosition;
+                                       CurrentLine++;
+                                       SelRelease = CurrentPosition;
+                                       break;
+                               }
+                               SelRelease = -1;
+                               CurrentLine++;                          
+                               break;
+                       case Key.Menu:
+                               break;
+                       case Key.NumLock:
+                               break;
+                       case Key.PageDown:                              
+                               break;
+                       case Key.PageUp:
+                               break;
+                       case Key.RWin:
+                               break;
+                       case Key.Tab:
+                               this.Insert ("\t");
+                               break;
+                       default:
+                               break;
+                       }
+                       RegisterForGraphicUpdate();
+               }
+               public override void onKeyPress (object sender, KeyPressEventArgs e)
+               {
+                       base.onKeyPress (sender, e);
+
+                       this.Insert (e.KeyChar.ToString());
+
+                       SelRelease = -1;
+                       SelBegin = new Point(CurrentColumn, SelBegin.Y);
+
+                       RegisterForGraphicUpdate();
+               }
+        #endregion
+       } 
+}
diff --git a/src/GraphicObjects/Base/TextRun.cs b/src/GraphicObjects/Base/TextRun.cs
new file mode 100644 (file)
index 0000000..a312ca1
--- /dev/null
@@ -0,0 +1,315 @@
+//
+// TextRun.cs
+//
+// Author:
+//       Jean-Philippe Bruyère <jp.bruyere@hotmail.com>
+//
+// Copyright (c) 2013-2017 Jean-Philippe Bruyère
+//
+// 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.Generic;
+using System.Linq;
+using System.Text;
+using System.Diagnostics;
+using Cairo;
+using System.Text.RegularExpressions;
+using System.Xml.Serialization;
+using System.ComponentModel;
+
+namespace Crow
+{
+       public class TextRun : GraphicObject
+       {
+               #region CTOR
+               public TextRun ()
+               {
+
+               }
+               public TextRun (string _text)
+                       : base ()
+               {
+                       Text = _text;
+               }
+               #endregion
+
+               //TODO:change protected to private
+
+               #region private and protected fields
+               protected string _text = "label";
+               Alignment _textAlignment = Alignment.Left;
+               bool horizontalStretch = false;
+               bool verticalStretch = false;
+               bool _multiline;
+               bool wordWrap;
+               protected Rectangle rText;
+               protected float widthRatio = 1f;
+               protected float heightRatio = 1f;
+               protected FontExtents fe;
+               protected TextExtents te;
+               #endregion
+
+
+               [XmlAttributeAttribute ()]
+               [DefaultValue (Alignment.Left)]
+               public Alignment TextAlignment {
+                       get { return _textAlignment; }
+                       set { _textAlignment = value; }
+               }
+               [XmlAttributeAttribute ()]
+               [DefaultValue (false)]
+               public virtual bool HorizontalStretch {
+                       get { return horizontalStretch; }
+                       set {
+                               if (horizontalStretch == value)
+                                       return;
+                               horizontalStretch = value;
+                               RegisterForRedraw ();
+                               NotifyValueChanged ("HorizontalStretch", horizontalStretch);
+                       }
+               }
+               [XmlAttributeAttribute ()]
+               [DefaultValue (false)]
+               public virtual bool VerticalStretch {
+                       get { return verticalStretch; }
+                       set {
+                               if (verticalStretch == value)
+                                       return;
+                               verticalStretch = value;
+                               RegisterForRedraw ();
+                               NotifyValueChanged ("VerticalStretch", verticalStretch);
+                       }
+               }
+               [XmlAttributeAttribute ()]
+               [DefaultValue ("label")]
+               public string Text {
+                       get {
+                               return lines == null ?
+                                       _text : lines.Aggregate ((i, j) => i + Interface.LineBreak + j);
+                       }
+                       set {
+                               if (_text == value)
+                                       return;
+
+                               RegisterForGraphicUpdate ();
+
+                               _text = value;
+
+                               if (string.IsNullOrEmpty (_text))
+                                       _text = "";
+
+                               lines = getLines;
+                       }
+               }
+               [XmlAttributeAttribute ()]
+               [DefaultValue (false)]
+               public bool Multiline {
+                       get { return _multiline; }
+                       set {
+                               _multiline = value;
+                               RegisterForGraphicUpdate ();
+                       }
+               }
+               [XmlAttributeAttribute ()]
+               [DefaultValue (false)]
+               public bool WordWrap {
+                       get {
+                               return wordWrap;
+                       }
+                       set {
+                               if (wordWrap == value)
+                                       return;
+                               wordWrap = value;
+                               RegisterForGraphicUpdate ();
+                       }
+               }
+
+               List<string> lines;
+               List<string> getLines {
+                       get {
+                               return _multiline ?
+                                       Regex.Split (_text, "\r\n|\r|\n").ToList () :
+                                       new List<string> (new string [] { _text });
+                       }
+               }
+
+               #region GraphicObject overrides
+               protected override int measureRawSize (LayoutingType lt)
+               {
+                       if (lines == null)
+                               lines = getLines;
+
+                       using (ImageSurface img = new ImageSurface (Format.Argb32, 10, 10)) {
+                               using (Context gr = new Context (img)) {
+                                       //Cairo.FontFace cf = gr.GetContextFontFace ();
+
+                                       gr.SelectFontFace (Font.Name, Font.Slant, Font.Wheight);
+                                       gr.SetFontSize (Font.Size);
+
+
+                                       fe = gr.FontExtents;
+                                       te = new TextExtents ();
+
+                                       if (lt == LayoutingType.Height) {
+                                               int lc = lines.Count;
+                                               //ensure minimal height = text line height
+                                               if (lc == 0)
+                                                       lc = 1;
+
+                                               return (int)(fe.Height * lc) + Margin * 2;
+                                       }
+
+                                       foreach (string s in lines) {
+                                               string l = s.Replace("\t", new String (' ', Interface.TabSize));
+                                               TextExtents tmp = gr.TextExtents (l);
+                                               if (tmp.XAdvance > te.XAdvance)
+                                                       te = tmp;
+                                       }
+                                       return (int)Math.Ceiling (te.XAdvance) + Margin * 2;
+                               }
+                       }
+               }
+               protected override void onDraw (Context gr)
+               {
+                       base.onDraw (gr);
+
+                       gr.SelectFontFace (Font.Name, Font.Slant, Font.Wheight);
+                       gr.SetFontSize (Font.Size);
+                       gr.FontOptions = Interface.FontRenderingOptions;
+                       gr.Antialias = Interface.Antialias;
+
+                       rText = new Rectangle (new Size (
+                               measureRawSize (LayoutingType.Width), measureRawSize (LayoutingType.Height)));
+                       rText.Width -= 2 * Margin;
+                       rText.Height -= 2 * Margin;
+
+                       widthRatio = 1f;
+                       heightRatio = 1f;
+
+                       Rectangle cb = ClientRectangle;
+
+                       //ignore text alignment if size to content = true
+                       //or if text size is larger than client bounds
+                       if (Width < 0 || Height < 0 || rText.Width > cb.Width) {
+                               rText.X = cb.X;
+                               rText.Y = cb.Y;
+                       } else {
+                               if (horizontalStretch) {
+                                       widthRatio = (float)cb.Width / rText.Width;
+                                       if (!verticalStretch)
+                                               heightRatio = widthRatio;
+                               }
+                               if (verticalStretch) {
+                                       heightRatio = (float)cb.Height / rText.Height;
+                                       if (!horizontalStretch)
+                                               widthRatio = heightRatio;
+                               }
+
+                               rText.Width = (int)(widthRatio * cb.Width);
+                               rText.Height = (int)(heightRatio * cb.Height);
+
+                               switch (TextAlignment) {
+                               case Alignment.TopLeft:     //ok
+                                       rText.X = cb.X;
+                                       rText.Y = cb.Y;
+                                       break;
+                               case Alignment.Top:   //ok                                              
+                                       rText.Y = cb.Y;
+                                       rText.X = cb.X + cb.Width / 2 - rText.Width / 2;
+                                       break;
+                               case Alignment.TopRight:    //ok
+                                       rText.Y = cb.Y;
+                                       rText.X = cb.Right - rText.Width;
+                                       break;
+                               case Alignment.Left://ok
+                                       rText.X = cb.X;
+                                       rText.Y = cb.Y + cb.Height / 2 - rText.Height / 2;
+                                       break;
+                               case Alignment.Right://ok
+                                       rText.X = cb.X + cb.Width - rText.Width;
+                                       rText.Y = cb.Y + cb.Height / 2 - rText.Height / 2;
+                                       break;
+                               case Alignment.Bottom://ok
+                                       rText.X = cb.Width / 2 - rText.Width / 2;
+                                       rText.Y = cb.Height - rText.Height;
+                                       break;
+                               case Alignment.BottomLeft://ok
+                                       rText.X = cb.X;
+                                       rText.Y = cb.Bottom - rText.Height;
+                                       break;
+                               case Alignment.BottomRight://ok
+                                       rText.Y = cb.Bottom - rText.Height;
+                                       rText.X = cb.Right - rText.Width;
+                                       break;
+                               case Alignment.Center://ok
+                                       rText.X = cb.X + cb.Width / 2 - rText.Width / 2;
+                                       rText.Y = cb.Y + cb.Height / 2 - rText.Height / 2;
+                                       break;
+                               }
+                       }
+
+                       gr.FontMatrix = new Matrix (widthRatio * Font.Size, 0, 0, heightRatio * Font.Size, 0, 0);
+
+
+                       int curLineCount = 0;
+                       for (int i = 0; i < lines.Count; i++) {
+                               string l = lines [i].Replace ("\t", new String (' ', Interface.TabSize));
+                               List<string> wl = new List<string> ();
+                               int lineLength = (int)gr.TextExtents (l).XAdvance;
+
+                               if (wordWrap && lineLength > cb.Width) {
+                                       string tmpLine = "";
+                                       int curChar = 0;
+                                       while (curChar < l.Length) {
+                                               tmpLine += l [curChar];
+                                               if ((int)gr.TextExtents (tmpLine).XAdvance > cb.Width) {
+                                                       tmpLine = tmpLine.Remove (tmpLine.Length - 1);
+                                                       wl.Add (tmpLine);
+                                                       tmpLine = "";
+                                                       continue;
+                                               }
+                                               curChar++;
+                                       }
+                                       wl.Add (tmpLine);
+                               } else
+                                       wl.Add (l);
+
+                               foreach (string ll in wl) {
+                                       lineLength = (int)gr.TextExtents (ll).XAdvance;
+
+
+                                       if (string.IsNullOrWhiteSpace (ll)) {
+                                               curLineCount++;
+                                               continue;
+                                       }
+
+                                       Foreground.SetAsSource (gr);
+                                       gr.MoveTo (rText.X, rText.Y + fe.Ascent + fe.Height * curLineCount);
+
+                                       gr.ShowText (ll);
+                                       gr.Fill ();
+
+                                       curLineCount++;
+                               }
+                       }
+               }
+               #endregion
+       }
+}
diff --git a/src/GraphicObjects/Base/TreeView.cs b/src/GraphicObjects/Base/TreeView.cs
new file mode 100644 (file)
index 0000000..6549f14
--- /dev/null
@@ -0,0 +1,120 @@
+//
+// TreeView.cs
+//
+// Author:
+//       Jean-Philippe Bruyère <jp.bruyere@hotmail.com>
+//
+// Copyright (c) 2013-2017 Jean-Philippe Bruyère
+//
+// 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.Xml.Serialization;
+using System.Diagnostics;
+using System.ComponentModel;
+
+namespace Crow
+{
+       //treeview expect expandable child (or not)
+       //if their are expandable, some functions and events are added
+       public class TreeView : TemplatedGroup
+       {
+               GraphicObject selectedItemContainer = null;
+               bool isRoot;
+
+               #region CTOR
+               public TreeView () : base()
+               {
+               }
+               #endregion
+
+               [XmlAttributeAttribute()][DefaultValue(false)]
+               public virtual bool IsRoot {
+                       get { return isRoot; }
+                       set {
+                               if (isRoot == value)
+                                       return;
+                               isRoot = value;
+                               NotifyValueChanged ("IsRoot", isRoot);
+                       }
+               }
+               [XmlIgnore]public override object SelectedItem {
+                       get {
+                               return selectedItemContainer == null ?
+                                       "" : selectedItemContainer.DataSource;
+                       }
+               }
+
+               protected override void registerItemClick (GraphicObject g)
+               {
+                       //register ItemClick on the Root node
+                       TreeView tv = this as TreeView;
+                       while (!tv.IsRoot) {
+                               ILayoutable tmp = tv.Parent;
+                               while (!(tmp is TreeView)) {
+                                       tmp = tmp.Parent;
+                               }
+                               tv = tmp as TreeView;
+                       }
+                       g.MouseClick += tv.itemClick;
+               }
+               internal override void itemClick (object sender, MouseButtonEventArgs e)
+               {
+                       GraphicObject tmp = sender as GraphicObject;
+                       if (!tmp.HasFocus)
+                               return;
+                       if (selectedItemContainer != null) {
+                               selectedItemContainer.Foreground = Color.Transparent;
+                               selectedItemContainer.Background = Color.Transparent;
+                       }
+                       selectedItemContainer = tmp;
+                       selectedItemContainer.Foreground = SelectionForeground;
+                       selectedItemContainer.Background = SelectionBackground;
+                       NotifyValueChanged ("SelectedItem", SelectedItem);
+                       raiseSelectedItemChanged ();
+               }
+
+               void onExpandAll_MouseClick (object sender, MouseButtonEventArgs e)
+               {
+                       ExpandAll ();
+               }
+
+               public void ExpandAll(){
+                       foreach (Group grp in items.Children) {
+                               foreach (GraphicObject go in grp.Children) {
+                                       Expandable exp = go as Expandable;
+                                       if (exp == null)
+                                               continue;
+                                       TreeView subTV = exp.FindByName ("List") as TreeView;
+                                       if (subTV == null)
+                                               continue;
+                                       EventHandler handler = null;
+                                       handler = delegate(object sender, EventArgs e) {
+                                               TreeView tv = sender as TreeView;
+                                               tv.Loaded -= handler;
+                                               tv.ExpandAll ();
+                                       };
+                                       subTV.Loaded += handler;
+                                       exp.IsExpanded = true;
+                               }
+                       }
+               }
+       }
+}
+
diff --git a/src/GraphicObjects/Base/VerticalStack.cs b/src/GraphicObjects/Base/VerticalStack.cs
new file mode 100644 (file)
index 0000000..d5d0236
--- /dev/null
@@ -0,0 +1,49 @@
+//
+// VerticalStack.cs
+//
+// Author:
+//       Jean-Philippe Bruyère <jp.bruyere@hotmail.com>
+//
+// Copyright (c) 2013-2017 Jean-Philippe Bruyère
+//
+// 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.Generic;
+using System.Linq;
+using System.Text;
+
+namespace Crow
+{
+    public class VerticalStack : GenericStack
+    {
+        public VerticalStack()
+            : base()
+        {
+        }
+
+        [System.Xml.Serialization.XmlIgnore]
+        public override Orientation Orientation
+        {
+            get { return Orientation.Vertical; }            
+        }
+
+
+    }
+}
diff --git a/src/GraphicObjects/Base/Window.cs b/src/GraphicObjects/Base/Window.cs
new file mode 100644 (file)
index 0000000..e282052
--- /dev/null
@@ -0,0 +1,399 @@
+//
+// Window.cs
+//
+// Author:
+//       Jean-Philippe Bruyère <jp.bruyere@hotmail.com>
+//
+// Copyright (c) 2013-2017 Jean-Philippe Bruyère
+//
+// 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.Xml.Serialization;
+using System.ComponentModel;
+using System.Diagnostics;
+
+namespace Crow
+{
+       public class Window : TemplatedContainer
+       {
+               enum Direction
+               {
+                       None,
+                       N,
+                       S,
+                       E,
+                       W,
+                       NW,
+                       NE,
+                       SW,
+                       SE,
+               }
+
+               string _icon;
+               bool _resizable;
+               bool _movable;
+               bool hoverBorder = false;
+               bool alwaysOnTop = false;
+
+               Rectangle savedBounds;
+               bool _minimized = false;
+
+               Container _contentContainer;
+               Direction currentDirection = Direction.None;
+
+               #region Events
+               public event EventHandler Closing;
+               public event EventHandler Maximized;
+               public event EventHandler Unmaximized;
+               public event EventHandler Minimize;
+               #endregion
+
+               #region CTOR
+               public Window () : base() {
+                       
+               }
+               #endregion
+
+               #region TemplatedContainer overrides
+               public override GraphicObject Content {
+                       get { return _contentContainer == null ? null : _contentContainer.Child; }
+                       set { _contentContainer.SetChild(value); }
+               }
+               protected override void loadTemplate(GraphicObject template = null)
+               {
+                       base.loadTemplate (template);
+                       _contentContainer = this.child.FindByName ("Content") as Container;
+
+                       NotifyValueChanged ("ShowNormal", false);
+                       NotifyValueChanged ("ShowMinimize", true);
+                       NotifyValueChanged ("ShowMaximize", true);
+               }
+               #endregion
+
+               #region public properties
+               [XmlAttributeAttribute][DefaultValue("#Crow.Images.Icons.crow.png")]
+               public string Icon {
+                       get { return _icon; } 
+                       set {
+                               if (_icon == value)
+                                       return;
+                               _icon = value;
+                               NotifyValueChanged ("Icon", _icon);
+                       }
+               } 
+               [XmlAttributeAttribute][DefaultValue(true)]
+               public bool Resizable {
+                       get {
+                               return _resizable;
+                       }
+                       set {
+                               if (_resizable == value)
+                                       return;
+                               _resizable = value;
+                               NotifyValueChanged ("Resizable", _resizable);
+                       }
+               }
+               [XmlAttributeAttribute][DefaultValue(true)]
+               public bool Movable {
+                       get {
+                               return _movable;
+                       }
+                       set {
+                               if (_movable == value)
+                                       return;
+                               _movable = value;
+                               NotifyValueChanged ("Movable", _movable);
+                       }
+               }
+               [XmlAttributeAttribute][DefaultValue(false)]
+               public bool IsMinimized {
+                       get { return _minimized; }
+                       set{
+                               if (value == IsMinimized)
+                                       return;
+
+                               _minimized = value;
+                               _contentContainer.Visible = !_minimized;
+
+                               NotifyValueChanged ("IsMinimized", _minimized);
+                       }
+               }
+               [XmlIgnore]public bool IsMaximized {
+                       get { return Width == Measure.Stretched & Height == Measure.Stretched & !_minimized; }
+               }
+               [XmlIgnore]public bool IsNormal {
+                       get { return !(IsMaximized|_minimized); }
+               }
+               [XmlAttributeAttribute][DefaultValue(false)]
+               public bool AlwaysOnTop {
+                       get {
+                               return alwaysOnTop;
+                       }
+                       set {
+                               if (alwaysOnTop == value)
+                                       return;
+                               alwaysOnTop = value;
+                               if (alwaysOnTop) {
+                                       CurrentInterface.PutOnTop (this);
+                                       CurrentInterface.TopWindows++;
+                               }else
+                                       CurrentInterface.TopWindows--;
+                               NotifyValueChanged ("AlwaysOnTop", alwaysOnTop);
+                       }
+               }
+//             [XmlAttributeAttribute()][DefaultValue(WindowState.Normal)]
+//             public virtual WindowState State {
+//                     get { return _state; }
+//                     set {
+//                             if (_state == value)
+//                                     return;
+//                             _state = value;
+//                             NotifyValueChanged ("State", _state);
+//                             NotifyValueChanged ("IsNormal", IsNormal);
+//                             NotifyValueChanged ("IsMaximized", IsMaximized);
+//                             NotifyValueChanged ("IsMinimized", IsMinimized);
+//                             NotifyValueChanged ("IsNotMinimized", IsNotMinimized);
+//                     }
+//             } 
+               #endregion
+
+               #region GraphicObject Overrides
+               public override void onMouseMove (object sender, MouseMoveEventArgs e)
+               {
+                       base.onMouseMove (sender, e);
+
+                       Interface otkgw = CurrentInterface;
+
+                       if (!hoverBorder) {
+                               currentDirection = Direction.None;
+                               CurrentInterface.MouseCursor = XCursor.Default;
+                               return;
+                       }
+
+                       if (this.HasFocus && _movable) {
+                               if (e.Mouse.IsButtonDown (MouseButton.Left)) {
+                                       int currentLeft = this.Left;
+                                       int currentTop = this.Top;
+                                       int currentWidth, currentHeight;
+
+                                       if (currentLeft == 0) {
+                                               currentLeft = this.Slot.Left;
+                                               this.Left = currentLeft;
+                                       }
+                                       if (currentTop == 0) {
+                                               currentTop = this.Slot.Top;
+                                               this.Top = currentTop;
+                                       }
+                                       if (this.Width.IsFixed)
+                                               currentWidth = this.Width;
+                                       else
+                                               currentWidth = this.Slot.Width;
+                               
+                                       if (this.Height.IsFixed)
+                                               currentHeight = this.Height;
+                                       else
+                                               currentHeight = this.Slot.Height;
+
+                                       switch (currentDirection) {
+                                       case Direction.None:
+                                               this.Left = currentLeft + e.XDelta;                             
+                                               this.Top = currentTop + e.YDelta;
+                                               break;
+                                       case Direction.N:
+                                               this.Height = currentHeight - e.YDelta;
+                                               if (this.Height == currentHeight - e.YDelta)
+                                                       this.Top = currentTop + e.YDelta;
+                                               break;
+                                       case Direction.S:
+                                               this.Height = currentHeight + e.YDelta;
+                                               break;
+                                       case Direction.W:
+                                               this.Width = currentWidth - e.XDelta;
+                                               if (this.Width == currentWidth - e.XDelta)
+                                                       this.Left = currentLeft + e.XDelta;
+                                               break;
+                                       case Direction.E:
+                                               this.Width = currentWidth + e.XDelta;
+                                               break;
+                                       case Direction.NW:
+                                               this.Height = currentHeight - e.YDelta;
+                                               if (this.Height == currentHeight - e.YDelta)
+                                                       this.Top = currentTop + e.YDelta;
+                                               this.Width = currentWidth - e.XDelta;
+                                               if (this.Width == currentWidth - e.XDelta)
+                                                       this.Left = currentLeft + e.XDelta;
+                                               break;
+                                       case Direction.NE:
+                                               this.Height = currentHeight - e.YDelta;
+                                               if (this.Height == currentHeight - e.YDelta)
+                                                       this.Top = currentTop + e.YDelta;
+                                               this.Width = currentWidth + e.XDelta;
+                                               break;
+                                       case Direction.SW:
+                                               this.Width = currentWidth - e.XDelta;
+                                               if (this.Width == currentWidth - e.XDelta)
+                                                       this.Left = currentLeft + e.XDelta;
+                                               this.Height = currentHeight + e.YDelta;
+                                               break;
+                                       case Direction.SE:
+                                               this.Height = currentHeight + e.YDelta;
+                                               this.Width = currentWidth + e.XDelta;
+                                               break;
+                                       }
+                                       return;
+                               }
+                       }
+                       if (Resizable) {
+                               Direction lastDir = currentDirection;
+
+                               if (Math.Abs (e.Position.Y - this.Slot.Y) < Interface.BorderThreshold) {
+                                       if (Math.Abs (e.Position.X - this.Slot.X) < Interface.BorderThreshold)
+                                               currentDirection = Direction.NW;
+                                       else if (Math.Abs (e.Position.X - this.Slot.Right) < Interface.BorderThreshold)
+                                               currentDirection = Direction.NE;
+                                       else
+                                               currentDirection = Direction.N;
+                               } else if (Math.Abs (e.Position.Y - this.Slot.Bottom) < Interface.BorderThreshold) {
+                                       if (Math.Abs (e.Position.X - this.Slot.X) < Interface.BorderThreshold)
+                                               currentDirection = Direction.SW;
+                                       else if (Math.Abs (e.Position.X - this.Slot.Right) < Interface.BorderThreshold)
+                                               currentDirection = Direction.SE;
+                                       else
+                                               currentDirection = Direction.S;
+                               } else if (Math.Abs (e.Position.X - this.Slot.X) < Interface.BorderThreshold)
+                                       currentDirection = Direction.W;
+                               else if (Math.Abs (e.Position.X - this.Slot.Right) < Interface.BorderThreshold)
+                                       currentDirection = Direction.E;
+                               else
+                                       currentDirection = Direction.None;
+
+                               if (currentDirection != lastDir) {
+                                       switch (currentDirection) {
+                                       case Direction.None:
+                                               otkgw.MouseCursor = XCursor.Default;
+                                               break;
+                                       case Direction.N:
+                                               otkgw.MouseCursor = XCursor.V;
+                                               break;
+                                       case Direction.S:
+                                               otkgw.MouseCursor = XCursor.V;
+                                               break;
+                                       case Direction.E:
+                                               otkgw.MouseCursor = XCursor.H;
+                                               break;
+                                       case Direction.W:
+                                               otkgw.MouseCursor = XCursor.H;
+                                               break;
+                                       case Direction.NW:
+                                               otkgw.MouseCursor = XCursor.NW;
+                                               break;
+                                       case Direction.NE:
+                                               otkgw.MouseCursor = XCursor.NE;
+                                               break;
+                                       case Direction.SW:
+                                               otkgw.MouseCursor = XCursor.SW;
+                                               break;
+                                       case Direction.SE:
+                                               otkgw.MouseCursor = XCursor.SE;
+                                               break;
+                                       }
+                               }                               
+                       }                               
+               }
+               public override void onMouseDown (object sender, MouseButtonEventArgs e)
+               {
+                       base.onMouseDown (sender, e);
+               }
+               #endregion
+
+               protected void onMaximized (object sender, EventArgs e){
+                       lock (CurrentInterface.LayoutMutex) {
+                               if (!IsMinimized)
+                                       savedBounds = this.LastPaintedSlot;
+                               this.Left = this.Top = 0;
+                               this.RegisterForLayouting (LayoutingType.Positioning);
+                               this.Width = this.Height = Measure.Stretched;
+                               IsMinimized = false;
+                               Resizable = false;
+                               NotifyValueChanged ("ShowNormal", true);
+                               NotifyValueChanged ("ShowMinimize", true);
+                               NotifyValueChanged ("ShowMaximize", false);
+                       }
+
+                       Maximized.Raise (sender, e);
+
+
+
+               }
+               protected void onUnmaximized (object sender, EventArgs e){
+                       lock (CurrentInterface.LayoutMutex) {
+                               this.Left = savedBounds.Left;
+                               this.Top = savedBounds.Top;
+                               this.Width = savedBounds.Width;
+                               this.Height = savedBounds.Height;
+                               IsMinimized = false;
+                               Resizable = true;
+                               NotifyValueChanged ("ShowNormal", false);
+                               NotifyValueChanged ("ShowMinimize", true);
+                               NotifyValueChanged ("ShowMaximize", true);
+                       }
+
+                       Unmaximized.Raise (sender, e);
+               }
+               protected void onMinimized (object sender, EventArgs e){
+                       lock (CurrentInterface.LayoutMutex) {
+                               if (IsNormal)
+                                       savedBounds = this.LastPaintedSlot;
+                               Width = 200;
+                               Height = 20;
+                               Resizable = false;
+                               IsMinimized = true;
+                               NotifyValueChanged ("ShowNormal", true);
+                               NotifyValueChanged ("ShowMinimize", false);
+                               NotifyValueChanged ("ShowMaximize", true);
+                       }
+
+                       Minimize.Raise (sender, e);
+               }
+               protected void onBorderMouseLeave (object sender, MouseMoveEventArgs e)
+               {
+                       hoverBorder = false;
+                       currentDirection = Direction.None;
+                       CurrentInterface.MouseCursor = XCursor.Default;
+               }
+               protected void onBorderMouseEnter (object sender, MouseMoveEventArgs e)
+               {
+                       hoverBorder = true;
+               }
+
+
+               protected void butQuitPress (object sender, MouseButtonEventArgs e)
+               {
+                       CurrentInterface.MouseCursor = XCursor.Default;
+                       close ();
+               }
+
+               protected void close(){
+                       Closing.Raise (this, null);
+                       CurrentInterface.DeleteWidget (this);
+               }
+       }
+}
+
diff --git a/src/GraphicObjects/Base/Wrapper.cs b/src/GraphicObjects/Base/Wrapper.cs
new file mode 100644 (file)
index 0000000..8b282eb
--- /dev/null
@@ -0,0 +1,233 @@
+//
+// Wrapper.cs
+//
+// Author:
+//       Jean-Philippe Bruyère <jp.bruyere@hotmail.com>
+//
+// Copyright (c) 2013-2017 Jean-Philippe Bruyère
+//
+// 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 Crow
+{
+       public class Wrapper : GenericStack
+       {
+               public Wrapper () : base()
+               {}
+
+               #region Group Overrides
+               public override void ChildrenLayoutingConstraints (ref LayoutingType layoutType)
+               {
+                       layoutType &= (~LayoutingType.Positioning);
+               }
+               public override void ComputeChildrenPositions()
+               {
+                       int dx = 0;
+                       int dy = 0;
+
+                       if (Orientation == Orientation.Vertical) {
+                               int tallestChild = 0;
+                               foreach (GraphicObject c in Children) {
+                                       if (!c.Visible)
+                                               continue;
+                                       if (dx + c.Slot.Width > ClientRectangle.Width) {
+                                               dx = 0;
+                                               dy += tallestChild + Spacing;
+                                               c.Slot.X = dx;
+                                               c.Slot.Y = dy;
+                                               tallestChild = c.Slot.Height;
+                                       } else {
+                                               if (tallestChild < c.Slot.Height)
+                                                       tallestChild = c.Slot.Height;
+                                               c.Slot.X = dx;
+                                               c.Slot.Y = dy;
+                                       }
+                                       dx += c.Slot.Width + Spacing;
+                               }
+                       } else {
+                               int largestChild = 0;
+                               foreach (GraphicObject c in Children) {
+                                       if (!c.Visible)
+                                               continue;
+                                       if (dy + c.Slot.Height > ClientRectangle.Height) {
+                                               dy = 0;
+                                               dx += largestChild + Spacing;
+                                               c.Slot.X = dx;
+                                               c.Slot.Y = dy;
+                                               largestChild = c.Slot.Width;
+                                       } else {
+                                               if (largestChild < c.Slot.Width)
+                                                       largestChild = c.Slot.Width;
+                                               c.Slot.X = dx;
+                                               c.Slot.Y = dy;
+                                       }
+                                       dy += c.Slot.Height + Spacing;
+                               }
+                       }
+                       IsDirty = true;
+               }
+               public override void OnChildLayoutChanges (object sender, LayoutingEventArgs arg)
+               {
+                       //children can't stretch in a wrapper
+                       GraphicObject go = sender as GraphicObject;
+                       //System.Diagnostics.Debug.WriteLine ("wrapper child layout change: " + go.LastSlots.ToString() + " => " + go.Slot.ToString());
+                       switch (arg.LayoutType) {
+                       case LayoutingType.Width:
+                               if (Orientation == Orientation.Horizontal && go.Width.Units == Unit.Percent){
+                                       go.Width = Measure.Fit;
+                                       return;
+                               }
+                               this.RegisterForLayouting (LayoutingType.Width);
+                               break;
+                       case LayoutingType.Height:
+                               if (Orientation == Orientation.Vertical && go.Height.Units == Unit.Percent) {
+                                       go.Height = Measure.Fit;
+                                       return;
+                               }
+                               this.RegisterForLayouting (LayoutingType.Height);
+                               break;
+                       default:
+                               return;
+                       }
+                       this.RegisterForLayouting (LayoutingType.ArrangeChildren);
+               }
+               #endregion
+
+               #region GraphicObject Overrides
+               protected override int measureRawSize (LayoutingType lt)
+               {
+                       int tmp = 0;
+                       //Wrapper can't fit in the opposite direction of the wrapper, this func is called only if Fit
+                       if (lt == LayoutingType.Width) {
+                               if (Orientation == Orientation.Vertical) {
+                                       Width = Measure.Stretched;
+                                       return -1;
+                               } else if (RegisteredLayoutings.HasFlag (LayoutingType.Height))
+                                       return -1;
+                               else {
+                                       int dy = 0;
+                                       int largestChild = 0;
+                                       lock (Children) {
+                                               foreach (GraphicObject c in Children) {
+                                                       if (!c.Visible)
+                                                               continue;
+                                                       if (c.Height.Units == Unit.Percent &&
+                                                               c.RegisteredLayoutings.HasFlag (LayoutingType.Height))
+                                                               return -1;
+                                                       if (dy + c.Slot.Height > ClientRectangle.Height) {
+                                                               dy = 0;
+                                                               tmp += largestChild + Spacing;
+                                                               largestChild = c.Slot.Width;
+                                                       } else if (largestChild < c.Slot.Width)
+                                                               largestChild = c.Slot.Width;
+
+                                                       dy += c.Slot.Height + Spacing;
+                                               }
+                                               if (dy == 0)
+                                                       tmp -= Spacing;
+                                               return tmp + largestChild + 2 * Margin;
+                                       }
+                               }
+                       } else if (Orientation == Orientation.Horizontal) {
+                               Height = Measure.Stretched;
+                               return -1;
+                       } else if (RegisteredLayoutings.HasFlag (LayoutingType.Width))
+                               return -1;
+                       else {
+                               int dx = 0;
+                               int tallestChild = 0;
+                               lock (Children) {
+                                       foreach (GraphicObject c in Children) {
+                                               if (!c.Visible)
+                                                       continue;
+                                               if (c.Width.Units == Unit.Percent &&
+                                                       c.RegisteredLayoutings.HasFlag (LayoutingType.Width))
+                                                       return -1;
+                                               if (dx + c.Slot.Width > ClientRectangle.Width) {
+                                                       dx = 0;
+                                                       tmp += tallestChild + Spacing;
+                                                       tallestChild = c.Slot.Height;
+                                               } else if (tallestChild < c.Slot.Height)
+                                                       tallestChild = c.Slot.Height;
+
+                                               dx += c.Slot.Width + Spacing;
+                                       }
+                                       if (dx == 0)
+                                               tmp -= Spacing;
+                                       return tmp + tallestChild + 2 * Margin;
+                               }
+                       }
+               }
+
+               public override bool UpdateLayout (LayoutingType layoutType)
+               {
+                       RegisteredLayoutings &= (~layoutType);
+
+                       if (layoutType == LayoutingType.ArrangeChildren) {
+                               if ((RegisteredLayoutings & LayoutingType.Sizing) != 0)
+                                       return false;
+
+                               ComputeChildrenPositions ();
+
+                               //if no layouting remains in queue for item, registre for redraw
+                               if (RegisteredLayoutings == LayoutingType.None && IsDirty)
+                                       CurrentInterface.EnqueueForRepaint (this);
+
+                               return true;
+                       }
+
+                       return base.UpdateLayout(layoutType);
+               }
+               public override void OnLayoutChanges (LayoutingType layoutType)
+               {
+                       #if DEBUG_LAYOUTING
+                       CurrentInterface.currentLQI.Slot = LastSlots;
+                       CurrentInterface.currentLQI.Slot = Slot;
+                       #endif
+                       switch (layoutType) {
+                       case LayoutingType.Width:
+                               foreach (GraphicObject c in Children) {
+                                       if (c.Width.Units == Unit.Percent)
+                                               c.RegisterForLayouting (LayoutingType.Width);
+                               }
+                               if (Height == Measure.Fit)
+                                       RegisterForLayouting (LayoutingType.Height);
+                               RegisterForLayouting (LayoutingType.X);
+                               break;
+                       case LayoutingType.Height:
+                               foreach (GraphicObject c in Children) {
+                                       if (c.Height.Units == Unit.Percent)
+                                               c.RegisterForLayouting (LayoutingType.Height);
+                               }
+                               if (Width == Measure.Fit)
+                                       RegisterForLayouting (LayoutingType.Width);
+                               RegisterForLayouting (LayoutingType.Y);
+                               break;
+                       default:
+                               return;
+                       }
+                       RegisterForLayouting (LayoutingType.ArrangeChildren);
+                       raiseLayoutChanged (new LayoutingEventArgs (layoutType));
+               }
+               #endregion
+       }
+}
+
diff --git a/src/GraphicObjects/Border.cs b/src/GraphicObjects/Border.cs
deleted file mode 100644 (file)
index 672d5ab..0000000
+++ /dev/null
@@ -1,100 +0,0 @@
-//
-// Border.cs
-//
-// Author:
-//       Jean-Philippe Bruyère <jp.bruyere@hotmail.com>
-//
-// Copyright (c) 2013-2017 Jean-Philippe Bruyère
-//
-// 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.Xml.Serialization;
-using System.ComponentModel;
-using System.Diagnostics;
-
-namespace Crow
-{
-       public class Border : Container
-       {
-               #region CTOR
-               public Border () : base(){}
-               #endregion
-
-               #region private fields
-               int _borderWidth;
-               #endregion
-
-               #region public properties
-               [XmlAttributeAttribute()][DefaultValue(1)]
-               public virtual int BorderWidth {
-                       get { return _borderWidth; }
-                       set {
-                               _borderWidth = value;
-                               RegisterForGraphicUpdate ();
-                       }
-               }
-               #endregion
-
-               #region GraphicObject override
-               [XmlIgnore]public override Rectangle ClientRectangle {
-                       get {
-                               Rectangle cb = base.ClientRectangle;
-                               cb.Inflate (- BorderWidth);
-                               return cb;
-                       }
-               }
-
-               protected override int measureRawSize (LayoutingType lt)
-               {
-                       int tmp = base.measureRawSize (lt);
-                       return tmp < 0 ? tmp : tmp + 2 * BorderWidth;
-               }
-               protected override void onDraw (Cairo.Context gr)
-               {
-                       Rectangle rBack = new Rectangle (Slot.Size);
-
-                       //rBack.Inflate (-Margin);
-//                     if (BorderWidth > 0) 
-//                             rBack.Inflate (-BorderWidth / 2);                       
-
-                       Background.SetAsSource (gr, rBack);
-                       CairoHelpers.CairoRectangle(gr, rBack, CornerRadius);
-                       gr.Fill ();
-
-                       if (BorderWidth > 0) {                          
-                               Foreground.SetAsSource (gr, rBack);
-                               CairoHelpers.CairoRectangle(gr, rBack, CornerRadius, BorderWidth);
-                       }
-
-                       gr.Save ();
-                       if (ClipToClientRect) {
-                               //clip to client zone
-                               CairoHelpers.CairoRectangle (gr, ClientRectangle,Math.Max(0.0, CornerRadius-Margin));
-                               gr.Clip ();
-                       }
-
-                       if (child != null)
-                               child.Paint (ref gr);
-                       gr.Restore ();
-               }               
-               #endregion
-       }
-}
-
diff --git a/src/GraphicObjects/Button.cs b/src/GraphicObjects/Button.cs
deleted file mode 100644 (file)
index 75f4301..0000000
+++ /dev/null
@@ -1,124 +0,0 @@
-//
-// Button.cs
-//
-// Author:
-//       Jean-Philippe Bruyère <jp.bruyere@hotmail.com>
-//
-// Copyright (c) 2013-2017 Jean-Philippe Bruyère
-//
-// 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.Generic;
-using System.Linq;
-using System.Text;
-//using OpenTK.Graphics.OpenGL;
-
-using System.Diagnostics;
-
-using System.Xml.Serialization;
-using Cairo;
-using System.ComponentModel;
-
-namespace Crow
-{
-    public class Button : TemplatedContainer
-    {
-               string image;
-               bool isPressed;
-               Container _contentContainer;
-
-               #region CTOR
-        public Button() : base()
-        {}
-               #endregion
-
-               public event EventHandler Pressed;
-               public event EventHandler Released;
-
-               #region TemplatedContainer overrides
-               public override GraphicObject Content {
-                       get {
-                               return _contentContainer == null ? null : _contentContainer.Child;
-                       }
-                       set {
-                               if (_contentContainer != null)
-                                       _contentContainer.SetChild(value);
-                       }
-               }
-               protected override void loadTemplate(GraphicObject template = null)
-               {
-                       base.loadTemplate (template);
-
-                       _contentContainer = this.child.FindByName ("Content") as Container;
-               }
-               #endregion
-
-               #region GraphicObject Overrides
-               public override void onMouseDown (object sender, MouseButtonEventArgs e)
-               {
-                       IsPressed = true;
-
-                       base.onMouseDown (sender, e);
-
-                       //TODO:remove
-                       NotifyValueChanged ("State", "pressed");
-               }
-               public override void onMouseUp (object sender, MouseButtonEventArgs e)
-               {
-                       IsPressed = false;
-
-                       base.onMouseUp (sender, e);
-
-                       //TODO:remove
-                       NotifyValueChanged ("State", "normal");
-               }
-               #endregion
-
-               [XmlAttributeAttribute][DefaultValue("#Crow.Images.button.svg")]
-               public string Image {
-                       get { return image; }
-                       set {
-                               if (image == value)
-                                       return;
-                               image = value;
-                               NotifyValueChanged ("Image", image);
-                       }
-               }
-               [XmlAttributeAttribute][DefaultValue(false)]
-               public bool IsPressed
-               {
-                       get { return isPressed; }
-                       set
-                       {
-                               if (isPressed == value)
-                                       return;
-
-                               isPressed = value;
-
-                               NotifyValueChanged ("IsPressed", isPressed);
-
-                               if (isPressed)
-                                       Pressed.Raise (this, null);
-                               else
-                                       Released.Raise (this, null);
-                       }
-               }
-       }
-}
diff --git a/src/GraphicObjects/CheckBox.cs b/src/GraphicObjects/CheckBox.cs
deleted file mode 100644 (file)
index 0a40d26..0000000
+++ /dev/null
@@ -1,71 +0,0 @@
-//
-// CheckBox.cs
-//
-// Author:
-//       Jean-Philippe Bruyère <jp.bruyere@hotmail.com>
-//
-// Copyright (c) 2013-2017 Jean-Philippe Bruyère
-//
-// 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.Xml.Serialization;
-
-namespace Crow
-{
-       public class CheckBox : TemplatedControl
-       {
-               bool isChecked;
-
-               #region CTOR
-               public CheckBox() : base()
-               {}
-               #endregion
-
-               public event EventHandler Checked;
-               public event EventHandler Unchecked;
-
-               [XmlAttributeAttribute()][DefaultValue(false)]
-               public bool IsChecked
-               {
-                       get { return isChecked; }
-                       set
-                       {
-                               if (isChecked == value)
-                                       return;
-
-                               isChecked = value;
-
-                               NotifyValueChanged ("IsChecked", value);
-
-                               if (isChecked)
-                                       Checked.Raise (this, null);
-                               else
-                                       Unchecked.Raise (this, null);
-                       }
-               }
-
-               public override void onMouseClick (object sender, MouseButtonEventArgs e)
-               {
-                       IsChecked = !IsChecked;
-                       base.onMouseClick (sender, e);
-               }
-       }
-}
diff --git a/src/GraphicObjects/ComboBox.cs b/src/GraphicObjects/ComboBox.cs
deleted file mode 100644 (file)
index 15b49db..0000000
+++ /dev/null
@@ -1,55 +0,0 @@
-//
-// ComboBox.cs
-//
-// Author:
-//       Jean-Philippe Bruyère <jp.bruyere@hotmail.com>
-//
-// Copyright (c) 2013-2017 Jean-Philippe Bruyère
-//
-// 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.Xml.Serialization;
-
-namespace Crow
-{
-       public class ComboBox : ListBox
-    {          
-               #region CTOR
-               public ComboBox() : base(){     }       
-               #endregion
-
-               Size minimumPopupSize = "10,10";
-               [XmlIgnore]public Size MinimumPopupSize{
-                       get { return minimumPopupSize; }
-                       set {
-                               minimumPopupSize = value;
-                               NotifyValueChanged ("MinimumPopupSize", minimumPopupSize);
-                       }
-               }
-
-               public override void OnLayoutChanges (LayoutingType layoutType)
-               {
-                       base.OnLayoutChanges (layoutType);
-
-                       if (layoutType == LayoutingType.Width)
-                               MinimumPopupSize = new Size (this.Slot.Width, minimumPopupSize.Height);                 
-               }
-       }
-}
diff --git a/src/GraphicObjects/Container.cs b/src/GraphicObjects/Container.cs
deleted file mode 100644 (file)
index aac3594..0000000
+++ /dev/null
@@ -1,109 +0,0 @@
-//
-// Container.cs
-//
-// Author:
-//       Jean-Philippe Bruyère <jp.bruyere@hotmail.com>
-//
-// Copyright (c) 2013-2017 Jean-Philippe Bruyère
-//
-// 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.Xml.Serialization;
-using System.Reflection;
-using System.ComponentModel;
-using System.Linq;
-using System.Threading;
-
-namespace Crow
-{
-    public class Container : PrivateContainer, IXmlSerializable
-    {
-               #region CTOR
-               public Container()
-                       : base()
-               {
-               }
-               #endregion
-
-               [XmlIgnore]
-               public GraphicObject Child {
-                       get { return child; }
-                       set { child = value; }
-               }
-               public virtual void SetChild(GraphicObject _child)
-               {
-                       base.SetChild (_child);
-               }
-
-               #region IXmlSerializable
-
-        public override System.Xml.Schema.XmlSchema GetSchema()
-        {
-            return null;
-        }
-        public override void ReadXml(System.Xml.XmlReader reader)
-        {
-                       //only read attributes in GraphicObject IXmlReader implementation
-            base.ReadXml(reader);
-
-
-            using (System.Xml.XmlReader subTree = reader.ReadSubtree())
-            {
-                subTree.Read(); //skip current node
-                subTree.Read(); //read first child
-
-                if (!subTree.IsStartElement())
-                    return;
-
-                Type t = Type.GetType("Crow." + subTree.Name);
-                               if (t == null) {
-                                       Assembly a = Assembly.GetEntryAssembly ();
-                                       foreach (Type expT in a.GetExportedTypes ()) {
-                                               if (expT.Name == subTree.Name) {
-                                                       t = expT;
-                                                       break;
-                                               }
-                                       }
-                               }
-                               GraphicObject go = (GraphicObject)Activator.CreateInstance(t);
-
-                               (go as IXmlSerializable).ReadXml(subTree);
-
-                               SetChild(go);
-
-                subTree.Read();//closing tag
-            }
-        }
-        public override void WriteXml(System.Xml.XmlWriter writer)
-        {
-            base.WriteXml(writer);
-
-            if (Child == null)
-                return;
-
-            writer.WriteStartElement(Child.GetType().Name);
-            (Child as IXmlSerializable).WriteXml(writer);
-            writer.WriteEndElement();
-        }
-    
-               #endregion
-       }
-}
-
diff --git a/src/GraphicObjects/Expandable.cs b/src/GraphicObjects/Expandable.cs
deleted file mode 100644 (file)
index 1cb3645..0000000
+++ /dev/null
@@ -1,141 +0,0 @@
-//
-// Expandable.cs
-//
-// Author:
-//       Jean-Philippe Bruyère <jp.bruyere@hotmail.com>
-//
-// Copyright (c) 2013-2017 Jean-Philippe Bruyère
-//
-// 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.Xml.Serialization;
-
-namespace Crow
-{
-    public class Expandable : TemplatedContainer
-    {
-               #region CTOR
-               public Expandable() : base()
-               {
-               }
-               #endregion
-
-               #region Private fields
-               bool _isExpanded;
-               string image;
-               Container _contentContainer;
-               #endregion
-
-               #region Event Handlers
-               public event EventHandler Expand;
-               public event EventHandler Collapse;
-               #endregion
-
-               public BooleanTestOnInstance GetIsExpandable;
-
-               public void onClickForExpand (object sender, MouseButtonEventArgs e)
-               {
-                       IsExpanded = !IsExpanded;
-               }
-
-               public override GraphicObject Content {
-                       get {
-                               return _contentContainer == null ? null : _contentContainer.Child;
-                       }
-                       set {
-                               _contentContainer.SetChild(value);
-                               NotifyValueChanged ("HasContent", HasContent);
-                       }
-               }
-               //TODO: move loadTemplate and ResolveBinding in TemplatedContainer
-               protected override void loadTemplate(GraphicObject template = null)
-               {
-                       base.loadTemplate (template);
-
-                       _contentContainer = this.child.FindByName ("Content") as Container;
-               }
-
-               #region Public properties
-               [XmlAttributeAttribute][DefaultValue("#Crow.Images.Icons.expandable.svg")]
-               public string Image {
-                       get { return image; }
-                       set {
-                               if (image == value)
-                                       return;
-                               image = value;
-                               NotifyValueChanged ("Image", image);
-                       }
-               }
-               [XmlAttributeAttribute][DefaultValue(false)]
-        public bool IsExpanded
-        {
-                       get { return _isExpanded; }
-            set
-            {
-                               if (value == _isExpanded)
-                                       return;
-
-                               _isExpanded = value;
-
-                               bool isExp = IsExpandable;
-                               NotifyValueChanged ("IsExpandable", isExp);
-                               if (!(HasContent & isExp))
-                                       _isExpanded = false;
-
-                               NotifyValueChanged ("IsExpanded", _isExpanded);
-
-                               if (_isExpanded)
-                                       onExpand (this, null);
-                               else
-                                       onCollapse (this, null);
-            }
-        }
-               [XmlIgnore]public bool HasContent {
-                       get { return _contentContainer == null ? false : _contentContainer.Child != null; }
-               }
-               [XmlIgnore]public bool IsExpandable {
-                       get {
-                               try {
-                                       return GetIsExpandable == null ? true : GetIsExpandable (this);
-                               } catch (Exception ex) {
-                                       System.Diagnostics.Debug.WriteLine ("Not Expandable error: " + ex.ToString ());
-                                       return false;
-                               }
-                       }
-               }
-               #endregion
-
-               public virtual void onExpand(object sender, EventArgs e)
-               {
-                       if (_contentContainer != null)
-                               _contentContainer.Visible = true;
-
-                       Expand.Raise (this, e);
-               }
-               public virtual void onCollapse(object sender, EventArgs e)
-               {
-                       if (_contentContainer != null)
-                               _contentContainer.Visible = false;
-
-                       Collapse.Raise (this, e);
-               }
-       }
-}
diff --git a/src/GraphicObjects/GenericStack.cs b/src/GraphicObjects/GenericStack.cs
deleted file mode 100644 (file)
index cecdaff..0000000
+++ /dev/null
@@ -1,228 +0,0 @@
-//
-// GenericStack.cs
-//
-// Author:
-//       Jean-Philippe Bruyère <jp.bruyere@hotmail.com>
-//
-// Copyright (c) 2013-2017 Jean-Philippe Bruyère
-//
-// 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.ComponentModel;
-using System.Diagnostics;
-using System.Xml.Serialization;
-using System;
-
-namespace Crow
-{
-       public class GenericStack : Group
-    {
-               #region CTOR
-               public GenericStack()
-                       : base()
-               {            
-               }
-               #endregion
-
-               #region Private fields
-        int _spacing;
-        Orientation _orientation;
-               #endregion
-
-               #region Public Properties
-        [XmlAttributeAttribute()][DefaultValue(2)]
-        public int Spacing
-        {
-                       get { return _spacing; }
-            set { 
-                               if (_spacing == value)
-                                       return;
-                               _spacing = value; 
-                               NotifyValueChanged ("Spacing", Spacing);
-                               RegisterForLayouting (LayoutingType.Sizing|LayoutingType.ArrangeChildren);
-                       }
-        }
-        [XmlAttributeAttribute()][DefaultValue(Orientation.Horizontal)]
-        public virtual Orientation Orientation
-        {
-            get { return _orientation; }
-            set { _orientation = value; }
-        }
-               #endregion
-
-               #region GraphicObject Overrides
-               public override bool ArrangeChildren { get { return true; } }
-               public override void ChildrenLayoutingConstraints (ref LayoutingType layoutType)
-               {
-                       //Prevent child repositionning in the direction of stacking
-                       if (Orientation == Orientation.Horizontal)
-                               layoutType &= (~LayoutingType.X);
-                       else
-                               layoutType &= (~LayoutingType.Y);                       
-               }
-               protected override int measureRawSize (LayoutingType lt)
-               {
-                       int totSpace = 0;
-                       for (int i = 0; i < Children.Count; i++) {
-                               if (Children [i].Visible)
-                                       totSpace += Spacing;
-                       }
-                       if (totSpace > 0)
-                               totSpace -= Spacing;
-                       if (lt == LayoutingType.Width) {
-                               if (Orientation == Orientation.Horizontal)
-                                       return contentSize.Width + totSpace + 2 * Margin;
-                       }else if (Orientation == Orientation.Vertical)
-                               return contentSize.Height + totSpace + 2 * Margin;                                                      
-                       
-                       return base.measureRawSize (lt);
-               }
-               public virtual void ComputeChildrenPositions()
-               {
-                       int d = 0;
-                       if (Orientation == Orientation.Horizontal) {
-                               foreach (GraphicObject c in Children) {
-                                       if (!c.Visible)
-                                               continue;
-                                       c.Slot.X = d;
-                                       d += c.Slot.Width + Spacing;
-                               }
-                       } else {
-                               foreach (GraphicObject c in Children) {
-                                       if (!c.Visible)
-                                               continue;                                       
-                                       c.Slot.Y = d;
-                                       d += c.Slot.Height + Spacing;
-                               }
-                       }
-                       IsDirty = true;
-               }
-               GraphicObject stretchedGO = null;
-               public override bool UpdateLayout (LayoutingType layoutType)
-        {
-                       RegisteredLayoutings &= (~layoutType);
-
-                       if (layoutType == LayoutingType.ArrangeChildren) {
-                               //allow 1 child to have size to 0 if stack has fixed or streched size policy,
-                               //this child will occupy remaining space
-                               //if stack size policy is Fit, no child may have stretch enabled
-                               //in the direction of stacking.
-                               ComputeChildrenPositions ();
-
-                               //if no layouting remains in queue for item, registre for redraw
-                               if (RegisteredLayoutings == LayoutingType.None && IsDirty)
-                                       CurrentInterface.EnqueueForRepaint (this);
-
-                               return true;
-                       }
-
-                       return base.UpdateLayout(layoutType);
-        }
-
-               public override void OnChildLayoutChanges (object sender, LayoutingEventArgs arg)
-               {
-                       GraphicObject go = sender as GraphicObject;
-                       //Debug.WriteLine ("child layout change: " + go.LastSlots.ToString() + " => " + go.Slot.ToString());
-                       switch (arg.LayoutType) {
-                       case LayoutingType.Width:
-                               if (Orientation == Orientation.Horizontal) {
-                                       if (go.Width == Measure.Stretched) {
-                                               if (stretchedGO == null && Width != Measure.Fit)
-                                                       stretchedGO = go;
-                                               else if (stretchedGO != go) {
-                                                       go.Slot.Width = 0;
-                                                       go.Width = Measure.Fit;
-                                                       return;
-                                               }
-                                       } else
-                                               contentSize.Width += go.Slot.Width - go.LastSlots.Width;
-
-                                       if (stretchedGO != null) {
-                                               int newW = Math.Max (
-                                                                  this.ClientRectangle.Width - contentSize.Width - Spacing * (Children.Count - 1),
-                                                                  stretchedGO.MinimumSize.Width);
-                                               if (stretchedGO.MaximumSize.Width > 0)
-                                                       newW = Math.Min (newW, stretchedGO.MaximumSize.Width);
-                                               if (newW != stretchedGO.Slot.Width) {                                                   
-                                                       stretchedGO.Slot.Width = newW;
-                                                       stretchedGO.IsDirty = true;
-#if DEBUG_LAYOUTING
-                                       Debug.WriteLine ("\tAdjusting Width of " + stretchedGO.ToString());
-#endif
-                                                       stretchedGO.LayoutChanged -= OnChildLayoutChanges;
-                                                       stretchedGO.OnLayoutChanges (LayoutingType.Width);
-                                                       stretchedGO.LayoutChanged += OnChildLayoutChanges;
-                                                       stretchedGO.LastSlots.Width = stretchedGO.Slot.Width;
-                                               }
-                                       }
-                                       
-                                       if (Width == Measure.Fit)
-                                               this.RegisterForLayouting (LayoutingType.Width);
-                                       
-                                       this.RegisterForLayouting (LayoutingType.ArrangeChildren);
-                                       return;
-                               }
-                               break;
-                       case LayoutingType.Height:
-                               if (Orientation == Orientation.Vertical) {
-                                       if (go.Height == Measure.Stretched) {
-                                               if (stretchedGO == null && Height != Measure.Fit)
-                                                       stretchedGO = go;
-                                               else if (stretchedGO != go){
-                                                       go.Slot.Height = 0;
-                                                       go.Height = Measure.Fit;
-                                                       return;
-                                               }
-                                       } else
-                                               contentSize.Height += go.Slot.Height - go.LastSlots.Height;
-                                       
-                                       if (stretchedGO != null) {
-                                               int newH = Math.Max (
-                                                       this.ClientRectangle.Height - contentSize.Height - Spacing * (Children.Count - 1),
-                                                       stretchedGO.MinimumSize.Height);
-                                               if (stretchedGO.MaximumSize.Height > 0)
-                                                       newH = Math.Min (newH, stretchedGO.MaximumSize.Height);
-                                               if (newH != stretchedGO.Slot.Height) {
-                                                       stretchedGO.Slot.Height = newH;
-                                                       stretchedGO.IsDirty = true;
-#if DEBUG_LAYOUTING
-                                       Debug.WriteLine ("\tAdjusting Height of " + stretchedGO.ToString());
-#endif
-                                                       stretchedGO.LayoutChanged -= OnChildLayoutChanges;
-                                                       stretchedGO.OnLayoutChanges (LayoutingType.Height);
-                                                       stretchedGO.LayoutChanged += OnChildLayoutChanges;
-                                                       stretchedGO.LastSlots.Height = stretchedGO.Slot.Height;
-                                               }
-                                       }
-
-                                       if (Height == Measure.Fit)
-                                               this.RegisterForLayouting (LayoutingType.Height);
-
-                                       this.RegisterForLayouting (LayoutingType.ArrangeChildren);
-                                       return;
-                               }
-                               break;
-                       }
-                       base.OnChildLayoutChanges (sender, arg);
-               }
-               #endregion
-
-    
-       }
-}
diff --git a/src/GraphicObjects/GraphicObject.cs b/src/GraphicObjects/GraphicObject.cs
deleted file mode 100644 (file)
index 2afbe33..0000000
+++ /dev/null
@@ -1,1555 +0,0 @@
-//
-// GraphicObject.cs
-//
-// Author:
-//       Jean-Philippe Bruyère <jp.bruyere@hotmail.com>
-//
-// Copyright (c) 2013-2017 Jean-Philippe Bruyère
-//
-// 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.Generic;
-using System.ComponentModel;
-using System.Xml.Serialization;
-using System.Reflection;
-using System.Reflection.Emit;
-using System.Runtime.CompilerServices;
-using Cairo;
-using System.Linq;
-using System.Diagnostics;
-using System.IO;
-
-namespace Crow
-{
-       public class GraphicObject : IXmlSerializable, ILayoutable, IValueChange, ICloneable
-       {
-               internal static ulong currentUid = 0;
-               internal ulong uid = 0;
-
-               Interface currentInterface = null;
-
-               [XmlIgnore]public Interface CurrentInterface {
-                       get {
-                               if (currentInterface == null) {
-                                       currentInterface = Interface.CurrentInterface;
-                                       Initialize ();
-                               }
-                               return currentInterface;
-                       }
-                       set {
-                               currentInterface = value;
-                       }
-               }
-
-               Rectangles clipping = new Rectangles();
-               public Rectangles Clipping { get { return clipping; }}
-
-               #region IValueChange implementation
-               public event EventHandler<ValueChangeEventArgs> ValueChanged;
-               public virtual void NotifyValueChanged(string MemberName, object _value)
-               {
-                       //Debug.WriteLine ("Value changed: {0}->{1} = {2}", this, MemberName, _value);
-                       ValueChanged.Raise(this, new ValueChangeEventArgs(MemberName, _value));
-               }
-               #endregion
-
-               #region CTOR
-               public GraphicObject ()
-               {
-                       #if DEBUG
-                       uid = currentUid;
-                       currentUid++;
-                       #endif
-               }
-               #endregion
-
-               /// <summary>
-               /// Initialize this Graphic object instance by setting style and default values and loading template if required
-               /// </summary>
-               public virtual void Initialize(){
-                       if (currentInterface == null)
-                               currentInterface = Interface.CurrentInterface;
-                       loadDefaultValues ();
-               }
-               #region private fields
-               LayoutingType registeredLayoutings = LayoutingType.All;
-               ILayoutable logicalParent;
-               ILayoutable parent;
-               string name;
-               Fill background = Color.Transparent;
-               Fill foreground = Color.White;
-               Font font = "droid, 10";
-               Measure width, height;
-               int left, top;
-               double cornerRadius = 0;
-               int margin = 0;
-               bool focusable = false;
-               bool hasFocus = false;
-               bool isActive = false;
-               bool mouseRepeat;
-               protected bool isVisible = true;
-               bool isEnabled = true;
-               VerticalAlignment verticalAlignment = VerticalAlignment.Center;
-               HorizontalAlignment horizontalAlignment = HorizontalAlignment.Center;
-               Size maximumSize = "0,0";
-               Size minimumSize = "0,0";
-               bool cacheEnabled = false;
-               bool clipToClientRect = true;
-               protected object dataSource;
-               string style;
-               object tag;
-               #endregion
-
-               #region public fields
-               /// <summary>
-               /// Current size and position computed during layouting pass
-               /// </summary>
-               public Rectangle Slot = new Rectangle ();
-               /// <summary>
-               /// keep last slot components for each layouting pass to track
-               /// changes and trigger update of other component accordingly
-               /// </summary>
-               public Rectangle LastSlots;
-               /// <summary>
-               /// keep last slot painted on screen to clear traces if moved or resized
-               /// TODO: we should ensure the whole parsed widget tree is the last painted
-               /// version to clear effective oldslot if parents have been moved or resized.
-               /// IDEA is to add a ScreenCoordinates function that use only lastPaintedSlots
-               /// </summary>
-               public Rectangle LastPaintedSlot;
-               /// <summary>Prevent requeuing multiple times the same widget</summary>
-               public bool IsQueueForRedraw = false;
-               /// <summary>drawing Cache, if null, a redraw is done, cached or not</summary>
-               public byte[] bmp;
-               public bool IsDirty = true;
-               /// <summary>
-               /// This size is computed on each child' layout changes.
-               /// In stacking widget, it is used to compute the remaining space for the stretched
-               /// widget inside the stack, which is never added to the contentSize, instead, its size
-               /// is deducted from (parent.ClientRectangle - contentSize)
-               /// </summary>
-               internal Size contentSize;
-               #endregion
-
-               #region ILayoutable
-               [XmlIgnore]public LayoutingType RegisteredLayoutings { get { return registeredLayoutings; } set { registeredLayoutings = value; } }
-               //TODO: it would save the recurent cost of a cast in event bubbling if parent type was GraphicObject
-               //              or we could add to the interface the mouse events
-               /// <summary>
-               /// Parent in the graphic tree, used for rendering and layouting
-               /// </summary>
-               [XmlIgnore]public virtual ILayoutable Parent {
-                       get { return parent; }
-                       set {
-                               if (parent == value)
-                                       return;
-                               DataSourceChangeEventArgs e = new DataSourceChangeEventArgs (parent, value);
-                               lock (this)
-                                       parent = value;
-
-                               onParentChanged (this, e);
-                       }
-               }
-               [XmlIgnore]public ILayoutable LogicalParent {
-                       get { return logicalParent == null ? Parent : logicalParent; }
-                       set {
-                               if (logicalParent == value)
-                                       return;
-                               if (logicalParent != null)
-                                       (logicalParent as GraphicObject).DataSourceChanged -= onLogicalParentDataSourceChanged;
-                               DataSourceChangeEventArgs dsce = new DataSourceChangeEventArgs (LogicalParent, null);
-                               logicalParent = value;
-                               dsce.NewDataSource = LogicalParent;
-                               if (logicalParent != null)
-                                       (logicalParent as GraphicObject).DataSourceChanged += onLogicalParentDataSourceChanged;
-                               onLogicalParentChanged (this, dsce);
-                       }
-               }
-               [XmlIgnore]public virtual Rectangle ClientRectangle {
-                       get {
-                               Rectangle cb = Slot.Size;
-                               cb.Inflate ( - Margin);
-                               return cb;
-                       }
-               }
-               public virtual Rectangle ContextCoordinates(Rectangle r){
-                       GraphicObject go = Parent as GraphicObject;
-                       if (go == null)
-                               return r + Parent.ClientRectangle.Position;
-                       return go.CacheEnabled ?
-                               r + Parent.ClientRectangle.Position :
-                               Parent.ContextCoordinates (r);
-               }
-               public virtual Rectangle ScreenCoordinates (Rectangle r){
-                       return
-                               Parent.ScreenCoordinates(r) + Parent.getSlot().Position + Parent.ClientRectangle.Position;
-               }
-               public virtual Rectangle getSlot () { return Slot;}
-               #endregion
-
-               #region EVENT HANDLERS
-               public event EventHandler<MouseWheelEventArgs> MouseWheelChanged;
-               public event EventHandler<MouseButtonEventArgs> MouseUp;
-               public event EventHandler<MouseButtonEventArgs> MouseDown;
-               public event EventHandler<MouseButtonEventArgs> MouseClick;
-               public event EventHandler<MouseButtonEventArgs> MouseDoubleClick;
-               public event EventHandler<MouseMoveEventArgs> MouseMove;
-               public event EventHandler<MouseMoveEventArgs> MouseEnter;
-               public event EventHandler<MouseMoveEventArgs> MouseLeave;
-               public event EventHandler<KeyboardKeyEventArgs> KeyDown;
-               public event EventHandler<KeyboardKeyEventArgs> KeyUp;
-               public event EventHandler<KeyPressEventArgs> KeyPress;
-               public event EventHandler Focused;
-               public event EventHandler Unfocused;
-               public event EventHandler Enabled;
-               public event EventHandler Disabled;
-               public event EventHandler<LayoutingEventArgs> LayoutChanged;
-               public event EventHandler<DataSourceChangeEventArgs> DataSourceChanged;
-               public event EventHandler<DataSourceChangeEventArgs> ParentChanged;
-               public event EventHandler<DataSourceChangeEventArgs> LogicalParentChanged;
-               #endregion
-
-               #region public properties
-               /// <summary>Random value placeholder</summary>
-               [XmlAttributeAttribute]
-               public object Tag {
-                       get { return tag; }
-                       set {
-                               if (tag == value)
-                                       return;
-                               tag = value;
-                               NotifyValueChanged ("Tag", tag);
-                       }
-               }
-               /// <summary>
-               /// If enabled, resulting bitmap of graphic object is cached in an byte array
-               /// speeding up rendering of complex object. Default is enabled.
-               /// </summary>
-               [XmlAttributeAttribute][DefaultValue(true)]
-               public virtual bool CacheEnabled {
-                       get { return cacheEnabled; }
-                       set {
-                               if (cacheEnabled == value)
-                                       return;
-                               cacheEnabled = value;
-                               NotifyValueChanged ("CacheEnabled", cacheEnabled);
-                       }
-               }
-               /// <summary>
-               /// If true, rendering of GraphicObject is clipped inside client rectangle
-               /// </summary>
-               [XmlAttributeAttribute][DefaultValue(true)]
-               public virtual bool ClipToClientRect {
-                       get { return clipToClientRect; }
-                       set {
-                               if (clipToClientRect == value)
-                                       return;
-                               clipToClientRect = value;
-                               NotifyValueChanged ("ClipToClientRect", clipToClientRect);
-                               this.RegisterForRedraw ();
-                       }
-               }
-               /// <summary>
-               /// Name is used in binding to reference other GraphicObjects inside the graphic tree
-               /// </summary>
-               [XmlAttributeAttribute][DefaultValue(null)]
-               public virtual string Name {
-                       get {
-                               #if DEBUG
-                               return string.IsNullOrEmpty(name) ? this.GetType().Name + uid.ToString () : name;
-                               #else
-                               return name;
-                               #endif
-                       }
-                       set {
-                               if (name == value)
-                                       return;
-                               name = value;
-                               NotifyValueChanged("Name", name);
-                       }
-               }
-               [XmlAttributeAttribute  ()][DefaultValue(VerticalAlignment.Center)]
-               public virtual VerticalAlignment VerticalAlignment {
-                       get { return verticalAlignment; }
-                       set {
-                               if (verticalAlignment == value)
-                                       return;
-
-                               verticalAlignment = value;
-                               NotifyValueChanged("VerticalAlignment", verticalAlignment);
-                               RegisterForLayouting (LayoutingType.Y);
-                       }
-               }
-               [XmlAttributeAttribute()][DefaultValue(HorizontalAlignment.Center)]
-               public virtual HorizontalAlignment HorizontalAlignment {
-                       get { return horizontalAlignment; }
-                       set {
-                               if (horizontalAlignment == value)
-                                       return;
-                               horizontalAlignment = value;
-                               NotifyValueChanged("HorizontalAlignment", horizontalAlignment);
-                               RegisterForLayouting (LayoutingType.X);
-                       }
-               }
-               [XmlAttributeAttribute()][DefaultValue(0)]
-               public virtual int Left {
-                       get { return left; }
-                       set {
-                               if (left == value)
-                                       return;
-                               left = value;
-                               NotifyValueChanged ("Left", left);
-                               this.RegisterForLayouting (LayoutingType.X);
-                       }
-               }
-               [XmlAttributeAttribute()][DefaultValue(0)]
-               public virtual int Top {
-                       get { return top; }
-                       set {
-                               if (top == value)
-                                       return;
-                               top = value;
-                               NotifyValueChanged ("Top", top);
-                               this.RegisterForLayouting (LayoutingType.Y);
-                       }
-               }
-               /// <summary>
-               /// When set to True, the <see cref="T:Crow.GraphicObject"/>'s width and height will be set to Fit.
-               /// </summary>
-               [XmlAttributeAttribute()][DefaultValue(false)]
-               public virtual bool Fit {
-                       get { return Width == Measure.Fit && Height == Measure.Fit ? true : false; }
-                       set {
-                               if (value == Fit)
-                                       return;
-
-                               Width = Height = Measure.Fit;
-                       }
-               }
-               [XmlAttributeAttribute()][DefaultValue("Inherit")]
-               public virtual Measure Width {
-                       get {
-                               return width.Units == Unit.Inherit ?
-                                       Parent is GraphicObject ? (Parent as GraphicObject).WidthPolicy :
-                                       Measure.Stretched : width;
-                       }
-                       set {
-                               if (width == value)
-                                       return;
-                               if (value.IsFixed) {
-                                       if (value < MinimumSize.Width || (value > MaximumSize.Width && MaximumSize.Width > 0))
-                                               return;
-                               }
-                               Measure lastWP = WidthPolicy;
-                               width = value;
-                               NotifyValueChanged ("Width", width);
-                               if (WidthPolicy != lastWP) {
-                                       NotifyValueChanged ("WidthPolicy", WidthPolicy);
-                                       //contentSize in Stacks are only update on childLayoutChange, and the single stretched
-                                       //child of the stack is not counted in contentSize, so when changing size policy of a child
-                                       //we should adapt contentSize
-                                       //TODO:check case when child become stretched, and another stretched item already exists.
-                                       if (parent is GenericStack) {//TODO:check if I should test Group instead
-                                               if ((parent as GenericStack).Orientation == Orientation.Horizontal) {
-                                                       if (lastWP == Measure.Fit)
-                                                               (parent as GenericStack).contentSize.Width -= this.LastSlots.Width;
-                                                       else
-                                                               (parent as GenericStack).contentSize.Width += this.LastSlots.Width;
-                                               }
-                                       }
-                               }
-
-                               this.RegisterForLayouting (LayoutingType.Width);
-                       }
-               }
-               [XmlAttributeAttribute()][DefaultValue("Inherit")]
-               public virtual Measure Height {
-                       get {
-                               return height.Units == Unit.Inherit ?
-                                       Parent is GraphicObject ? (Parent as GraphicObject).HeightPolicy :
-                                       Measure.Stretched : height;
-                       }
-                       set {
-                               if (height == value)
-                                       return;
-                               if (value.IsFixed) {
-                                       if (value < MinimumSize.Height || (value > MaximumSize.Height && MaximumSize.Height > 0))
-                                               return;
-                               }
-                               Measure lastHP = HeightPolicy;
-                               height = value;
-                               NotifyValueChanged ("Height", height);
-                               if (HeightPolicy != lastHP) {
-                                       NotifyValueChanged ("HeightPolicy", HeightPolicy);
-                                       if (parent is GenericStack) {
-                                               if ((parent as GenericStack).Orientation == Orientation.Vertical) {
-                                                       if (lastHP == Measure.Fit)
-                                                               (parent as GenericStack).contentSize.Height -= this.LastSlots.Height;
-                                                       else
-                                                               (parent as GenericStack).contentSize.Height += this.LastSlots.Height;
-                                               }
-                                       }
-                               }
-
-                               this.RegisterForLayouting (LayoutingType.Height);
-                       }
-               }
-               /// <summary>
-               /// Used for binding on dimensions, this property will never hold fixed size, but instead only
-               /// Fit or Stretched
-               /// </summary>
-               [XmlIgnore]public virtual Measure WidthPolicy { get {
-                               return Width.IsFit ? Measure.Fit : Measure.Stretched; } }
-               /// <summary>
-               /// Used for binding on dimensions, this property will never hold fixed size, but instead only
-               /// Fit or Stretched
-               /// </summary>
-               [XmlIgnore]public virtual Measure HeightPolicy { get {
-                               return Height.IsFit ? Measure.Fit : Measure.Stretched; } }
-               [XmlAttributeAttribute()][DefaultValue(false)]
-               public virtual bool Focusable {
-                       get { return focusable; }
-                       set {
-                               if (focusable == value)
-                                       return;
-                               focusable = value;
-                               NotifyValueChanged ("Focusable", focusable);
-                       }
-               }
-               [XmlIgnore]public virtual bool HasFocus {
-                       get { return hasFocus; }
-                       set {
-                               if (value == hasFocus)
-                                       return;
-
-                               hasFocus = value;
-                               if (hasFocus)
-                                       onFocused (this, null);
-                               else
-                                       onUnfocused (this, null);
-                               NotifyValueChanged ("HasFocus", hasFocus);
-                       }
-               }
-               [XmlIgnore]public virtual bool IsActive {
-                       get { return isActive; }
-                       set {
-                               if (value == isActive)
-                                       return;
-
-                               isActive = value;
-                               NotifyValueChanged ("IsActive", isActive);
-                       }
-               }
-               [XmlAttributeAttribute()][DefaultValue(false)]
-               public virtual bool MouseRepeat {
-                       get { return mouseRepeat; }
-                       set {
-                               if (mouseRepeat == value)
-                                       return;
-                               mouseRepeat = value;
-                               NotifyValueChanged ("MouseRepeat", mouseRepeat);
-                       }
-               }
-               bool clearBackground = false;
-               [XmlAttributeAttribute()][DefaultValue("Transparent")]
-               public virtual Fill Background {
-                       get { return background; }
-                       set {
-                               if (background == value)
-                                       return;
-                               clearBackground = false;
-                               if (value == null)
-                                       return;
-                               background = value;
-                               NotifyValueChanged ("Background", background);
-                               RegisterForRedraw ();
-                               if (background is SolidColor) {
-                                       if ((Background as SolidColor).Equals (Color.Clear))
-                                               clearBackground = true;
-                               }
-                       }
-               }
-               [XmlAttributeAttribute()][DefaultValue("White")]
-               public virtual Fill Foreground {
-                       get { return foreground; }
-                       set {
-                               if (foreground == value)
-                                       return;
-                               foreground = value;
-                               NotifyValueChanged ("Foreground", foreground);
-                               RegisterForRedraw ();
-                       }
-               }
-               [XmlAttributeAttribute()][DefaultValue("sans,10")]
-               public virtual Font Font {
-                       get { return font; }
-                       set {
-                               if (value == font)
-                                       return;
-                               font = value;
-                               NotifyValueChanged ("Font", font);
-                               RegisterForGraphicUpdate ();
-                       }
-               }
-               [XmlAttributeAttribute()][DefaultValue(0.0)]
-               public virtual double CornerRadius {
-                       get { return cornerRadius; }
-                       set {
-                               if (value == cornerRadius)
-                                       return;
-                               cornerRadius = value;
-                               NotifyValueChanged ("CornerRadius", cornerRadius);
-                               RegisterForRedraw ();
-                       }
-               }
-               [XmlAttributeAttribute()][DefaultValue(0)]
-               public virtual int Margin {
-                       get { return margin; }
-                       set {
-                               if (value == margin)
-                                       return;
-                               margin = value;
-                               NotifyValueChanged ("Margin", margin);
-                               RegisterForGraphicUpdate ();
-                       }
-               }
-               [XmlAttributeAttribute][DefaultValue(true)]
-               public virtual bool Visible {
-                       get { return isVisible; }
-                       set {
-                               if (value == isVisible)
-                                       return;
-
-                               isVisible = value;
-
-                               if (isVisible)
-                                       RegisterForLayouting (LayoutingType.Sizing);
-                               else {
-                                       lock (CurrentInterface.UpdateMutex) {
-                                               Slot.Width = 0;
-                                               LayoutChanged.Raise (this, new LayoutingEventArgs (LayoutingType.Width));
-                                               Slot.Height = 0;
-                                               LayoutChanged.Raise (this, new LayoutingEventArgs (LayoutingType.Height));
-                                               if (this.parent != null)
-                                                       CurrentInterface.EnqueueForRepaint (this);
-                                               LastSlots.Width = LastSlots.Height = 0;
-                                       }
-                               }
-
-                               //trigger a mouse to handle possible hover changes
-                               CurrentInterface.ProcessMouseMove (CurrentInterface.Mouse.X, CurrentInterface.Mouse.Y);
-
-                               NotifyValueChanged ("Visible", isVisible);
-                       }
-               }
-               [XmlAttributeAttribute][DefaultValue(true)]
-               public virtual bool IsEnabled {
-                       get { return isEnabled; }
-                       set {
-                               if (value == isEnabled)
-                                       return;
-
-                               isEnabled = value;
-
-                               if (isEnabled)
-                                       onEnable (this, null);
-                               else
-                                       onDisable (this, null);
-
-                               NotifyValueChanged ("IsEnabled", isEnabled);
-                               RegisterForRedraw ();
-                       }
-               }
-               [XmlAttributeAttribute()][DefaultValue("1,1")]
-               public virtual Size MinimumSize {
-                       get { return minimumSize; }
-                       set {
-                               if (value == minimumSize)
-                                       return;
-
-                               minimumSize = value;
-
-                               NotifyValueChanged ("MinimumSize", minimumSize);
-                               RegisterForLayouting (LayoutingType.Sizing);
-                       }
-               }
-               [XmlAttributeAttribute()][DefaultValue("0,0")]
-               public virtual Size MaximumSize {
-                       get { return maximumSize; }
-                       set {
-                               if (value == maximumSize)
-                                       return;
-
-                               maximumSize = value;
-
-                               NotifyValueChanged ("MaximumSize", maximumSize);
-                               RegisterForLayouting (LayoutingType.Sizing);
-                       }
-               }
-               /// <summary>
-               /// Seek first logical tree upward if logicalParent is set, or seek graphic tree for
-               /// a not null dataSource that will be active for all descendants having dataSource=null
-               /// </summary>
-               [XmlAttributeAttribute][DefaultValue(null)]
-               public virtual object DataSource {
-                       set {
-                               if (DataSource == value)
-                                       return;
-
-                               DataSourceChangeEventArgs dse = new DataSourceChangeEventArgs (DataSource, null);
-                               dataSource = value;
-                               dse.NewDataSource = DataSource;
-
-                               OnDataSourceChanged (this, dse);
-
-                               NotifyValueChanged ("DataSource", DataSource);
-                       }
-                       get {
-                               return dataSource == null ?
-                                       LogicalParent == null ? null :
-                                       LogicalParent is GraphicObject ? (LogicalParent as GraphicObject).DataSource : null :
-                                       dataSource;
-                       }
-               }
-               protected virtual void onLogicalParentDataSourceChanged(object sender, DataSourceChangeEventArgs e){
-                       if (localDataSourceIsNull)
-                               OnDataSourceChanged (this, e);
-               }
-               internal bool localDataSourceIsNull { get { return dataSource == null; } }
-               internal bool localLogicalParentIsNull { get { return logicalParent == null; } }
-
-               public virtual void OnDataSourceChanged(object sender, DataSourceChangeEventArgs e){
-                       DataSourceChanged.Raise (this, e);
-                       #if DEBUG_BINDING
-                       Debug.WriteLine("New DataSource for => {0} \n\t{1}=>{2}", this.ToString(),e.OldDataSource,e.NewDataSource);
-                       #endif
-               }
-
-               [XmlAttributeAttribute]
-               public virtual string Style {
-                       get { return style; }
-                       set {
-                               if (value == style)
-                                       return;
-
-                               style = value;
-
-                               NotifyValueChanged ("Style", style);
-                       }
-               }
-               #endregion
-
-               #region Default and Style Values loading
-               /// <summary> Loads the default values from XML attributes default </summary>
-               public void loadDefaultValues()
-               {
-                       #if DEBUG_LOAD
-                       Debug.WriteLine ("LoadDefValues for " + this.ToString ());
-                       #endif
-
-                       Type thisType = this.GetType ();
-
-                       if (!string.IsNullOrEmpty (Style)) {
-                               if (Interface.DefaultValuesLoader.ContainsKey (Style)) {
-                                       Interface.DefaultValuesLoader [Style] (this);
-                                       return;
-                               }
-                       } else {
-                               if (Interface.DefaultValuesLoader.ContainsKey (thisType.FullName)) {
-                                       Interface.DefaultValuesLoader [thisType.FullName] (this);
-                                       return;
-                               } else if (!Interface.Styling.ContainsKey (thisType.FullName)) {
-                                       if (Interface.DefaultValuesLoader.ContainsKey (thisType.Name)) {
-                                               Interface.DefaultValuesLoader [thisType.Name] (this);
-                                               return;
-                                       }
-                               }
-                       }
-
-                       List<Style> styling = new List<Style>();
-
-                       //Search for a style matching :
-                       //1: Full class name, with full namespace
-                       //2: class name
-                       //3: style may have been registered with their ressource ID minus .style extention
-                       //   those files being placed in a Styles folder
-                       string styleKey = Style;
-                       if (!string.IsNullOrEmpty (Style)) {
-                               if (Interface.Styling.ContainsKey (Style)) {
-                                       styling.Add (Interface.Styling [Style]);
-                               }
-                       }
-                       if (Interface.Styling.ContainsKey (thisType.FullName)) {
-                               styling.Add (Interface.Styling [thisType.FullName]);
-                               if (string.IsNullOrEmpty (styleKey))
-                                       styleKey = thisType.FullName;
-                       }
-                       if (Interface.Styling.ContainsKey (thisType.Name)) {
-                               styling.Add (Interface.Styling [thisType.Name]);
-                               if (string.IsNullOrEmpty (styleKey))
-                                       styleKey = thisType.Name;
-                       }
-
-                       if (string.IsNullOrEmpty (styleKey))
-                               styleKey = thisType.FullName;
-
-
-                       //Reflexion being very slow compared to dyn method or delegates,
-                       //I compile the initial values coded in the CustomAttribs of the class,
-                       //all other instance of this type would not longer use reflexion to init properly
-                       //but will fetch the  dynamic initialisation method compiled for this precise type
-                       //TODO:measure speed gain.
-                       #region Delfault values Loading dynamic compilation
-                       DynamicMethod dm = null;
-                       ILGenerator il = null;
-
-                       dm = new DynamicMethod("dyn_loadDefValues",
-                               MethodAttributes.Family | MethodAttributes.FamANDAssem | MethodAttributes.NewSlot,
-                               CallingConventions.Standard,
-                               typeof(void),new Type[] {CompilerServices.TObject},thisType,true);
-
-                       il = dm.GetILGenerator(256);
-                       il.DeclareLocal(CompilerServices.TObject);
-                       il.Emit(OpCodes.Nop);
-                       //set local GraphicObject to root object passed as 1st argument
-                       il.Emit (OpCodes.Ldarg_0);
-                       il.Emit (OpCodes.Stloc_0);
-
-                       foreach (EventInfo ei in thisType.GetEvents(BindingFlags.Public | BindingFlags.Instance)) {
-                               string expression;
-                               if (!getDefaultEvent(ei, styling, out expression))
-                                       continue;
-                               //TODO:dynEventHandler could be cached somewhere, maybe a style instanciator class holding the styling delegate and bound to it.
-                               foreach (string exp in CompilerServices.splitOnSemiColumnOutsideAccolades(expression)) {
-                                       string trimed = exp.Trim();
-                                       if (trimed.StartsWith ("{", StringComparison.OrdinalIgnoreCase)){
-                                               il.Emit (OpCodes.Ldloc_0);//load this as 1st arg of event Add
-
-                                               //push eventInfo as 1st arg of compile
-                                               il.Emit (OpCodes.Ldloc_0);
-                                               il.Emit (OpCodes.Call, CompilerServices.miGetType);
-                                               il.Emit (OpCodes.Ldstr, ei.Name);//push event name
-                                               il.Emit (OpCodes.Call, CompilerServices.miGetEvent);
-                                               //push expression as 2nd arg of compile
-                                               il.Emit (OpCodes.Ldstr, trimed.Substring (1, trimed.Length - 2));
-                                               //push null as 3rd arg, currentNode, not known when instanciing
-                                               il.Emit (OpCodes.Ldnull);
-                                               il.Emit (OpCodes.Callvirt, CompilerServices.miCompileDynEventHandler);
-                                               il.Emit (OpCodes.Castclass, ei.EventHandlerType);
-                                               il.Emit (OpCodes.Callvirt, ei.AddMethod);
-                                       }else
-                                               Debug.WriteLine("error in styling, event not handled : " + trimed);
-                               }
-                       }
-
-                       foreach (PropertyInfo pi in thisType.GetProperties(BindingFlags.Public | BindingFlags.Instance)) {
-                               if (pi.GetSetMethod () == null)
-                                       continue;
-                               object defaultValue;
-                               if (!getDefaultValue (pi, styling, out defaultValue))
-                                       continue;
-
-                               CompilerServices.EmitSetValue (il, pi, defaultValue);
-                       }
-                       il.Emit(OpCodes.Ret);
-                       #endregion
-
-                       try {
-                               Interface.DefaultValuesLoader[styleKey] = (Interface.LoaderInvoker)dm.CreateDelegate(typeof(Interface.LoaderInvoker));
-                               Interface.DefaultValuesLoader[styleKey] (this);
-                       } catch (Exception ex) {
-                               throw new Exception ("Error applying style <" + styleKey + ">:", ex);
-                       }
-               }
-               bool getDefaultEvent(EventInfo ei, List<Style> styling,
-                       out string expression){
-                       expression = "";
-                       if (styling.Count > 0){
-                               for (int i = 0; i < styling.Count; i++) {
-                                       if (styling[i].ContainsKey (ei.Name)){
-                                               expression = (string)styling[i] [ei.Name];
-                                               return true;
-                                       }
-                               }
-                       }
-                       return false;
-               }
-               bool getDefaultValue(PropertyInfo pi, List<Style> styling,
-                       out object defaultValue){
-                       defaultValue = null;
-                       string name = "";
-
-                       XmlIgnoreAttribute xia = (XmlIgnoreAttribute)pi.GetCustomAttribute (typeof(XmlIgnoreAttribute));
-                       if (xia != null)
-                               return false;
-                       XmlAttributeAttribute xaa = (XmlAttributeAttribute)pi.GetCustomAttribute (typeof(XmlAttributeAttribute));
-                       if (xaa != null) {
-                               if (string.IsNullOrEmpty (xaa.AttributeName))
-                                       name = pi.Name;
-                               else
-                                       name = xaa.AttributeName;
-                       }
-
-                       int styleIndex = -1;
-                       if (styling.Count > 0){
-                               for (int i = 0; i < styling.Count; i++) {
-                                       if (styling[i].ContainsKey (name)){
-                                               styleIndex = i;
-                                               break;
-                                       }
-                               }
-                       }
-                       if (styleIndex >= 0){
-                               if (pi.PropertyType.IsEnum)//maybe should be in parser..
-                                       defaultValue = Enum.Parse(pi.PropertyType, (string)styling[styleIndex] [name], true);
-                               else
-                                       defaultValue = styling[styleIndex] [name];
-                       }else {
-                               DefaultValueAttribute dv = (DefaultValueAttribute)pi.GetCustomAttribute (typeof (DefaultValueAttribute));
-                               if (dv == null)
-                                       return false;
-                               defaultValue = dv.Value;
-                       }
-                       return true;
-               }
-               #endregion
-
-               public virtual GraphicObject FindByName(string nameToFind){
-                       return string.Equals(nameToFind, name, StringComparison.Ordinal) ? this : null;
-               }
-               public virtual bool Contains(GraphicObject goToFind){
-                       return false;
-               }
-
-               #region Queuing
-               /// <summary>
-               /// Register old and new slot for clipping
-               /// </summary>
-               public virtual void ClippingRegistration(){
-                       IsQueueForRedraw = false;
-                       if (Parent == null)
-                               return;
-                       Parent.RegisterClip (LastPaintedSlot);
-                       Parent.RegisterClip (Slot);
-               }
-               /// <summary>
-               /// Add clip rectangle to this.clipping and propagate up to root
-               /// </summary>
-               /// <param name="clip">Clip rectangle</param>
-               public virtual void RegisterClip(Rectangle clip){
-                       if (CacheEnabled && !IsDirty)
-                               Clipping.AddRectangle (clip + ClientRectangle.Position);
-                       if (Parent == null)
-                               return;
-                       GraphicObject p = Parent as GraphicObject;
-                       if (p?.IsDirty == true && p?.CacheEnabled == true)
-                               return;
-                       Parent.RegisterClip (clip + Slot.Position + ClientRectangle.Position);
-               }
-               /// <summary> Full update, taking care of sizing policy </summary>
-               [MethodImpl(MethodImplOptions.AggressiveInlining)]
-               public void RegisterForGraphicUpdate ()
-               {
-                       IsDirty = true;
-                       if (Width.IsFit || Height.IsFit)
-                               RegisterForLayouting (LayoutingType.Sizing);
-                       else if (RegisteredLayoutings == LayoutingType.None)
-                               CurrentInterface.EnqueueForRepaint (this);
-               }
-               /// <summary> query an update of the content, a redraw </summary>
-               [MethodImpl(MethodImplOptions.AggressiveInlining)]
-               public void RegisterForRedraw ()
-               {
-                       IsDirty = true;
-                       if (RegisteredLayoutings == LayoutingType.None)
-                               CurrentInterface.EnqueueForRepaint (this);
-               }
-               #endregion
-
-               #region Layouting
-
-               /// <summary> return size of content + margins </summary>
-               protected virtual int measureRawSize (LayoutingType lt) {
-                       return lt == LayoutingType.Width ?
-                               contentSize.Width + 2 * Margin: contentSize.Height + 2 * Margin;
-               }
-               /// <summary> By default in groups, LayoutingType.ArrangeChildren is reset </summary>
-               public virtual void ChildrenLayoutingConstraints(ref LayoutingType layoutType){
-               }
-               public virtual bool ArrangeChildren { get { return false; } }
-               public virtual void RegisterForLayouting(LayoutingType layoutType){
-                       if (Parent == null)
-                               return;
-                       lock (CurrentInterface.LayoutMutex) {
-                               //prevent queueing same LayoutingType for this
-                               layoutType &= (~RegisteredLayoutings);
-
-                               if (layoutType == LayoutingType.None)
-                                       return;
-                               //dont set position for stretched item
-                               if (Width == Measure.Stretched)
-                                       layoutType &= (~LayoutingType.X);
-                               if (Height == Measure.Stretched)
-                                       layoutType &= (~LayoutingType.Y);
-
-                               if (!ArrangeChildren)
-                                       layoutType &= (~LayoutingType.ArrangeChildren);
-
-                               //apply constraints depending on parent type
-                               if (Parent is GraphicObject)
-                                       (Parent as GraphicObject).ChildrenLayoutingConstraints (ref layoutType);
-
-//                             //prevent queueing same LayoutingType for this
-//                             layoutType &= (~RegisteredLayoutings);
-
-                               if (layoutType == LayoutingType.None)
-                                       return;
-
-                               //enqueue LQI LayoutingTypes separately
-                               if (layoutType.HasFlag (LayoutingType.Width))
-                                       CurrentInterface.LayoutingQueue.Enqueue (new LayoutingQueueItem (LayoutingType.Width, this));
-                               if (layoutType.HasFlag (LayoutingType.Height))
-                                       CurrentInterface.LayoutingQueue.Enqueue (new LayoutingQueueItem (LayoutingType.Height, this));
-                               if (layoutType.HasFlag (LayoutingType.X))
-                                       CurrentInterface.LayoutingQueue.Enqueue (new LayoutingQueueItem (LayoutingType.X, this));
-                               if (layoutType.HasFlag (LayoutingType.Y))
-                                       CurrentInterface.LayoutingQueue.Enqueue (new LayoutingQueueItem (LayoutingType.Y, this));
-                               if (layoutType.HasFlag (LayoutingType.ArrangeChildren))
-                                       CurrentInterface.LayoutingQueue.Enqueue (new LayoutingQueueItem (LayoutingType.ArrangeChildren, this));
-                       }
-               }
-
-               /// <summary> trigger dependant sizing component update </summary>
-               public virtual void OnLayoutChanges(LayoutingType  layoutType)
-               {
-                       #if DEBUG_LAYOUTING
-                       CurrentInterface.currentLQI.Slot = LastSlots;
-                       CurrentInterface.currentLQI.NewSlot = Slot;
-                       Debug.WriteLine ("\t\t{0} => {1}",LastSlots,Slot);
-                       #endif
-
-                       switch (layoutType) {
-                       case LayoutingType.Width:
-                               RegisterForLayouting (LayoutingType.X);
-                               break;
-                       case LayoutingType.Height:
-                               RegisterForLayouting (LayoutingType.Y);
-                               break;
-                       }
-                       LayoutChanged.Raise (this, new LayoutingEventArgs (layoutType));
-               }
-               internal protected void raiseLayoutChanged(LayoutingEventArgs e){
-                       LayoutChanged.Raise (this, e);
-               }
-               /// <summary> Update layout component only one at a time, this is where the computation of alignement
-               /// and size take place.
-               /// The redrawing will only be triggered if final slot size has changed </summary>
-               /// <returns><c>true</c>, if layouting was possible, <c>false</c> if conditions were not
-               /// met and LQI has to be re-queued</returns>
-               public virtual bool UpdateLayout (LayoutingType layoutType)
-               {
-                       //unset bit, it would be reset if LQI is re-queued
-                       registeredLayoutings &= (~layoutType);
-
-                       switch (layoutType) {
-                       case LayoutingType.X:
-                               if (Left == 0) {
-
-                                       if (Parent.RegisteredLayoutings.HasFlag (LayoutingType.Width) ||
-                                           RegisteredLayoutings.HasFlag (LayoutingType.Width))
-                                               return false;
-
-                                       switch (HorizontalAlignment) {
-                                       case HorizontalAlignment.Left:
-                                               Slot.X = 0;
-                                               break;
-                                       case HorizontalAlignment.Right:
-                                               Slot.X = Parent.ClientRectangle.Width - Slot.Width;
-                                               break;
-                                       case HorizontalAlignment.Center:
-                                               Slot.X = Parent.ClientRectangle.Width / 2 - Slot.Width / 2;
-                                               break;
-                                       }
-                               } else
-                                       Slot.X = Left;
-
-                               if (LastSlots.X == Slot.X)
-                                       break;
-
-                               IsDirty = true;
-
-                               OnLayoutChanges (layoutType);
-
-                               LastSlots.X = Slot.X;
-                               break;
-                       case LayoutingType.Y:
-                               if (Top == 0) {
-
-                                       if (Parent.RegisteredLayoutings.HasFlag (LayoutingType.Height) ||
-                                           RegisteredLayoutings.HasFlag (LayoutingType.Height))
-                                               return false;
-
-                                       switch (VerticalAlignment) {
-                                       case VerticalAlignment.Top://this could be processed even if parent Height is not known
-                                               Slot.Y = 0;
-                                               break;
-                                       case VerticalAlignment.Bottom:
-                                               Slot.Y = Parent.ClientRectangle.Height - Slot.Height;
-                                               break;
-                                       case VerticalAlignment.Center:
-                                               Slot.Y = Parent.ClientRectangle.Height / 2 - Slot.Height / 2;
-                                               break;
-                                       }
-                               } else
-                                       Slot.Y = Top;
-
-                               if (LastSlots.Y == Slot.Y)
-                                       break;
-
-                               IsDirty = true;
-
-                               OnLayoutChanges (layoutType);
-
-                               LastSlots.Y = Slot.Y;
-                               break;
-                       case LayoutingType.Width:
-                               if (Visible) {
-                                       if (Width.IsFixed)
-                                               Slot.Width = Width;
-                                       else if (Width == Measure.Fit) {
-                                               Slot.Width = measureRawSize (LayoutingType.Width);
-                                       } else if (Parent.RegisteredLayoutings.HasFlag (LayoutingType.Width))
-                                               return false;
-                                       else if (Width == Measure.Stretched)
-                                               Slot.Width = Parent.ClientRectangle.Width;
-                                       else
-                                               Slot.Width = (int)Math.Round ((double)(Parent.ClientRectangle.Width * Width) / 100.0);
-
-                                       if (Slot.Width < 0)
-                                               return false;
-
-                                       //size constrain
-                                       if (Slot.Width < MinimumSize.Width) {
-                                               Slot.Width = MinimumSize.Width;
-                                               //NotifyValueChanged ("WidthPolicy", Measure.Stretched);
-                                       } else if (Slot.Width > MaximumSize.Width && MaximumSize.Width > 0) {
-                                               Slot.Width = MaximumSize.Width;
-                                               //NotifyValueChanged ("WidthPolicy", Measure.Stretched);
-                                       }
-                               } else
-                                       Slot.Width = 0;
-
-                               if (LastSlots.Width == Slot.Width)
-                                       break;
-
-                               IsDirty = true;
-
-                               OnLayoutChanges (layoutType);
-
-                               LastSlots.Width = Slot.Width;
-                               break;
-                       case LayoutingType.Height:
-                               if (Visible) {
-                                       if (Height.IsFixed)
-                                               Slot.Height = Height;
-                                       else if (Height == Measure.Fit) {
-                                               Slot.Height = measureRawSize (LayoutingType.Height);
-                                       } else if (Parent.RegisteredLayoutings.HasFlag (LayoutingType.Height))
-                                               return false;
-                                       else if (Height == Measure.Stretched)
-                                               Slot.Height = Parent.ClientRectangle.Height;
-                                       else
-                                               Slot.Height = (int)Math.Round ((double)(Parent.ClientRectangle.Height * Height) / 100.0);
-
-                                       if (Slot.Height < 0)
-                                               return false;
-
-                                       //size constrain
-                                       if (Slot.Height < MinimumSize.Height) {
-                                               Slot.Height = MinimumSize.Height;
-                                               //NotifyValueChanged ("HeightPolicy", Measure.Stretched);
-                                       } else if (Slot.Height > MaximumSize.Height && MaximumSize.Height > 0) {
-                                               Slot.Height = MaximumSize.Height;
-                                               //NotifyValueChanged ("HeightPolicy", Measure.Stretched);
-                                       }
-                               } else
-                                       Slot.Height = 0;
-
-                               if (LastSlots.Height == Slot.Height)
-                                       break;
-
-                               IsDirty = true;
-
-                               OnLayoutChanges (layoutType);
-
-                               LastSlots.Height = Slot.Height;
-                               break;
-                       }
-
-                       //if no layouting remains in queue for item, registre for redraw
-                       if (this.registeredLayoutings == LayoutingType.None && IsDirty)
-                               CurrentInterface.EnqueueForRepaint (this);
-
-                       return true;
-               }
-               #endregion
-
-               #region Rendering
-               /// <summary> This is the common overridable drawing routine to create new widget </summary>
-               protected virtual void onDraw(Context gr)
-               {
-                       Rectangle rBack = new Rectangle (Slot.Size);
-
-                       Background.SetAsSource (gr, rBack);
-                       CairoHelpers.CairoRectangle(gr,rBack,cornerRadius);
-                       gr.Fill ();
-               }
-
-               /// <summary>
-               /// Internal drawing context creation on a cached surface limited to slot size
-               /// this trigger the effective drawing routine </summary>
-               protected virtual void RecreateCache ()
-               {
-                       int stride = 4 * Slot.Width;
-
-                       int bmpSize = Math.Abs (stride) * Slot.Height;
-                       bmp = new byte[bmpSize];
-                       IsDirty = false;
-                       using (ImageSurface draw =
-                new ImageSurface(bmp, Format.Argb32, Slot.Width, Slot.Height, stride)) {
-                               using (Context gr = new Context (draw)) {
-                                       gr.Antialias = Interface.Antialias;
-                                       onDraw (gr);
-                               }
-                               draw.Flush ();
-                       }
-               }
-               protected virtual void UpdateCache(Context ctx){
-                       Rectangle rb = Slot + Parent.ClientRectangle.Position;
-                       using (ImageSurface cache = new ImageSurface (bmp, Format.Argb32, Slot.Width, Slot.Height, 4 * Slot.Width)) {
-                               if (clearBackground) {
-                                               ctx.Save ();
-                                               ctx.Operator = Operator.Clear;
-                                               ctx.Rectangle (rb);
-                                               ctx.Fill ();
-                                               ctx.Restore ();
-                               }
-                               ctx.SetSourceSurface (cache, rb.X, rb.Y);
-                               ctx.Paint ();
-                       }
-                       //Clipping.clearAndClip (ctx);
-                       Clipping.Reset();
-               }
-               /// <summary> Chained painting routine on the parent context of the actual cached version
-               /// of the widget </summary>
-               public virtual void Paint (ref Context ctx)
-               {
-                       //TODO:this test should not be necessary
-                       if (Slot.Height < 0 || Slot.Width < 0 || parent == null)
-                               return;
-                       lock (this) {
-                               if (cacheEnabled) {
-                                       if (Slot.Width > Interface.MaxCacheSize || Slot.Height > Interface.MaxCacheSize)
-                                               cacheEnabled = false;
-                               }
-
-                               if (cacheEnabled) {
-                                       if (IsDirty)
-                                               RecreateCache ();
-
-                                       UpdateCache (ctx);
-                                       if (!isEnabled)
-                                               paintDisabled (ctx, Slot + Parent.ClientRectangle.Position);
-                               } else {
-                                       Rectangle rb = Slot + Parent.ClientRectangle.Position;
-                                       ctx.Save ();
-
-                                       ctx.Translate (rb.X, rb.Y);
-
-                                       onDraw (ctx);
-                                       if (!isEnabled)
-                                               paintDisabled (ctx, Slot);
-
-                                       ctx.Restore ();
-                               }
-                               LastPaintedSlot = Slot;
-                       }
-               }
-               void paintDisabled(Context gr, Rectangle rb){
-                       gr.Operator = Operator.Xor;
-                       gr.SetSourceRGBA (0.6, 0.6, 0.6, 0.3);
-                       gr.Rectangle (rb);
-                       gr.Fill ();
-                       gr.Operator = Operator.Over;
-               }
-               #endregion
-
-        #region Keyboard handling
-               public virtual void onKeyDown(object sender, KeyboardKeyEventArgs e){
-                       KeyDown.Raise (sender, e);
-               }
-               public virtual void onKeyUp(object sender, KeyboardKeyEventArgs e){
-                       KeyUp.Raise (sender, e);
-               }
-               public virtual void onKeyPress(object sender, KeyPressEventArgs e){
-                       KeyPress.Raise (sender, e);
-               }
-        #endregion
-
-               #region Mouse handling
-               public virtual bool MouseIsIn(Point m)
-               {
-                       try {
-                               if (!(Visible & isEnabled))
-                                       return false;
-                               if (ScreenCoordinates (Slot).ContainsOrIsEqual (m)) {
-                                       Scroller scr = Parent as Scroller;
-                                       if (scr == null) {
-                                               if (Parent is GraphicObject)
-                                                       return (Parent as GraphicObject).MouseIsIn (m);
-                                               else return true;
-                                       }
-                                       return scr.MouseIsIn (scr.savedMousePos);
-                               }
-                       } catch (Exception ex) {
-                               return false;
-                       }
-                       return false;
-               }
-               public virtual void checkHoverWidget(MouseMoveEventArgs e)
-               {
-                       if (CurrentInterface.HoverWidget != this) {
-                               CurrentInterface.HoverWidget = this;
-                               onMouseEnter (this, e);
-                       }
-
-                       this.onMouseMove (this, e);//without this, window border doesn't work, should be removed
-               }
-               public virtual void onMouseMove(object sender, MouseMoveEventArgs e)
-               {
-                       //bubble event to the top
-                       GraphicObject p = Parent as GraphicObject;
-                       if (p != null)
-                               p.onMouseMove(sender,e);
-
-                       MouseMove.Raise (this, e);
-               }
-               public virtual void onMouseDown(object sender, MouseButtonEventArgs e){
-                       if (CurrentInterface.eligibleForDoubleClick == this && CurrentInterface.clickTimer.ElapsedMilliseconds < Interface.DoubleClick)
-                               onMouseDoubleClick (this, e);
-                       else
-                               currentInterface.clickTimer.Restart();
-                       CurrentInterface.eligibleForDoubleClick = null;
-
-                       if (CurrentInterface.ActiveWidget == null)
-                               CurrentInterface.ActiveWidget = this;
-                       if (this.Focusable && !Interface.FocusOnHover) {
-                               BubblingMouseButtonEventArg be = e as BubblingMouseButtonEventArg;
-                               if (be.Focused == null) {
-                                       be.Focused = this;
-                                       CurrentInterface.FocusedWidget = this;
-                               }
-                       }
-                       //bubble event to the top
-                       GraphicObject p = Parent as GraphicObject;
-                       if (p != null)
-                               p.onMouseDown(sender,e);
-
-                       MouseDown.Raise (this, e);
-               }
-               public virtual void onMouseUp(object sender, MouseButtonEventArgs e){
-                       //bubble event to the top
-                       GraphicObject p = Parent as GraphicObject;
-                       if (p != null)
-                               p.onMouseUp(sender,e);
-
-                       MouseUp.Raise (this, e);
-
-                       if (MouseIsIn (e.Position) && IsActive) {
-                               if (CurrentInterface.clickTimer.ElapsedMilliseconds < Interface.DoubleClick)
-                                       CurrentInterface.eligibleForDoubleClick = this;
-                               onMouseClick (this, e);
-                       }
-               }
-               public virtual void onMouseClick(object sender, MouseButtonEventArgs e){
-                       GraphicObject p = Parent as GraphicObject;
-                       if (p != null)
-                               p.onMouseClick(sender,e);
-                       MouseClick.Raise (this, e);
-               }
-               public virtual void onMouseDoubleClick(object sender, MouseButtonEventArgs e){
-                       GraphicObject p = Parent as GraphicObject;
-                       if (p != null)
-                               p.onMouseDoubleClick(sender,e);
-                       MouseDoubleClick.Raise (this, e);
-               }
-               public virtual void onMouseWheel(object sender, MouseWheelEventArgs e){
-                       GraphicObject p = Parent as GraphicObject;
-                       if (p != null)
-                               p.onMouseWheel(sender,e);
-
-                       MouseWheelChanged.Raise (this, e);
-               }
-               public virtual void onMouseEnter(object sender, MouseMoveEventArgs e)
-               {
-                       #if DEBUG_FOCUS
-                       Debug.WriteLine("MouseEnter => " + this.ToString());
-                       #endif
-                       MouseEnter.Raise (this, e);
-               }
-               public virtual void onMouseLeave(object sender, MouseMoveEventArgs e)
-               {
-                       #if DEBUG_FOCUS
-                       Debug.WriteLine("MouseLeave => " + this.ToString());
-                       #endif
-                       MouseLeave.Raise (this, e);
-               }
-               #endregion
-
-               protected virtual void onFocused(object sender, EventArgs e){
-                       #if DEBUG_FOCUS
-                       Debug.WriteLine("Focused => " + this.ToString());
-                       #endif
-                       Focused.Raise (this, e);
-               }
-               protected virtual void onUnfocused(object sender, EventArgs e){
-                       #if DEBUG_FOCUS
-                       Debug.WriteLine("UnFocused => " + this.ToString());
-                       #endif
-                       Unfocused.Raise (this, e);
-               }
-               public virtual void onEnable(object sender, EventArgs e){
-                       Enabled.Raise (this, e);
-               }
-               public virtual void onDisable(object sender, EventArgs e){
-                       Disabled.Raise (this, e);
-               }
-               protected virtual void onParentChanged(object sender, DataSourceChangeEventArgs e) {
-                       ParentChanged.Raise (this, e);
-                       if (logicalParent == null)
-                               LogicalParentChanged.Raise (this, e);
-               }
-               protected virtual void onLogicalParentChanged(object sender, DataSourceChangeEventArgs e) {
-                       LogicalParentChanged.Raise (this, e);
-               }
-               #region IXmlSerializable
-               public virtual System.Xml.Schema.XmlSchema GetSchema ()
-               {
-                       return null;
-               }
-//             void affectMember(string name, string value){
-//                     Type thisType = this.GetType ();
-//
-//                     if (string.IsNullOrEmpty (value))
-//                             return;
-//
-//                     MemberInfo mi = thisType.GetMember (name).FirstOrDefault();
-//                     if (mi == null) {
-//                             Debug.WriteLine ("XML: Unknown attribute in " + thisType.ToString() + " : " + name);
-//                             return;
-//                     }
-//                     if (mi.MemberType == MemberTypes.Event) {
-//                             this.Bindings.Add (new Binding (new MemberReference(this, mi), value));
-//                             return;
-//                     }
-//                     if (mi.MemberType == MemberTypes.Property) {
-//                             PropertyInfo pi = mi as PropertyInfo;
-//
-//                             if (pi.GetSetMethod () == null) {
-//                                     Debug.WriteLine ("XML: Read only property in " + thisType.ToString() + " : " + name);
-//                                     return;
-//                             }
-//
-//                             XmlAttributeAttribute xaa = (XmlAttributeAttribute)pi.GetCustomAttribute (typeof(XmlAttributeAttribute));
-//                             if (xaa != null) {
-//                                     if (!string.IsNullOrEmpty (xaa.AttributeName))
-//                                             name = xaa.AttributeName;
-//                             }
-//                             if (value.StartsWith("{",StringComparison.Ordinal)) {
-//                                     //binding
-//                                     if (!value.EndsWith("}", StringComparison.Ordinal))
-//                                             throw new Exception (string.Format("XML:Malformed binding: {0}", value));
-//
-//                                     this.Bindings.Add (new Binding (new MemberReference(this, pi), value.Substring (1, value.Length - 2)));
-//                                     return;
-//                             }
-//                             if (pi.GetCustomAttribute (typeof(XmlIgnoreAttribute)) != null)
-//                                     return;
-//                             if (xaa == null)//not define as xmlAttribute
-//                                     return;
-//
-//                             if (pi.PropertyType == typeof(string)) {
-//                                     pi.SetValue (this, value, null);
-//                                     return;
-//                             }
-//
-//                             if (pi.PropertyType.IsEnum) {
-//                                     pi.SetValue (this, Enum.Parse (pi.PropertyType, value), null);
-//                             } else {
-//                                     MethodInfo me = pi.PropertyType.GetMethod ("Parse", new Type[] { typeof(string) });
-//                                     pi.SetValue (this, me.Invoke (null, new string[] { value }), null);
-//                             }
-//                     }
-//             }
-               public virtual void ReadXml (System.Xml.XmlReader reader)
-               {
-                       if (reader.HasAttributes) {
-
-                               style = reader.GetAttribute ("Style");
-
-                               loadDefaultValues ();
-
-                               while (reader.MoveToNextAttribute ()) {
-                                       if (reader.Name == "Style")
-                                               continue;
-
-                                       //affectMember (reader.Name, reader.Value);
-                               }
-                               reader.MoveToElement ();
-                       }else
-                               loadDefaultValues ();
-               }
-               public virtual void WriteXml (System.Xml.XmlWriter writer)
-               {
-                       foreach (PropertyInfo pi in this.GetType().GetProperties(BindingFlags.Public | BindingFlags.Instance)) {
-                               if (pi.GetSetMethod () == null)
-                                       continue;
-
-                               bool isAttribute = false;
-                               bool hasDefaultValue = false;
-                               bool ignore = false;
-                               string name = "";
-                               object value = null;
-                               Type valueType = null;
-
-
-                               MemberInfo mi = pi.GetGetMethod ();
-
-                               if (mi == null)
-                                       continue;
-
-                               value = pi.GetValue (this, null);
-                               valueType = pi.PropertyType;
-                               name = pi.Name;
-
-
-
-                               object[] att = pi.GetCustomAttributes (false);
-
-                               foreach (object o in att) {
-                                       XmlAttributeAttribute xaa = o as XmlAttributeAttribute;
-                                       if (xaa != null) {
-                                               isAttribute = true;
-                                               if (string.IsNullOrEmpty (xaa.AttributeName))
-                                                       name = pi.Name;
-                                               else
-                                                       name = xaa.AttributeName;
-                                               continue;
-                                       }
-
-                                       XmlIgnoreAttribute xia = o as XmlIgnoreAttribute;
-                                       if (xia != null) {
-                                               ignore = true;
-                                               continue;
-                                       }
-
-                                       DefaultValueAttribute dv = o as DefaultValueAttribute;
-                                       if (dv != null) {
-                                               if (dv.Value.Equals (value))
-                                                       hasDefaultValue = true;
-                                               if (dv.Value.ToString () == value.ToString ())
-                                                       hasDefaultValue = true;
-
-                                               continue;
-                                       }
-
-
-                               }
-
-                               if (hasDefaultValue || ignore || value==null)
-                                       continue;
-
-                               if (isAttribute)
-                                       writer.WriteAttributeString (name, value.ToString ());
-                               else {
-                                       if (valueType.GetInterface ("IXmlSerializable") == null)
-                                               continue;
-
-                                       (pi.GetValue (this, null) as IXmlSerializable).WriteXml (writer);
-                               }
-                       }
-                       foreach (EventInfo ei in this.GetType().GetEvents()) {
-                               FieldInfo fi = this.GetType().GetField(ei.Name,
-                                       BindingFlags.NonPublic |
-                                       BindingFlags.Instance |
-                                       BindingFlags.GetField);
-
-                               Delegate dg = (System.Delegate)fi.GetValue (this);
-
-                               if (dg == null)
-                                       continue;
-
-                               foreach (Delegate d in dg.GetInvocationList()) {
-                                       if (!d.Method.Name.StartsWith ("<"))//Skipping empty handler, not clear it's trikky
-                                               writer.WriteAttributeString (ei.Name, d.Method.Name);
-                               }
-                       }
-               }
-               #endregion
-
-               #region ICloneable implementation
-               public object Clone ()
-               {
-                       Type type = this.GetType ();
-                       GraphicObject result = (GraphicObject)Activator.CreateInstance (type);
-                       result.CurrentInterface = CurrentInterface;
-
-                       foreach (PropertyInfo pi in type.GetProperties(BindingFlags.Public | BindingFlags.Instance)) {
-                               if (pi.GetSetMethod () == null)
-                                       continue;
-
-                               if (pi.GetCustomAttribute<XmlIgnoreAttribute> () != null)
-                                       continue;
-                               if (pi.Name == "DataSource")
-                                       continue;
-
-                               pi.SetValue(result, pi.GetValue(this));
-                       }
-                       return result;
-               }
-               #endregion
-               /// <summary>
-               /// full GraphicTree clone with binding definition
-               /// </summary>
-
-               public override string ToString ()
-               {
-                       string tmp ="";
-
-                       if (Parent != null)
-                               tmp = Parent.ToString () + tmp;
-                       #if DEBUG_LAYOUTING
-                       return Name == "unamed" ? tmp + "." + this.GetType ().Name + uid.ToString(): tmp + "." + Name;
-                       #else
-                       return Name == "unamed" ? tmp + "." + this.GetType ().Name : tmp + "." + Name;
-                       #endif
-               }
-       }
-}
diff --git a/src/GraphicObjects/Group.cs b/src/GraphicObjects/Group.cs
deleted file mode 100644 (file)
index d00449c..0000000
+++ /dev/null
@@ -1,408 +0,0 @@
-//
-// Group.cs
-//
-// Author:
-//       Jean-Philippe Bruyère <jp.bruyere@hotmail.com>
-//
-// Copyright (c) 2013-2017 Jean-Philippe Bruyère
-//
-// 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.Generic;
-using System.ComponentModel;
-using System.Xml.Serialization;
-using Cairo;
-using OpenTK.Input;
-using System.Diagnostics;
-using System.Reflection;
-
-
-namespace Crow
-{
-       public class Group : GraphicObject, IXmlSerializable
-    {
-               #region CTOR
-               public Group()
-                       : base(){}
-               #endregion
-
-               #region EVENT HANDLERS
-               public event EventHandler<EventArgs> ChildrenCleared;
-               #endregion
-
-               internal GraphicObject largestChild = null;
-               internal GraphicObject tallestChild = null;
-
-        bool _multiSelect = false;
-               List<GraphicObject> children = new List<GraphicObject>();
-
-        public virtual List<GraphicObject> Children {
-                       get { return children; }
-               }
-               [XmlAttributeAttribute()][DefaultValue(false)]
-        public bool MultiSelect
-        {
-            get { return _multiSelect; }
-            set { _multiSelect = value; }
-        }
-               public virtual void AddChild(GraphicObject g){
-                       lock (children) {
-                               g.Parent = this;
-                               Children.Add (g);
-                       }
-                       g.RegisteredLayoutings = LayoutingType.None;
-                       g.RegisterForLayouting (LayoutingType.Sizing | LayoutingType.ArrangeChildren);
-                       g.LayoutChanged += OnChildLayoutChanges;
-               }
-        public virtual void RemoveChild(GraphicObject child)        
-               {
-                       child.LayoutChanged -= OnChildLayoutChanges;
-                       //child.Parent = null;
-                       lock (children)
-               Children.Remove(child);
-
-                       if (child == largestChild && Width == Measure.Fit)
-                               searchLargestChild ();
-                       if (child == tallestChild && Height == Measure.Fit)
-                               searchTallestChild ();
-                       
-                       this.RegisterForLayouting (LayoutingType.Sizing | LayoutingType.ArrangeChildren);
-        }
-               public virtual void ClearChildren()
-               {
-                       lock (children) {
-                               while (Children.Count > 0) {
-                                       GraphicObject g = Children [Children.Count - 1];
-                                       g.LayoutChanged -= OnChildLayoutChanges;
-                                       g.Parent = null;
-                                       Children.RemoveAt (Children.Count - 1);
-                               }
-                       }
-
-                       resetChildrenMaxSize ();
-
-                       this.RegisterForLayouting (LayoutingType.Sizing);
-                       ChildrenCleared.Raise (this, new EventArgs ());
-               }
-
-               public void putWidgetOnTop(GraphicObject w)
-               {
-                       if (Children.Contains(w))
-                       {
-                               lock (children) {
-                                       Children.Remove (w);
-                                       Children.Add (w);
-                               }
-                       }
-               }
-               public void putWidgetOnBottom(GraphicObject w)
-               {
-                       if (Children.Contains(w))
-                       {
-                               lock (children) {
-                                       Children.Remove (w);
-                                       Children.Insert (0, w);
-                               }
-                       }
-               }
-
-               #region GraphicObject overrides
-               public override void OnDataSourceChanged (object sender, DataSourceChangeEventArgs e)
-               {
-                       base.OnDataSourceChanged (this, e);
-                       lock (children) {
-                               foreach (GraphicObject g in children)
-                                       if (g.localDataSourceIsNull & g.localLogicalParentIsNull)
-                                               g.OnDataSourceChanged (sender, e);
-                       }
-               }
-               public override GraphicObject FindByName (string nameToFind)
-               {
-                       if (Name == nameToFind)
-                               return this;
-                       GraphicObject tmp = null;
-                       lock (children) {
-                               foreach (GraphicObject w in Children) {
-                                       tmp = w.FindByName (nameToFind);
-                                       if (tmp != null)
-                                               break;
-                               }
-                       }
-                       return tmp;
-               }
-               public override bool Contains (GraphicObject goToFind)
-               {
-                       foreach (GraphicObject w in Children) {
-                               if (w == goToFind)
-                                       return true;
-                               if (w.Contains (goToFind))
-                                       return true;
-                       }
-                       return false;
-               }
-               protected override int measureRawSize (LayoutingType lt)
-               {
-                       if (Children.Count > 0) {
-                               if (lt == LayoutingType.Width) {
-                                       if (largestChild == null)
-                                               searchLargestChild ();
-                                       if (largestChild == null) {
-                                               //if still null, not possible to determine a width
-                                               //because all children are stretched, force first one to fit
-                                               Children [0].Width = Measure.Fit;
-                                               return -1;//cancel actual sizing to let child computation take place
-                                       }
-                               } else {
-                                       if (tallestChild == null)
-                                               searchTallestChild ();
-                                       if (tallestChild == null) {
-                                               Children [0].Height = Measure.Fit;
-                                               return -1;
-                                       }
-                               }
-                       }
-                       return base.measureRawSize (lt);
-               }
-                       
-               public override void OnLayoutChanges (LayoutingType layoutType)
-               {
-                       base.OnLayoutChanges (layoutType);
-
-                       //position smaller objects in group when group size is fit
-                       switch (layoutType) {
-                       case LayoutingType.Width:
-                               foreach (GraphicObject c in Children){
-                                       if (c.Width.Units == Unit.Percent)
-                                               c.RegisterForLayouting (LayoutingType.Width);
-                                       else
-                                               c.RegisterForLayouting (LayoutingType.X);
-                               }
-                               break;
-                       case LayoutingType.Height:
-                               foreach (GraphicObject c in Children) {
-                                       if (c.Height.Units == Unit.Percent)
-                                               c.RegisterForLayouting (LayoutingType.Height);
-                                       else
-                                               c.RegisterForLayouting (LayoutingType.Y);
-                               }
-                               break;
-                       }
-               }
-               protected override void onDraw (Context gr)
-               {
-                       base.onDraw (gr);
-
-                       gr.Save ();
-
-                       if (ClipToClientRect) {
-                               //clip to client zone
-                               CairoHelpers.CairoRectangle (gr, ClientRectangle, CornerRadius);
-                               gr.Clip ();
-                       }
-
-                       lock (children) {
-                               foreach (GraphicObject g in Children) {
-                                       g.Paint (ref gr);
-                               }
-                       }
-                       gr.Restore ();
-               }
-               protected override void UpdateCache (Context ctx)
-               {
-                       Rectangle rb = Slot + Parent.ClientRectangle.Position;
-
-                       using (ImageSurface cache = new ImageSurface (bmp, Format.Argb32, Slot.Width, Slot.Height, 4 * Slot.Width)) {
-                               Context gr = new Context (cache);
-
-                               if (Clipping.count > 0) {
-                                       Clipping.clearAndClip (gr);
-                                       base.onDraw (gr);
-
-                                       //clip to client zone
-                                       CairoHelpers.CairoRectangle (gr, ClientRectangle, CornerRadius);
-                                       gr.Clip ();
-
-                                       lock (Children) {
-                                               foreach (GraphicObject c in Children) {
-                                                       if (!c.Visible)
-                                                               continue;
-                                                       if (Clipping.intersect (c.Slot + ClientRectangle.Position))
-                                                               c.Paint (ref gr);
-                                               }
-                                       }
-
-                                       #if DEBUG_CLIP_RECTANGLE
-                                       Clipping.stroke (gr, Color.Amaranth.AdjustAlpha (0.8));
-                                       #endif
-                               }
-                               gr.Dispose ();
-
-                               ctx.SetSourceSurface (cache, rb.X, rb.Y);
-                               ctx.Paint ();
-                       }
-                       Clipping.Reset();
-               }
-               #endregion
-
-               public virtual void OnChildLayoutChanges (object sender, LayoutingEventArgs arg)
-               {
-                       GraphicObject g = sender as GraphicObject;
-
-                       switch (arg.LayoutType) {
-                       case LayoutingType.Width:
-                               if (Width != Measure.Fit)
-                                       return;
-                               if (g.Slot.Width > contentSize.Width) {
-                                       largestChild = g;
-                                       contentSize.Width = g.Slot.Width;
-                               } else if (g == largestChild)
-                                       searchLargestChild ();
-
-                               this.RegisterForLayouting (LayoutingType.Width);
-                               break;
-                       case LayoutingType.Height:
-                               if (Height != Measure.Fit)
-                                       return;
-                               if (g.Slot.Height > contentSize.Height) {
-                                       tallestChild = g;
-                                       contentSize.Height = g.Slot.Height;
-                               } else if (g == tallestChild)
-                                       searchTallestChild ();
-
-                               this.RegisterForLayouting (LayoutingType.Height);
-                               break;
-                       }
-               }
-               //TODO: x,y position should be taken in account for computation of width and height
-               void resetChildrenMaxSize(){
-                       largestChild = null;
-                       tallestChild = null;
-                       contentSize = 0;
-               }
-               void searchLargestChild(){
-                       #if DEBUG_LAYOUTING
-                       Debug.WriteLine("\tSearch largest child");
-                       #endif
-                       largestChild = null;
-                       contentSize.Width = 0;
-                       for (int i = 0; i < Children.Count; i++) {
-                               if (!Children [i].Visible)
-                                       continue;
-                               if (children [i].RegisteredLayoutings.HasFlag (LayoutingType.Width))
-                                       continue;
-                               if (Children [i].Slot.Width > contentSize.Width) {
-                                       contentSize.Width = Children [i].Slot.Width;
-                                       largestChild = Children [i];
-                               }
-                       }
-               }
-               void searchTallestChild(){
-                       #if DEBUG_LAYOUTING
-                       Debug.WriteLine("\tSearch tallest child");
-                       #endif
-                       tallestChild = null;
-                       contentSize.Height = 0;
-                       for (int i = 0; i < Children.Count; i++) {
-                               if (!Children [i].Visible)
-                                       continue;
-                               if (children [i].RegisteredLayoutings.HasFlag (LayoutingType.Height))
-                                       continue;
-                               if (Children [i].Slot.Height > contentSize.Height) {
-                                       contentSize.Height = Children [i].Slot.Height;
-                                       tallestChild = Children [i];
-                               }
-                       }
-               }
-
-       
-               #region Mouse handling
-               public override void checkHoverWidget (MouseMoveEventArgs e)
-               {
-                       if (CurrentInterface.HoverWidget != this) {
-                               CurrentInterface.HoverWidget = this;
-                               onMouseEnter (this, e);
-                       }
-                       for (int i = Children.Count - 1; i >= 0; i--) {
-                               if (Children[i].MouseIsIn(e.Position))
-                               {
-                                       Children[i].checkHoverWidget (e);
-                                       return;
-                               }
-                       }
-                       base.checkHoverWidget (e);
-               }
-               #endregion
-
-
-               #region IXmlSerializable
-
-        public override System.Xml.Schema.XmlSchema GetSchema()
-        {
-            return null;
-        }
-        public override void ReadXml(System.Xml.XmlReader reader)
-        {
-            base.ReadXml(reader);
-
-            using (System.Xml.XmlReader subTree = reader.ReadSubtree())
-            {
-                subTree.Read();
-
-                while (!subTree.EOF)
-                {
-                    subTree.Read();
-
-                    if (!subTree.IsStartElement())
-                        break;
-
-                    Type t = Type.GetType("Crow." + subTree.Name);
-                                       if (t == null) {
-                                               Assembly a = Assembly.GetEntryAssembly ();
-                                               foreach (Type expT in a.GetExportedTypes ()) {
-                                                       if (expT.Name == subTree.Name) {
-                                                               t = expT;
-                                                               break;
-                                                       }
-                                               }
-                                       }
-                                       if (t == null)
-                                               throw new Exception (subTree.Name + " type not found");
-                    GraphicObject go = (GraphicObject)Activator.CreateInstance(t);
-                    (go as IXmlSerializable).ReadXml(subTree);                    
-                    AddChild(go);
-                }
-            }
-        }
-        public override void WriteXml(System.Xml.XmlWriter writer)
-        {
-            base.WriteXml(writer);
-
-            foreach (GraphicObject go in Children)
-            {
-                writer.WriteStartElement(go.GetType().Name);
-                (go as IXmlSerializable).WriteXml(writer);
-                writer.WriteEndElement();
-            }
-        }
-    
-               #endregion
-
-       }
-}
diff --git a/src/GraphicObjects/GroupBox.cs b/src/GraphicObjects/GroupBox.cs
deleted file mode 100644 (file)
index 9cabbb5..0000000
+++ /dev/null
@@ -1,58 +0,0 @@
-//
-// GroupBox.cs
-//
-// Author:
-//       Jean-Philippe Bruyère <jp.bruyere@hotmail.com>
-//
-// Copyright (c) 2013-2017 Jean-Philippe Bruyère
-//
-// 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.Xml.Serialization;
-using System.ComponentModel;
-
-namespace Crow
-{
-    public class GroupBox : TemplatedContainer
-    {
-               Container _contentContainer;
-
-               #region CTOR
-               public GroupBox() : base(){}
-               #endregion
-
-               #region Template overrides
-               public override GraphicObject Content {
-                       get {
-                               return _contentContainer == null ? null : _contentContainer.Child;
-                       }
-                       set {
-                               _contentContainer.SetChild(value);
-                       }
-               }
-               protected override void loadTemplate(GraphicObject template = null)
-               {
-                       base.loadTemplate (template);
-
-                       _contentContainer = this.child.FindByName ("Content") as Container;
-               }
-               #endregion
-       }
-}
diff --git a/src/GraphicObjects/HorizontalStack.cs b/src/GraphicObjects/HorizontalStack.cs
deleted file mode 100644 (file)
index 620dab2..0000000
+++ /dev/null
@@ -1,48 +0,0 @@
-//
-// HorizontalStack.cs
-//
-// Author:
-//       Jean-Philippe Bruyère <jp.bruyere@hotmail.com>
-//
-// Copyright (c) 2013-2017 Jean-Philippe Bruyère
-//
-// 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.Generic;
-using System.Linq;
-using System.Text;
-using System.Xml.Serialization;
-
-namespace Crow
-{
-    public class HorizontalStack : GenericStack
-    {
-        public HorizontalStack()
-            : base()
-        {            
-        }
-
-        [XmlIgnore]
-        public override Orientation Orientation
-        {
-            get { return Orientation.Horizontal; }
-        }
-    }
-}
diff --git a/src/GraphicObjects/Image.cs b/src/GraphicObjects/Image.cs
deleted file mode 100644 (file)
index 6a4c590..0000000
+++ /dev/null
@@ -1,181 +0,0 @@
-//
-// Image.cs
-//
-// Author:
-//       Jean-Philippe Bruyère <jp.bruyere@hotmail.com>
-//
-// Copyright (c) 2013-2017 Jean-Philippe Bruyère
-//
-// 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 Cairo;
-using System.Xml.Serialization;
-using System.ComponentModel;
-using System.Diagnostics;
-
-
-namespace Crow
-{
-       public class Image : GraphicObject
-       {
-               Picture _pic;
-               string _svgSub;
-               bool scaled, keepProps;
-               double opacity;
-
-               #region Public properties
-               [XmlAttributeAttribute][DefaultValue(true)]
-               public virtual bool Scaled {
-                       get { return scaled; }
-                       set {
-                               if (scaled == value)
-                                       return;
-                               scaled = value;
-                               NotifyValueChanged ("Scaled", scaled);
-                               if (_pic == null)
-                                       return;
-                               _pic.Scaled = scaled;
-                               RegisterForGraphicUpdate ();
-                       }
-               }
-               [XmlAttributeAttribute][DefaultValue(true)]
-               public virtual bool KeepProportions {
-                       get { return keepProps; }
-                       set {
-                               if (keepProps == value)
-                                       return;
-                               keepProps = value;
-                               NotifyValueChanged ("KeepProportions", keepProps);
-                               if (_pic == null)
-                                       return;
-                               _pic.KeepProportions = keepProps;
-                               RegisterForGraphicUpdate ();
-                       }
-               }
-        [XmlAttributeAttribute]
-               public string Path {
-                       get { return _pic == null ? "" : _pic.Path; }
-                       set {
-                               if (value == Path)
-                                       return;
-                               try {
-                                       if (string.IsNullOrEmpty(value))
-                                               Picture = null;
-                                       else {
-                                               lock(CurrentInterface.LayoutMutex){
-                                                       LoadImage (value);
-                                               }
-                                       }
-                               } catch (Exception ex) {
-                                       Debug.WriteLine (ex.Message);
-                                       _pic = null;
-                               }
-                               NotifyValueChanged ("Path", Path);
-                       }
-               }
-               [XmlAttributeAttribute]
-               public string SvgSub {
-                       get { return _svgSub; }
-                       set {
-                               if (_svgSub == value)
-                                       return;
-                               _svgSub = value;
-                               RegisterForGraphicUpdate ();
-                       }
-               }
-               [XmlAttributeAttribute]
-               public Picture Picture {
-                       get { return _pic; }
-                       set {
-                               if (_pic == value)
-                                       return;
-                               _pic = value;
-                               NotifyValueChanged ("Picture", _pic);
-                               RegisterForGraphicUpdate ();
-                       }
-               }
-               [XmlAttributeAttribute()][DefaultValue(1.0)]
-               public virtual double Opacity {
-                       get { return opacity; }
-                       set {
-                               if (opacity == value)
-                                       return;
-                               opacity = value;
-                               NotifyValueChanged ("Faded", opacity);
-                               RegisterForRedraw ();
-                       }
-               }
-               #endregion
-
-               #region CTOR
-               public Image () : base()
-               {
-               }
-               #endregion
-
-               #region Image Loading
-               public void LoadImage (string path)
-               {
-                       Picture pic;
-                       if (path.EndsWith (".svg", true, System.Globalization.CultureInfo.InvariantCulture))
-                               pic = new SvgPicture ();
-                       else
-                               pic = new BmpPicture ();
-
-                       pic.LoadImage (path);
-                       pic.Scaled = scaled;
-                       pic.KeepProportions = keepProps;
-
-                       Picture = pic;
-               }
-               #endregion
-
-               #region GraphicObject overrides
-               protected override int measureRawSize (LayoutingType lt)
-               {
-                       if (_pic == null)
-                               return 2 * Margin;
-                               //_pic = "#Crow.Images.Icons.IconAlerte.svg";
-                       //TODO:take scalling in account
-                       if (lt == LayoutingType.Width)
-                               return _pic.Dimensions.Width + 2 * Margin;
-                       else
-                               return _pic.Dimensions.Height + 2 * Margin;
-               }
-               protected override void onDraw (Context gr)
-               {
-                       base.onDraw (gr);
-
-                       if (_pic == null)
-                               return;
-
-                       _pic.Paint (gr, ClientRectangle, _svgSub);
-
-                       if (Opacity<1.0) {
-                               gr.SetSourceRGBA (0.0, 0.0, 0.0, 1.0-Opacity);
-                               gr.Operator = Operator.DestOut;
-                               gr.Rectangle (ClientRectangle);
-                               gr.Fill ();
-                               gr.Operator = Operator.Over;
-                       }
-               }
-               #endregion
-       }
-}
diff --git a/src/GraphicObjects/Label.cs b/src/GraphicObjects/Label.cs
deleted file mode 100644 (file)
index 64ee968..0000000
+++ /dev/null
@@ -1,825 +0,0 @@
-//
-// Label.cs
-//
-// Author:
-//       Jean-Philippe Bruyère <jp.bruyere@hotmail.com>
-//
-// Copyright (c) 2013-2017 Jean-Philippe Bruyère
-//
-// 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.Generic;
-using System.Linq;
-using System.Diagnostics;
-using Cairo;
-using System.Text.RegularExpressions;
-using System.Xml.Serialization;
-using System.ComponentModel;
-
-namespace Crow
-{
-    public class Label : GraphicObject
-    {
-               #region CTOR
-               public Label()
-               {
-
-               }
-               public Label(string _text)
-                       : base()
-               {
-                       Text = _text;
-               }
-               #endregion
-
-               public event EventHandler<TextChangeEventArgs> TextChanged;
-
-               public virtual void OnTextChanged(Object sender, TextChangeEventArgs e)
-               {
-                       NotifyValueChanged ("Text", Text);
-                       TextChanged.Raise (this, e);
-               }
-        //TODO:change protected to private
-
-               #region private and protected fields
-               string _text = "label";
-        Alignment _textAlignment;
-               bool horizontalStretch;
-               bool verticalStretch;
-               bool _selectable;
-               bool _multiline;
-               Color selBackground;
-               Color selForeground;
-               Point mouseLocalPos = -1;//mouse coord in widget space, filled only when clicked
-               int _currentCol;        //0 based cursor position in string
-               int _currentLine;
-               Point _selBegin = -1;   //selection start (row,column)
-               Point _selRelease = -1; //selection end (row,column)
-               double textCursorPos;   //cursor position in cairo units in widget client coord.
-               double SelStartCursorPos = -1;
-               double SelEndCursorPos = -1;
-               bool SelectionInProgress = false;
-
-        protected Rectangle rText;
-               protected float widthRatio = 1f;
-               protected float heightRatio = 1f;
-               protected FontExtents fe;
-               protected TextExtents te;
-               #endregion
-
-               [XmlAttributeAttribute][DefaultValue("BlueGray")]
-               public virtual Color SelectionBackground {
-                       get { return selBackground; }
-                       set {
-                               if (value == selBackground)
-                                       return;
-                               selBackground = value;
-                               NotifyValueChanged ("SelectionBackground", selBackground);
-                               RegisterForRedraw ();
-                       }
-               }
-               [XmlAttributeAttribute][DefaultValue("White")]
-               public virtual Color SelectionForeground {
-                       get { return selForeground; }
-                       set {
-                               if (value == selForeground)
-                                       return;
-                               selForeground = value;
-                               NotifyValueChanged ("SelectionForeground", selForeground);
-                               RegisterForRedraw ();
-                       }
-               }
-               [XmlAttributeAttribute][DefaultValue(Alignment.Left)]
-               public Alignment TextAlignment
-        {
-            get { return _textAlignment; }
-            set {
-                               if (value == _textAlignment)
-                                       return;
-                               _textAlignment = value;
-                               RegisterForRedraw ();
-                               NotifyValueChanged ("TextAlignment", _textAlignment);
-                       }
-        }
-               [XmlAttributeAttribute][DefaultValue(false)]
-               public virtual bool HorizontalStretch {
-                       get { return horizontalStretch; }
-                       set {
-                               if (horizontalStretch == value)
-                                       return;
-                               horizontalStretch = value;
-                               RegisterForRedraw ();
-                               NotifyValueChanged ("HorizontalStretch", horizontalStretch);
-                       }
-               }
-               [XmlAttributeAttribute][DefaultValue(false)]
-               public virtual bool VerticalStretch {
-                       get { return verticalStretch; }
-                       set {
-                               if (verticalStretch == value)
-                                       return;
-                               verticalStretch = value;
-                               RegisterForRedraw ();
-                               NotifyValueChanged ("VerticalStretch", verticalStretch);
-                       }
-               }
-               [XmlAttributeAttribute][DefaultValue("label")]
-        public string Text
-        {
-            get {
-                               return lines == null ?
-                                       _text : lines.Aggregate((i, j) => i + Interface.LineBreak + j);
-                       }
-            set
-            {
-                               if (string.Equals (value, _text, StringComparison.Ordinal))
-                    return;
-
-                _text = value;
-
-                               if (string.IsNullOrEmpty(_text))
-                                       _text = "";
-
-                               lines = getLines;
-
-                               OnTextChanged (this, new TextChangeEventArgs (Text));
-                               RegisterForGraphicUpdate ();
-            }
-        }
-               [XmlAttributeAttribute][DefaultValue(false)]
-               public bool Selectable
-               {
-                       get { return _selectable; }
-                       set
-                       {
-                               if (value == _selectable)
-                                       return;
-                               _selectable = value;
-                               NotifyValueChanged ("Selectable", _selectable);
-                               SelBegin = -1;
-                               SelRelease = -1;
-                               RegisterForRedraw ();
-                       }
-               }
-               [XmlAttributeAttribute][DefaultValue(false)]
-               public bool Multiline
-               {
-                       get { return _multiline; }
-                       set
-                       {
-                               if (value == _multiline)
-                                       return;
-                               _multiline = value;
-                               NotifyValueChanged ("Multiline", _multiline);
-                               RegisterForGraphicUpdate();
-                       }
-               }
-               [XmlAttributeAttribute][DefaultValue(0)]
-               public int CurrentColumn{
-                       get { return _currentCol; }
-                       set {
-                               if (value == _currentCol)
-                                       return;
-                               if (value < 0)
-                                       _currentCol = 0;
-                               else if (value > lines [_currentLine].Length)
-                                       _currentCol = lines [_currentLine].Length;
-                               else
-                                       _currentCol = value;
-                               NotifyValueChanged ("CurrentColumn", _currentCol);
-                       }
-               }
-               [XmlAttributeAttribute][DefaultValue(0)]
-               public int CurrentLine{
-                       get { return _currentLine; }
-                       set {
-                               if (value == _currentLine)
-                                       return;
-                               if (value >= lines.Count)
-                                       _currentLine = lines.Count-1;
-                               else if (value < 0)
-                                       _currentLine = 0;
-                               else
-                                       _currentLine = value;
-                               //force recheck of currentCol for bounding
-                               int cc = _currentCol;
-                               _currentCol = 0;
-                               CurrentColumn = cc;
-                               NotifyValueChanged ("CurrentLine", _currentLine);
-                       }
-               }
-               [XmlIgnore]public Point CurrentPosition {
-                       get { return new Point(_currentCol, CurrentLine); }
-               }
-               //TODO:using HasFocus for drawing selection cause SelBegin and Release binding not to work
-               /// <summary>
-               /// Selection begin position in char units
-               /// </summary>
-               [XmlAttributeAttribute][DefaultValue("-1")]
-               public Point SelBegin {
-                       get {
-                               return _selBegin;
-                       }
-                       set {
-                               if (value == _selBegin)
-                                       return;
-                               _selBegin = value;
-                               NotifyValueChanged ("SelBegin", _selBegin);
-                               NotifyValueChanged ("SelectedText", SelectedText);
-                       }
-               }
-               [XmlAttributeAttribute][DefaultValue("-1")]
-               public Point SelRelease {
-                       get {
-                               return _selRelease;
-                       }
-                       set {
-                               if (value == _selRelease)
-                                       return;
-                               _selRelease = value;
-                               NotifyValueChanged ("SelRelease", _selRelease);
-                               NotifyValueChanged ("SelectedText", SelectedText);
-                       }
-               }
-               /// <summary>
-               /// return char at CurrentLine, CurrentColumn
-               /// </summary>
-               [XmlIgnore]protected Char CurrentChar
-               {
-                       get {
-                               return lines [CurrentLine] [CurrentColumn];
-                       }
-               }
-               /// <summary>
-               /// ordered selection start and end positions in char units
-               /// </summary>
-               [XmlIgnore]protected Point selectionStart
-               {
-                       get {
-                               return SelRelease < 0 || SelBegin.Y < SelRelease.Y ? SelBegin :
-                                       SelBegin.Y > SelRelease.Y ? SelRelease :
-                                       SelBegin.X < SelRelease.X ? SelBegin : SelRelease;
-                       }
-               }
-               [XmlIgnore]public Point selectionEnd
-               {
-                       get {
-                               return SelRelease < 0 || SelBegin.Y > SelRelease.Y ? SelBegin :
-                                       SelBegin.Y < SelRelease.Y ? SelRelease :
-                                       SelBegin.X > SelRelease.X ? SelBegin : SelRelease;
-                       }
-               }
-               [XmlIgnore]public string SelectedText
-               {
-                       get {
-
-                               if (SelRelease < 0 || SelBegin < 0)
-                                       return "";
-                               if (selectionStart.Y == selectionEnd.Y)
-                                       return lines [selectionStart.Y].Substring (selectionStart.X, selectionEnd.X - selectionStart.X);
-                               string tmp = "";
-                               tmp = lines [selectionStart.Y].Substring (selectionStart.X);
-                               for (int l = selectionStart.Y + 1; l < selectionEnd.Y; l++) {
-                                       tmp += Interface.LineBreak + lines [l];
-                               }
-                               tmp += Interface.LineBreak + lines [selectionEnd.Y].Substring (0, selectionEnd.X);
-                               return tmp;
-                       }
-               }
-               [XmlIgnore]public bool selectionIsEmpty
-               { get { return SelRelease < 0; } }
-
-               List<string> lines;
-               List<string> getLines {
-                       get {
-                               return _multiline ?
-                                       Regex.Split (_text, "\r\n|\r|\n|\\\\n").ToList() :
-                                       new List<string>(new string[] { _text });
-                       }
-               }
-               /// <summary>
-               /// Moves cursor one char to the left.
-               /// </summary>
-               /// <returns><c>true</c> if move succeed</returns>
-               public bool MoveLeft(){
-                       int tmp = _currentCol - 1;
-                       if (tmp < 0) {
-                               if (_currentLine == 0)
-                                       return false;
-                               CurrentLine--;
-                               CurrentColumn = int.MaxValue;
-                       } else
-                               CurrentColumn = tmp;
-                       return true;
-               }
-               /// <summary>
-               /// Moves cursor one char to the right.
-               /// </summary>
-               /// <returns><c>true</c> if move succeed</returns>
-               public bool MoveRight(){
-                       int tmp = _currentCol + 1;
-                       if (tmp > lines [_currentLine].Length){
-                               if (CurrentLine == lines.Count - 1)
-                                       return false;
-                               CurrentLine++;
-                               CurrentColumn = 0;
-                       } else
-                               CurrentColumn = tmp;
-                       return true;
-               }
-               public void GotoWordStart(){
-                       CurrentColumn--;
-                       //skip white spaces
-                       while (!char.IsLetterOrDigit (this.CurrentChar) && CurrentColumn > 0)
-                               CurrentColumn--;
-                       while (char.IsLetterOrDigit (lines [CurrentLine] [CurrentColumn]) && CurrentColumn > 0)
-                               CurrentColumn--;
-                       if (!char.IsLetterOrDigit (this.CurrentChar))
-                               CurrentColumn++;
-               }
-               public void GotoWordEnd(){
-                       //skip white spaces
-                       if (CurrentColumn >= lines [CurrentLine].Length - 1)
-                               return;
-                       while (!char.IsLetterOrDigit (this.CurrentChar) && CurrentColumn < lines [CurrentLine].Length-1)
-                               CurrentColumn++;
-                       while (char.IsLetterOrDigit (this.CurrentChar) && CurrentColumn < lines [CurrentLine].Length-1)
-                               CurrentColumn++;
-                       if (char.IsLetterOrDigit (this.CurrentChar))
-                               CurrentColumn++;
-               }
-               public void DeleteChar()
-               {
-                       if (selectionIsEmpty) {
-                               if (CurrentColumn == 0) {
-                                       if (CurrentLine == 0 && lines.Count == 1)
-                                               return;
-                                       CurrentLine--;
-                                       CurrentColumn = lines [CurrentLine].Length;
-                                       lines [CurrentLine] += lines [CurrentLine + 1];
-                                       lines.RemoveAt (CurrentLine + 1);
-
-                                       OnTextChanged (this, new TextChangeEventArgs (Text));
-                                       return;
-                               }
-                               CurrentColumn--;
-                               lines [CurrentLine] = lines [CurrentLine].Remove (CurrentColumn, 1);
-                       } else {
-                               int linesToRemove = selectionEnd.Y - selectionStart.Y + 1;
-                               int l = selectionStart.Y;
-
-                               if (linesToRemove > 0) {
-                                       lines [l] = lines [l].Remove (selectionStart.X, lines [l].Length - selectionStart.X) +
-                                               lines [selectionEnd.Y].Substring (selectionEnd.X, lines [selectionEnd.Y].Length - selectionEnd.X);
-                                       l++;
-                                       for (int c = 0; c < linesToRemove-1; c++)
-                                               lines.RemoveAt (l);
-                                       CurrentLine = selectionStart.Y;
-                                       CurrentColumn = selectionStart.X;
-                               } else
-                                       lines [l] = lines [l].Remove (selectionStart.X, selectionEnd.X - selectionStart.X);
-                               CurrentColumn = selectionStart.X;
-                               SelBegin = -1;
-                               SelRelease = -1;
-                       }
-                       OnTextChanged (this, new TextChangeEventArgs (Text));
-               }
-               /// <summary>
-               /// Insert new string at caret position, should be sure no line break is inside.
-               /// </summary>
-               /// <param name="str">String.</param>
-               protected void Insert(string str)
-               {
-                       if (!selectionIsEmpty)
-                               this.DeleteChar ();
-                       if (_multiline) {
-                               string[] strLines = Regex.Split (str, "\r\n|\r|\n|" + @"\\n").ToArray();
-                               lines [CurrentLine] = lines [CurrentLine].Insert (CurrentColumn, strLines[0]);
-                               CurrentColumn += strLines[0].Length;
-                               for (int i = 1; i < strLines.Length; i++) {
-                                       InsertLineBreak ();
-                                       lines [CurrentLine] = lines [CurrentLine].Insert (CurrentColumn, strLines[i]);
-                                       CurrentColumn += strLines[i].Length;
-                               }
-                       } else {
-                               lines [CurrentLine] = lines [CurrentLine].Insert (CurrentColumn, str);
-                               CurrentColumn += str.Length;
-                       }
-                       OnTextChanged (this, new TextChangeEventArgs (Text));
-               }
-               /// <summary>
-               /// Insert a line break.
-               /// </summary>
-               protected void InsertLineBreak()
-               {
-                       lines.Insert(CurrentLine + 1, lines[CurrentLine].Substring(CurrentColumn));
-                       lines [CurrentLine] = lines [CurrentLine].Substring (0, CurrentColumn);
-                       CurrentLine++;
-                       CurrentColumn = 0;
-                       OnTextChanged (this, new TextChangeEventArgs (Text));
-               }
-
-               #region GraphicObject overrides
-               protected override int measureRawSize(LayoutingType lt)
-        {
-                       if (lines == null)
-                               lines = getLines;
-
-                       using (ImageSurface img = new ImageSurface (Format.Argb32, 10, 10)) {
-                               using (Context gr = new Context (img)) {
-                                       //Cairo.FontFace cf = gr.GetContextFontFace ();
-
-                                       gr.SelectFontFace (Font.Name, Font.Slant, Font.Wheight);
-                                       gr.SetFontSize (Font.Size);
-
-
-                                       fe = gr.FontExtents;
-                                       te = new TextExtents();
-
-                                       if (lt == LayoutingType.Height){
-                                               int lc = lines.Count;
-                                               //ensure minimal height = text line height
-                                               if (lc == 0)
-                                                       lc = 1;
-
-                                               return (int)Math.Ceiling(fe.Height * lc) + Margin * 2;
-                                       }
-                                       try {
-                                               foreach (string s in lines) {
-                                                       string l = s.Replace("\t", new String (' ', Interface.TabSize));
-
-                                                       TextExtents tmp = gr.TextExtents (l);
-
-                                                       if (tmp.XAdvance > te.XAdvance)
-                                                               te = tmp;
-                                               }
-                                       } catch (Exception ex) {
-                                               return -1;
-                                       }
-                                       return (int)Math.Ceiling (te.XAdvance) + Margin * 2;
-                               }
-                       }
-        }
-               protected override void onDraw (Context gr)
-               {
-                       base.onDraw (gr);
-
-                       gr.SelectFontFace (Font.Name, Font.Slant, Font.Wheight);
-                       gr.SetFontSize (Font.Size);
-                       gr.FontOptions = Interface.FontRenderingOptions;
-                       gr.Antialias = Interface.Antialias;
-
-                       rText = new Rectangle(new Size(
-                               measureRawSize(LayoutingType.Width), measureRawSize(LayoutingType.Height)));
-                       rText.Width -= 2 * Margin;
-                       rText.Height -= 2 * Margin;
-
-                       widthRatio = 1f;
-                       heightRatio = 1f;
-
-                       Rectangle cb = ClientRectangle;
-
-                       rText.X = cb.X;
-                       rText.Y = cb.Y;
-
-                       if (horizontalStretch) {
-                               widthRatio = (float)cb.Width / (float)rText.Width;
-                               if (!verticalStretch)
-                                       heightRatio = widthRatio;
-                       }
-
-                       if (verticalStretch) {
-                               heightRatio = (float)cb.Height / (float)rText.Height;
-                               if (!horizontalStretch)
-                                       widthRatio = heightRatio;
-                       }
-
-                       rText.Width = (int)(widthRatio * (float)rText.Width);
-                       rText.Height = (int)(heightRatio * (float)rText.Height);
-
-                       switch (TextAlignment)
-                       {
-                       case Alignment.TopLeft:     //ok
-                               rText.X = cb.X;
-                               rText.Y = cb.Y;
-                               break;
-                       case Alignment.Top:   //ok
-                               rText.Y = cb.Y;
-                               rText.X = cb.X + cb.Width / 2 - rText.Width / 2;
-                               break;
-                       case Alignment.TopRight:    //ok
-                               rText.Y = cb.Y;
-                               rText.X = cb.Right - rText.Width;
-                               break;
-                       case Alignment.Left://ok
-                               rText.X = cb.X;
-                               rText.Y = cb.Y + cb.Height / 2 - rText.Height / 2;
-                               break;
-                       case Alignment.Right://ok
-                               rText.X = cb.X + cb.Width - rText.Width;
-                               rText.Y = cb.Y + cb.Height / 2 - rText.Height / 2;
-                               break;
-                       case Alignment.Bottom://ok
-                               rText.X = cb.Width / 2 - rText.Width / 2;
-                               rText.Y = cb.Height - rText.Height;
-                               break;
-                       case Alignment.BottomLeft://ok
-                               rText.X = cb.X;
-                               rText.Y = cb.Bottom - rText.Height;
-                               break;
-                       case Alignment.BottomRight://ok
-                               rText.Y = cb.Bottom - rText.Height;
-                               rText.X = cb.Right - rText.Width;
-                               break;
-                       case Alignment.Center://ok
-                               rText.X = cb.X + cb.Width / 2 - rText.Width / 2;
-                               rText.Y = cb.Y + cb.Height / 2 - rText.Height / 2;
-                               break;
-                       }
-
-                       gr.FontMatrix = new Matrix(widthRatio * (float)Font.Size, 0, 0, heightRatio * (float)Font.Size, 0, 0);
-                       fe = gr.FontExtents;
-
-                       #region draw text cursor
-                       if (HasFocus && Selectable)
-                       {
-                               if (mouseLocalPos >= 0)
-                               {
-                                       computeTextCursor(gr);
-
-                                       if (SelectionInProgress)
-                                       {
-                                               if (SelBegin < 0){
-                                                       SelBegin = new Point(CurrentColumn, CurrentLine);
-                                                       SelStartCursorPos = textCursorPos;
-                                                       SelRelease = -1;
-                                               }else{
-                                                       SelRelease = new Point(CurrentColumn, CurrentLine);
-                                                       if (SelRelease == SelBegin)
-                                                               SelRelease = -1;
-                                                       else
-                                                               SelEndCursorPos = textCursorPos;
-                                               }
-                                       }else
-                                               computeTextCursorPosition(gr);
-                               }else
-                                       computeTextCursorPosition(gr);
-
-                               Foreground.SetAsSource (gr);
-                               gr.LineWidth = 1.0;
-                               gr.MoveTo (0.5 + textCursorPos + rText.X, rText.Y + CurrentLine * fe.Height);
-                               gr.LineTo (0.5 + textCursorPos + rText.X, rText.Y + (CurrentLine + 1) * fe.Height);
-                               gr.Stroke();
-                       }
-                       #endregion
-
-                       //****** debug selection *************
-//                     if (SelRelease >= 0) {
-//                             new SolidColor(Color.DarkGreen).SetAsSource(gr);
-//                             Rectangle R = new Rectangle (
-//                                                  rText.X + (int)SelEndCursorPos - 3,
-//                                                  rText.Y + (int)(SelRelease.Y * fe.Height),
-//                                                  6,
-//                                                  (int)fe.Height);
-//                             gr.Rectangle (R);
-//                             gr.Fill ();
-//                     }
-//                     if (SelBegin >= 0) {
-//                             new SolidColor(Color.DarkRed).SetAsSource(gr);
-//                             Rectangle R = new Rectangle (
-//                                     rText.X + (int)SelStartCursorPos - 3,
-//                                     rText.Y + (int)(SelBegin.Y * fe.Height),
-//                                     6,
-//                                     (int)fe.Height);
-//                             gr.Rectangle (R);
-//                             gr.Fill ();
-//                     }
-                       //*******************
-
-                       for (int i = 0; i < lines.Count; i++) {
-                               string l = lines [i].Replace ("\t", new String (' ', Interface.TabSize));
-                               int lineLength = (int)gr.TextExtents (l).XAdvance;
-                               Rectangle lineRect = new Rectangle (
-                                       rText.X,
-                                       rText.Y + (int)Math.Ceiling(i * fe.Height),
-                                       lineLength,
-                                       (int)Math.Ceiling(fe.Height));
-
-//                             if (TextAlignment == Alignment.Center ||
-//                                     TextAlignment == Alignment.Top ||
-//                                     TextAlignment == Alignment.Bottom)
-//                                     lineRect.X += (rText.Width - lineLength) / 2;
-//                             else if (TextAlignment == Alignment.Right ||
-//                                     TextAlignment == Alignment.TopRight ||
-//                                     TextAlignment == Alignment.BottomRight)
-//                                     lineRect.X += (rText.Width - lineLength);
-                               if (string.IsNullOrWhiteSpace (l))
-                                       continue;
-
-                               Foreground.SetAsSource (gr);
-                               gr.MoveTo (lineRect.X, rText.Y + fe.Ascent + fe.Height * i);
-                               gr.ShowText (l);
-                               gr.Fill ();
-
-                               if (Selectable) {
-                                       if (SelRelease >= 0 && i >= selectionStart.Y && i <= selectionEnd.Y) {
-                                               gr.SetSourceColor (selBackground);
-
-                                               Rectangle selRect = lineRect;
-
-                                               int cpStart = (int)SelStartCursorPos,
-                                               cpEnd = (int)SelEndCursorPos;
-
-                                               if (SelBegin.Y > SelRelease.Y) {
-                                                       cpStart = cpEnd;
-                                                       cpEnd = (int)SelStartCursorPos;
-                                               }
-
-                                               if (i == selectionStart.Y) {
-                                                       selRect.Width -= cpStart;
-                                                       selRect.Left += cpStart;
-                                               }
-                                               if (i == selectionEnd.Y)
-                                                       selRect.Width -= (lineLength - cpEnd);
-
-                                               gr.Rectangle (selRect);
-                                               gr.FillPreserve ();
-                                               gr.Save ();
-                                               gr.Clip ();
-                                               gr.SetSourceColor (SelectionForeground);
-                                               gr.MoveTo (lineRect.X, rText.Y + fe.Ascent + fe.Height * i);
-                                               gr.ShowText (l);
-                                               gr.Fill ();
-                                               gr.Restore ();
-                                       }
-                               }
-                       }
-               }
-               #endregion
-
-               #region Mouse handling
-               void updatemouseLocalPos(Point mpos){
-                       mouseLocalPos = mpos - ScreenCoordinates(Slot).TopLeft - ClientRectangle.TopLeft;
-                       if (mouseLocalPos.X < 0)
-                               mouseLocalPos.X = 0;
-                       if (mouseLocalPos.Y < 0)
-                               mouseLocalPos.Y = 0;
-               }
-               public override void onMouseEnter (object sender, MouseMoveEventArgs e)
-               {
-                       base.onMouseEnter (sender, e);
-                       if (Selectable)
-                               CurrentInterface.MouseCursor = XCursor.Text;
-               }
-               public override void onMouseLeave (object sender, MouseMoveEventArgs e)
-               {
-                       base.onMouseLeave (sender, e);
-                       CurrentInterface.MouseCursor = XCursor.Default;
-               }
-               protected override void onFocused (object sender, EventArgs e)
-               {
-                       base.onFocused (sender, e);
-
-                       if (!_selectable)
-                               return;
-                       SelBegin = new Point(0,0);
-                       SelRelease = new Point (lines.LastOrDefault ().Length, lines.Count-1);
-                       RegisterForRedraw ();
-               }
-               protected override void onUnfocused (object sender, EventArgs e)
-               {
-                       base.onUnfocused (sender, e);
-
-                       SelBegin = -1;
-                       SelRelease = -1;
-                       RegisterForRedraw ();
-               }
-               public override void onMouseMove (object sender, MouseMoveEventArgs e)
-               {
-                       base.onMouseMove (sender, e);
-
-                       if (!(SelectionInProgress && HasFocus && _selectable))
-                               return;
-
-                       updatemouseLocalPos (e.Position);
-
-                       RegisterForRedraw();
-               }
-               public override void onMouseDown (object sender, MouseButtonEventArgs e)
-               {
-                       if (this.HasFocus && _selectable){
-                               updatemouseLocalPos (e.Position);
-                               SelBegin = -1;
-                               SelRelease = -1;
-                               SelectionInProgress = true;
-                               RegisterForRedraw();//TODO:should put it in properties
-                       }
-
-                       //done at the end to set 'hasFocus' value after testing it
-                       base.onMouseDown (sender, e);
-               }
-               public override void onMouseUp (object sender, MouseButtonEventArgs e)
-               {
-                       base.onMouseUp (sender, e);
-
-                       if (!SelectionInProgress)
-                               return;
-
-                       updatemouseLocalPos (e.Position);
-                       SelectionInProgress = false;
-                       RegisterForRedraw ();
-               }
-               public override void onMouseDoubleClick (object sender, MouseButtonEventArgs e)
-               {
-                       base.onMouseDoubleClick (sender, e);
-
-                       GotoWordStart ();
-                       SelBegin = CurrentPosition;
-                       GotoWordEnd ();
-                       SelRelease = CurrentPosition;
-                       SelectionInProgress = false;
-                       RegisterForRedraw ();
-               }
-               #endregion
-
-               /// <summary>
-               /// Update Current Column, line and TextCursorPos
-               /// from mouseLocalPos
-               /// </summary>
-               void computeTextCursor(Context gr)
-               {
-                       TextExtents te;
-
-                       double cPos = 0f;
-
-                       CurrentLine = (int)(mouseLocalPos.Y / fe.Height);
-
-                       //fix cu
-                       if (CurrentLine >= lines.Count)
-                               CurrentLine = lines.Count - 1;
-
-                       for (int i = 0; i < lines[CurrentLine].Length; i++)
-                       {
-                               string c = lines [CurrentLine].Substring (i, 1);
-                               if (c == "\t")
-                                       c = new string (' ', Interface.TabSize);
-
-                               te = gr.TextExtents(c);
-
-                               double halfWidth = te.XAdvance / 2;
-
-                               if (mouseLocalPos.X <= cPos + halfWidth)
-                               {
-                                       CurrentColumn = i;
-                                       textCursorPos = cPos;
-                                       mouseLocalPos = -1;
-                                       return;
-                               }
-
-                               cPos += te.XAdvance;
-                       }
-                       CurrentColumn = lines[CurrentLine].Length;
-                       textCursorPos = cPos;
-
-                       //reset mouseLocalPos
-                       mouseLocalPos = -1;
-               }
-               /// <summary> Computes offsets in cairo units </summary>
-               void computeTextCursorPosition(Context gr)
-               {
-                       if (SelBegin >= 0)
-                               SelStartCursorPos = GetXFromTextPointer (gr, SelBegin);
-                       if (SelRelease >= 0)
-                               SelEndCursorPos = GetXFromTextPointer (gr, SelRelease);
-                       textCursorPos = GetXFromTextPointer (gr, new Point(CurrentColumn, CurrentLine));
-               }
-               /// <summary> Compute x offset in cairo unit from text position </summary>
-               double GetXFromTextPointer(Context gr, Point pos)
-               {
-                       try {
-                               string l = lines [pos.Y].Substring (0, pos.X).
-                                       Replace ("\t", new String (' ', Interface.TabSize));
-                               return gr.TextExtents (l).XAdvance;
-                       } catch{
-                               return -1;
-                       }
-               }
-    }
-}
diff --git a/src/GraphicObjects/ListBox.cs b/src/GraphicObjects/ListBox.cs
deleted file mode 100644 (file)
index f66edf6..0000000
+++ /dev/null
@@ -1,47 +0,0 @@
-//
-// ListBox.cs
-//
-// Author:
-//       Jean-Philippe Bruyère <jp.bruyere@hotmail.com>
-//
-// Copyright (c) 2013-2017 Jean-Philippe Bruyère
-//
-// 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.Xml.Serialization;
-using System.ComponentModel;
-using System.IO;
-using System.Diagnostics;
-using System.Xml;
-using System.Collections.Generic;
-using System.Threading;
-
-namespace Crow
-{
-       public class ListBox : TemplatedGroup
-       {
-               #region CTOR
-               public ListBox () : base() {}
-               #endregion
-
-       }
-}
-
diff --git a/src/GraphicObjects/Menu.cs b/src/GraphicObjects/Menu.cs
deleted file mode 100644 (file)
index 5049481..0000000
+++ /dev/null
@@ -1,76 +0,0 @@
-//
-// Menu.cs
-//
-// Author:
-//       Jean-Philippe Bruyère <jp.bruyere@hotmail.com>
-//
-// Copyright (c) 2013-2017 Jean-Philippe Bruyère
-//
-// 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.Xml.Serialization;
-using System.ComponentModel;
-
-namespace Crow
-{
-       public class Menu : TemplatedGroup
-       {
-               #region CTOR
-               public Menu () : base() {}
-               #endregion
-
-               Orientation orientation;
-               bool autoOpen = false;
-
-               #region Public properties
-               [XmlAttributeAttribute][DefaultValue(Orientation.Horizontal)]
-               public Orientation Orientation {
-                       get { return orientation; }
-                       set {
-                               if (orientation == value)
-                                       return;
-                               orientation = value;
-                               NotifyValueChanged ("Orientation", orientation);
-                       }
-               }
-               [XmlIgnore]public bool AutomaticOpenning
-               {
-                       get { return autoOpen; }
-                       set     { autoOpen = value;     }
-               }
-               #endregion
-
-               public override void AddItem (GraphicObject g)
-               {                       
-                       base.AddItem (g);
-
-                       if (orientation == Orientation.Horizontal)
-                               g.NotifyValueChanged ("PopDirection", Alignment.Bottom);
-                       else
-                               g.NotifyValueChanged ("PopDirection", Alignment.Right);
-               }
-               public override void onMouseLeave (object sender, MouseMoveEventArgs e)
-               {
-                       base.onMouseLeave (sender, e);
-                       AutomaticOpenning = false;
-               }
-       }
-}
-
diff --git a/src/GraphicObjects/MenuItem.cs b/src/GraphicObjects/MenuItem.cs
deleted file mode 100644 (file)
index 0d99a2e..0000000
+++ /dev/null
@@ -1,174 +0,0 @@
-//
-// MenuItem.cs
-//
-// Author:
-//       Jean-Philippe Bruyère <jp.bruyere@hotmail.com>
-//
-// Copyright (c) 2013-2017 Jean-Philippe Bruyère
-//
-// 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.Xml.Serialization;
-using System.ComponentModel;
-
-namespace Crow
-{
-       public class MenuItem : Menu
-       {
-               #region CTOR
-               public MenuItem () : base() {}
-               #endregion
-
-               public event EventHandler Open;
-               public event EventHandler Close;
-
-               string caption;
-               Command command;
-               Picture icon;
-               bool isOpened;
-               Measure popWidth, popHeight;
-
-               #region Public properties
-               [XmlAttributeAttribute][DefaultValue(false)]
-               public bool IsOpened {
-                       get { return isOpened; }
-                       set {
-                               if (isOpened == value)
-                                       return;
-                               isOpened = value;
-                               NotifyValueChanged ("IsOpened", isOpened);
-
-                               if (isOpened) {
-                                       onOpen (this, null);
-                                       (LogicalParent as Menu).AutomaticOpenning = true;
-                               }else
-                                       onClose (this, null);
-                       }
-               }
-               [XmlAttributeAttribute][DefaultValue(null)]
-               public virtual Command Command {
-                       get { return command; }
-                       set {
-                               if (command == value)
-                                       return;
-
-                               if (command != null) {
-                                       command.raiseAllValuesChanged ();
-                                       command.ValueChanged -= Command_ValueChanged;
-                               }
-
-                               command = value;
-
-                               if (command != null) {
-                                       command.ValueChanged += Command_ValueChanged;
-                                       command.raiseAllValuesChanged ();
-                               }
-
-                               NotifyValueChanged ("Command", command);
-                       }
-               }
-               [XmlAttributeAttribute]
-               public override bool IsEnabled {
-                       get { return Command == null ? base.IsEnabled : Command.CanExecute; }
-                       set { base.IsEnabled = value; }
-               }
-               [XmlAttributeAttribute]
-               public override string Caption {
-                       get { return Command == null ? base.Caption : Command.Caption; }
-                       set { base.Caption = value; }
-               }
-               [XmlAttributeAttribute]
-               public Picture Icon {
-                       get { return Command == null ? icon : Command.Icon;; }
-                       set {
-                               if (icon == value)
-                                       return;
-                               icon = value;
-                               if (command == null)
-                                       NotifyValueChanged ("Icon", icon);
-                       }
-               }
-               [XmlAttributeAttribute()][DefaultValue("Fit")]
-               public virtual Measure PopWidth {
-                       get { return popWidth; }
-                       set {
-                               if (popWidth == value)
-                                       return;
-                               popWidth = value;
-                               NotifyValueChanged ("PopWidth", popWidth);
-                       }
-               }
-               [XmlAttributeAttribute()][DefaultValue("Fit")]
-               public virtual Measure PopHeight {
-                       get { return popHeight; }
-                       set {
-                               if (popHeight == value)
-                                       return;
-                               popHeight = value;
-                               NotifyValueChanged ("PopHeight", popHeight);
-                       }
-               }
-               #endregion
-
-               public override void AddItem (GraphicObject g)
-               {
-                       base.AddItem (g);
-                       g.NotifyValueChanged ("PopDirection", Alignment.Right);
-               }
-
-               void Command_ValueChanged (object sender, ValueChangeEventArgs e)
-               {
-                       string mName = e.MemberName;
-                       if (mName == "CanExecute")
-                               mName = "IsEnabled";
-                       NotifyValueChanged (mName, e.NewValue);
-               }
-               void onMI_Click (object sender, MouseButtonEventArgs e)
-               {
-                       if (command != null)
-                               command.Execute ();
-                       if(!IsOpened)
-                               (LogicalParent as Menu).AutomaticOpenning = false;
-               }
-               protected virtual void onOpen (object sender, EventArgs e){
-                       Open.Raise (this, null);
-               }
-               protected virtual void onClose (object sender, EventArgs e){
-                       Close.Raise (this, null);
-               }
-               public override bool MouseIsIn (Point m)
-               {
-                       return IsEnabled ? base.MouseIsIn (m) || child.MouseIsIn (m) : false;
-               }
-               public override void onMouseEnter (object sender, MouseMoveEventArgs e)
-               {
-                       base.onMouseEnter (sender, e);
-                       if ((LogicalParent as Menu).AutomaticOpenning && items.Children.Count>0)
-                               IsOpened = true;
-               }
-               public override void onMouseLeave (object sender, MouseMoveEventArgs e)
-               {
-                       if (IsOpened)
-                               IsOpened = false;
-                       base.onMouseLeave (this, e);
-               }
-       }
-}
-
diff --git a/src/GraphicObjects/MessageBox.cs b/src/GraphicObjects/MessageBox.cs
deleted file mode 100644 (file)
index d8ce1da..0000000
+++ /dev/null
@@ -1,150 +0,0 @@
-//
-// MessageBox.cs
-//
-// Author:
-//       Jean-Philippe Bruyère <jp.bruyere@hotmail.com>
-//
-// Copyright (c) 2013-2017 Jean-Philippe Bruyère
-//
-// 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.Xml.Serialization;
-using System.ComponentModel;
-
-namespace Crow
-{
-       public class MessageBox : Window
-       {
-               public enum Type {
-                       Information,
-                       YesNo,
-                       Alert,
-                       Error
-               }
-               public MessageBox (): base(){}
-
-               protected override void loadTemplate (GraphicObject template)
-               {
-                       base.loadTemplate (template);
-                       NotifyValueChanged ("MsgIcon", "#Crow.Images.Icons.Informations.svg");
-               }
-               string message, okMessage, cancelMessage;
-               Type msgType = Type.Information;
-
-               public event EventHandler Ok;
-               public event EventHandler Cancel;
-
-               [XmlAttributeAttribute][DefaultValue("Informations")]
-               public virtual string Message
-               {
-                       get { return message; }
-                       set {
-                               if (message == value)
-                                       return;
-                               message = value;
-                               NotifyValueChanged ("Message", message);
-                       }
-               }
-               [XmlAttributeAttribute][DefaultValue("Ok")]
-               public virtual string OkMessage
-               {
-                       get { return okMessage; }
-                       set {
-                               if (okMessage == value)
-                                       return;
-                               okMessage = value;
-                               NotifyValueChanged ("OkMessage", okMessage);
-                       }
-               }
-               [XmlAttributeAttribute][DefaultValue("Cancel")]
-               public virtual string CancelMessage
-               {
-                       get { return cancelMessage; }
-                       set {
-                               if (cancelMessage == value)
-                                       return;
-                               cancelMessage = value;
-                               NotifyValueChanged ("CancelMessage", cancelMessage);
-                       }
-               }
-               [XmlAttributeAttribute][DefaultValue("Information")]
-               public virtual Type MsgType
-               {
-                       get { return msgType; }
-                       set {
-                               if (msgType == value)
-                                       return;
-                               msgType = value;
-                               NotifyValueChanged ("MsgType", msgType);
-                               switch (msgType) {
-                               case Type.Information:
-                                       NotifyValueChanged ("MsgIcon", "#Crow.Images.Icons.Informations.svg");
-                                       Caption = "Informations";
-                                       OkMessage = "Ok";
-                                       CancelMessage = "Cancel";
-                                       break;
-                               case Type.YesNo:
-                                       NotifyValueChanged ("MsgIcon", "#Crow.Icons.question.svg");
-                                       Caption = "Choice";
-                                       OkMessage = "Yes";
-                                       CancelMessage = "No";
-                                       break;
-                               case Type.Alert:
-                                       NotifyValueChanged ("MsgIcon", "#Crow.Images.Icons.IconAlerte.svg");
-                                       Caption = "Alert";
-                                       OkMessage = "Ok";
-                                       CancelMessage = "Cancel";
-                                       break;
-                               case Type.Error:
-                                       NotifyValueChanged ("MsgIcon", "#Crow.Images.Icons.exit.svg");
-                                       Caption = "Error";
-                                       OkMessage = "Ok";
-                                       CancelMessage = "Cancel";
-                                       break;
-                               }
-                       }
-               }
-               void onOkButtonClick (object sender, EventArgs e)
-               {
-                       Ok.Raise (this, null);
-                       close ();
-               }
-               void onCancelButtonClick (object sender, EventArgs e)
-               {
-                       Cancel.Raise (this, null);
-                       close ();
-               }
-               public static MessageBox Show (Type msgBoxType, string message, string okMsg = "", string cancelMsg = ""){
-                       lock (Interface.CurrentInterface.UpdateMutex) {
-                               MessageBox mb = new MessageBox ();
-                               mb.Initialize ();
-                               mb.CurrentInterface.AddWidget (mb);
-                               mb.MsgType = msgBoxType;
-                               mb.Message = message;
-                               if (!string.IsNullOrEmpty(okMsg))
-                                       mb.OkMessage = okMsg;
-                               if (!string.IsNullOrEmpty(cancelMsg))
-                                       mb.CancelMessage = cancelMsg;
-                               return mb;
-                       }
-               }
-       }
-}
-
diff --git a/src/GraphicObjects/NumericControl.cs b/src/GraphicObjects/NumericControl.cs
deleted file mode 100644 (file)
index 9b51183..0000000
+++ /dev/null
@@ -1,125 +0,0 @@
-//
-// NumericControl.cs
-//
-// Author:
-//       Jean-Philippe Bruyère <jp.bruyere@hotmail.com>
-//
-// Copyright (c) 2013-2017 Jean-Philippe Bruyère
-//
-// 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.Xml.Serialization;
-using System.ComponentModel;
-
-namespace Crow
-{
-       public abstract class NumericControl : TemplatedControl
-       {
-               #region CTOR
-               public NumericControl () : base()
-               {
-               }
-               public NumericControl(double minimum, double maximum, double step)
-                       : base()
-               {
-               }
-               #endregion
-
-               #region private fields
-               double _actualValue, minValue, maxValue, smallStep, bigStep;
-               #endregion
-
-               #region public properties
-               [XmlAttributeAttribute()][DefaultValue(0.0)]
-               public virtual double Minimum {
-                       get { return minValue; }
-                       set {
-                               if (minValue == value)
-                                       return;
-
-                               minValue = value;
-                               NotifyValueChanged ("Minimum", minValue);
-                               RegisterForRedraw ();
-                       }
-               }
-               [XmlAttributeAttribute()][DefaultValue(100.0)]
-               public virtual double Maximum
-               {
-                       get { return maxValue; }
-                       set {
-                               if (maxValue == value)
-                                       return;
-
-                               maxValue = value;
-                               NotifyValueChanged ("Maximum", maxValue);
-                               RegisterForRedraw ();
-                       }
-               }
-               [XmlAttributeAttribute()][DefaultValue(1.0)]
-               public virtual double SmallIncrement
-               {
-                       get { return smallStep; }
-                       set {
-                               if (smallStep == value)
-                                       return;
-
-                               smallStep = value;
-                               NotifyValueChanged ("SmallIncrement", smallStep);
-                               RegisterForRedraw ();
-                       }
-               }
-               [XmlAttributeAttribute()][DefaultValue(5.0)]
-               public virtual double LargeIncrement
-               {
-                       get { return bigStep; }
-                       set {
-                               if (bigStep == value)
-                                       return;
-
-                               bigStep = value;
-                               NotifyValueChanged ("LargeIncrement", bigStep);
-                               RegisterForRedraw ();
-                       }
-               }
-               [XmlAttributeAttribute()][DefaultValue(0.0)]
-               public double Value
-               {
-                       get { return _actualValue; }
-                       set
-                       {
-                               if (value == _actualValue)
-                                       return;
-
-                               if (value < minValue)
-                                       _actualValue = minValue;
-                               else if (value > maxValue)
-                                       _actualValue = maxValue;
-                               else                    
-                                       _actualValue = value;
-
-                               NotifyValueChanged("Value",  _actualValue);
-                               RegisterForGraphicUpdate();
-                       }
-               }
-               #endregion
-
-       }
-}
-
diff --git a/src/GraphicObjects/Popper.cs b/src/GraphicObjects/Popper.cs
deleted file mode 100644 (file)
index d3f2e7c..0000000
+++ /dev/null
@@ -1,245 +0,0 @@
-//
-// Popper.cs
-//
-// Author:
-//       Jean-Philippe Bruyère <jp.bruyere@hotmail.com>
-//
-// Copyright (c) 2013-2017 Jean-Philippe Bruyère
-//
-// 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.Xml.Serialization;
-using System.ComponentModel;
-using OpenTK.Input;
-
-namespace Crow
-{
-    public class Popper : TemplatedContainer
-    {
-               #region CTOR
-               public Popper() : base()
-               {
-               }
-               #endregion
-
-               bool _isPopped, _canPop;
-               Alignment popDirection;
-               GraphicObject _content;
-               Measure popWidth, popHeight;
-
-               public event EventHandler Popped;
-               public event EventHandler Unpoped;
-
-               #region Public Properties
-               [XmlAttributeAttribute()][DefaultValue("Fit")]
-               public virtual Measure PopWidth {
-                       get { return popWidth; }
-                       set {
-                               if (popWidth == value)
-                                       return;
-                               popWidth = value;
-                               NotifyValueChanged ("PopWidth", popWidth);
-                       }
-               }
-               [XmlAttributeAttribute()][DefaultValue("Fit")]
-               public virtual Measure PopHeight {
-                       get { return popHeight; }
-                       set {
-                               if (popHeight == value)
-                                       return;
-                               popHeight = value;
-                               NotifyValueChanged ("PopHeight", popHeight);
-                       }
-               }
-               [XmlAttributeAttribute()][DefaultValue(false)]
-               public bool IsPopped
-               {
-                       get { return _isPopped; }
-                       set
-                       {
-                               if (value == _isPopped)
-                                       return;
-
-                               _isPopped = value;
-                               NotifyValueChanged ("IsPopped", _isPopped);
-
-                               if (_isPopped)
-                                       onPop (this, null);
-                               else
-                                       onUnpop (this, null);
-
-                       }
-               }
-               [XmlAttributeAttribute()][DefaultValue(true)]
-               public bool CanPop
-               {
-                       get { return _canPop; }
-                       set
-                       {
-                               if (value == _canPop)
-                                       return;
-
-                               _canPop = value;
-                               NotifyValueChanged ("CanPop", _canPop);
-                       }
-               }
-               [XmlAttributeAttribute()][DefaultValue(Alignment.Bottom)]
-               public virtual Alignment PopDirection {
-                       get { return popDirection; }
-                       set {
-                               if (popDirection == value)
-                                       return;
-                               popDirection = value;
-                               NotifyValueChanged ("PopDirection", popDirection);
-                       }
-               }
-               #endregion
-
-               public override GraphicObject Content {
-                       get { return _content; }
-                       set {
-                               if (_content != null) {
-                                       _content.LogicalParent = null;
-                                       _content.LayoutChanged -= _content_LayoutChanged;
-                               }
-
-                               _content = value;
-
-                               if (_content == null)
-                                       return;
-
-                               _content.LogicalParent = this;
-                               _content.HorizontalAlignment = HorizontalAlignment.Left;
-                               _content.VerticalAlignment = VerticalAlignment.Top;
-                               _content.LayoutChanged += _content_LayoutChanged;
-                       }
-               }
-               void positionContent(LayoutingType lt){
-                       ILayoutable tc = Content.Parent;
-                       if (tc == null)
-                               return;
-                       Rectangle r = this.ScreenCoordinates (this.Slot);
-                       if (lt == LayoutingType.X) {
-                               if (popDirection.HasFlag (Alignment.Right)) {
-                                       if (r.Right + Content.Slot.Width > tc.ClientRectangle.Right)
-                                               Content.Left = r.Left - Content.Slot.Width;
-                                       else
-                                               Content.Left = r.Right;
-                               } else if (popDirection.HasFlag (Alignment.Left)) {
-                                       if (r.Left - Content.Slot.Width < tc.ClientRectangle.Left)
-                                               Content.Left = r.Right;
-                                       else
-                                               Content.Left = r.Left - Content.Slot.Width;
-                               } else {
-                                       if (Content.Slot.Width < tc.ClientRectangle.Width) {
-                                               if (r.Left + Content.Slot.Width > tc.ClientRectangle.Right)
-                                                       Content.Left = tc.ClientRectangle.Right - Content.Slot.Width;
-                                               else
-                                                       Content.Left = r.Left;
-                                       } else
-                                               Content.Left = 0;
-                               }
-                       }else if (lt == LayoutingType.Y) {
-                               if (Content.Slot.Height < tc.ClientRectangle.Height) {
-                                       if (PopDirection.HasFlag (Alignment.Bottom)) {
-                                               if (r.Bottom + Content.Slot.Height > tc.ClientRectangle.Bottom)
-                                                       Content.Top = r.Top - Content.Slot.Height;
-                                               else
-                                                       Content.Top = r.Bottom;
-                                       } else if (PopDirection.HasFlag (Alignment.Top)) {
-                                               if (r.Top - Content.Slot.Height < tc.ClientRectangle.Top)
-                                                       Content.Top = r.Bottom;
-                                               else
-                                                       Content.Top = r.Top - Content.Slot.Height;
-                                       } else
-                                               Content.Top = r.Top;
-                               }else
-                                       Content.Top = 0;
-                       }
-               }
-               protected void _content_LayoutChanged (object sender, LayoutingEventArgs e)
-               {
-                       if (e.LayoutType.HasFlag (LayoutingType.Width))
-                               positionContent (LayoutingType.X);
-                       if (e.LayoutType.HasFlag(LayoutingType.Height))
-                               positionContent (LayoutingType.Y);
-               }
-
-               #region GraphicObject overrides
-               public override void onMouseClick (object sender, MouseButtonEventArgs e)
-               {
-                       if (_canPop)
-                               IsPopped = !IsPopped;
-                       base.onMouseClick (this, e);
-               }
-               public override void onMouseLeave (object sender, MouseMoveEventArgs e)
-               {
-                       base.onMouseLeave (this, e);
-                       IsPopped = false;
-               }
-               public override bool MouseIsIn (Point m)
-               {
-                       bool isInContent = false;
-                       if (Content != null) {
-                               if (Content.Parent != null)
-                                       isInContent = Content.MouseIsIn (m);
-                       }
-                       return base.MouseIsIn (m) || isInContent;
-               }
-               public override void checkHoverWidget (MouseMoveEventArgs e)
-               {
-                       if (CurrentInterface.HoverWidget != this) {
-                               CurrentInterface.HoverWidget = this;
-                               onMouseEnter (this, e);
-                       }
-                       if (Content != null){
-                               if (Content.Parent != null) {
-                                       if (Content.MouseIsIn (e.Position)) {
-                                               Content.checkHoverWidget (e);
-                                               return;
-                                       }
-                               }
-                       }
-                       base.checkHoverWidget (e);
-               }
-               #endregion
-
-               public virtual void onPop(object sender, EventArgs e)
-               {
-                       if (Content != null) {
-                               Content.Visible = true;
-                               if (Content.Parent == null)
-                                       CurrentInterface.AddWidget (Content, true);
-                               if (Content.LogicalParent != this)
-                                       Content.LogicalParent = this;
-                               CurrentInterface.PutOnTop (Content, true);
-                               _content_LayoutChanged (this, new LayoutingEventArgs (LayoutingType.Sizing));
-                       }
-                       Popped.Raise (this, e);
-               }
-               public virtual void onUnpop(object sender, EventArgs e)
-               {
-                       if (Content != null) {
-                               Content.Visible = false;
-                       }
-                       Unpoped.Raise (this, e);
-               }
-       }
-}
diff --git a/src/GraphicObjects/PrivateContainer.cs b/src/GraphicObjects/PrivateContainer.cs
deleted file mode 100644 (file)
index 65eacab..0000000
+++ /dev/null
@@ -1,207 +0,0 @@
-//
-// PrivateContainer.cs
-//
-// Author:
-//       Jean-Philippe Bruyère <jp.bruyere@hotmail.com>
-//
-// Copyright (c) 2013-2017 Jean-Philippe Bruyère
-//
-// 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.Xml.Serialization;
-using System.ComponentModel;
-using Cairo;
-
-namespace Crow
-{
-       /// <summary>
-       /// Implement drawing and layouting for a single child, but
-       /// does not implement IXmlSerialisation to allow reuse of container
-       /// behaviour for widgets that have other xml hierarchy: example
-       /// TemplatedControl may have 3 children (template,templateItem,content) but
-       /// behave exactely as a container for layouting and drawing
-       /// </summary>
-       public class PrivateContainer : GraphicObject
-       {
-               #region CTOR
-               public PrivateContainer()
-                       : base()
-               {
-               }
-               #endregion
-
-               protected GraphicObject child;
-
-               internal virtual void SetChild(GraphicObject _child)
-               {
-
-                       if (child != null) {
-                               contentSize = new Size (0, 0);
-                               child.LayoutChanged -= OnChildLayoutChanges;
-                               child.Parent = null;
-                               this.RegisterForGraphicUpdate ();
-                       }
-
-                       child = _child as GraphicObject;
-
-                       if (child != null) {
-                               child.Parent = this;
-                               child.LayoutChanged += OnChildLayoutChanges;
-                               contentSize = child.Slot.Size;
-                               child.RegisteredLayoutings = LayoutingType.None;
-                               child.RegisterForLayouting (LayoutingType.Sizing);
-                       }
-               }
-
-               #region GraphicObject Overrides
-
-               public override GraphicObject FindByName (string nameToFind)
-               {
-                       if (Name == nameToFind)
-                               return this;
-
-                       return child == null ? null : child.FindByName (nameToFind);
-               }
-               public override bool Contains (GraphicObject goToFind)
-               {
-                       return child == goToFind ? true : 
-                               child == null ? false : child.Contains(goToFind);
-               }
-               public override void OnDataSourceChanged (object sender, DataSourceChangeEventArgs e)
-               {
-                       base.OnDataSourceChanged (this, e);
-                       if (child != null)
-                       if (child.localDataSourceIsNull & child.localLogicalParentIsNull)
-                                       child.OnDataSourceChanged (sender, e);
-               }
-               public override bool UpdateLayout (LayoutingType layoutType)
-               {
-                       if (child != null) {
-                               //force sizing to fit if sizing on children and child has stretched size
-                               switch (layoutType) {
-                               case LayoutingType.Width:
-                                       if (Width == Measure.Fit && child.Width.Units == Unit.Percent)
-                                               child.Width = Measure.Fit;
-                                       break;
-                               case LayoutingType.Height:
-                                       if (Height == Measure.Fit && child.Height.Units == Unit.Percent)
-                                               child.Height = Measure.Fit;
-                                       break;
-                               }
-                       }
-                       return base.UpdateLayout (layoutType);
-               }
-               public override void OnLayoutChanges (LayoutingType layoutType)
-               {
-                       base.OnLayoutChanges (layoutType);
-
-                       if (child == null)
-                               return;
-                       
-                       LayoutingType ltChild = LayoutingType.None;
-
-                       if (layoutType == LayoutingType.Width) {
-                               if (child.Width.Units == Unit.Percent) {
-                                       ltChild |= LayoutingType.Width;
-                                       if (child.Width.Value < 100 && child.Left == 0)
-                                               ltChild |= LayoutingType.X;
-                               } else if (child.Left == 0)
-                                       ltChild |= LayoutingType.X;
-                       } else if (layoutType == LayoutingType.Height) {
-                               if (child.Height.Units == Unit.Percent) {
-                                       ltChild |= LayoutingType.Height;
-                                       if (child.Height.Value < 100 && child.Top == 0)
-                                               ltChild |= LayoutingType.Y;
-                               } else if (child.Top == 0)
-                                               ltChild |= LayoutingType.Y;
-                       }
-                       if (ltChild == LayoutingType.None)
-                               return;
-                       child.RegisterForLayouting (ltChild);
-               }
-               public virtual void OnChildLayoutChanges (object sender, LayoutingEventArgs arg)
-               {                       
-                       GraphicObject g = sender as GraphicObject;
-
-                       if (arg.LayoutType == LayoutingType.Width) {
-                               if (Width != Measure.Fit)
-                                       return;
-                               contentSize.Width = g.Slot.Width;
-                               this.RegisterForLayouting (LayoutingType.Width);
-                       }else if (arg.LayoutType == LayoutingType.Height){
-                               if (Height != Measure.Fit)
-                                       return;
-                               contentSize.Height = g.Slot.Height;
-                               this.RegisterForLayouting (LayoutingType.Height);
-                       }
-               }
-               protected override void onDraw (Context gr)
-               {
-                       base.onDraw (gr);
-
-                       gr.Save ();
-
-                       if (ClipToClientRect) {
-                               //clip to client zone
-                               CairoHelpers.CairoRectangle (gr, ClientRectangle, CornerRadius);
-                               gr.Clip ();
-                       }
-
-                       if (child != null) {
-                               if (child.Visible)
-                                       child.Paint (ref gr);
-                       }
-                       gr.Restore ();
-               }
-               protected override void UpdateCache (Context ctx)
-               {
-                       Rectangle rb = Slot + Parent.ClientRectangle.Position;
-
-                       using (ImageSurface cache = new ImageSurface (bmp, Format.Argb32, Slot.Width, Slot.Height, 4 * Slot.Width)) {
-                               Context gr = new Context (cache);
-
-                               if (Clipping.count > 0) {
-                                       Clipping.clearAndClip (gr);
-
-                                       onDraw (gr);
-                               }
-                                       
-                               gr.Dispose ();
-
-                               ctx.SetSourceSurface (cache, rb.X, rb.Y);
-                               ctx.Paint ();
-                       }
-                       Clipping.Reset();
-               }
-               #endregion
-
-               #region Mouse handling
-               public override void checkHoverWidget (MouseMoveEventArgs e)
-               {
-                       base.checkHoverWidget (e);
-                       if (child != null) 
-                               if (child.MouseIsIn (e.Position)) 
-                                       child.checkHoverWidget (e);
-               }
-               #endregion
-
-       }
-}
-
diff --git a/src/GraphicObjects/ProgressBar.cs b/src/GraphicObjects/ProgressBar.cs
deleted file mode 100644 (file)
index 34366ca..0000000
+++ /dev/null
@@ -1,67 +0,0 @@
-//
-// ProgressBar.cs
-//
-// Author:
-//       Jean-Philippe Bruyère <jp.bruyere@hotmail.com>
-//
-// Copyright (c) 2013-2017 Jean-Philippe Bruyère
-//
-// 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.Generic;
-using System.Linq;
-using System.Text;
-using Cairo;
-using System.Diagnostics;
-using System.Xml.Serialization;
-using System.ComponentModel;
-
-namespace Crow
-{
-       
-       public class ProgressBar : NumericControl
-    {
-               #region CTOR
-               public ProgressBar() : base(){}
-               #endregion
-
-               protected override void loadTemplate (GraphicObject template)
-               {
-                       
-               }
-
-               #region GraphicObject overrides
-               protected override void onDraw (Context gr)
-               {
-                       base.onDraw (gr);
-
-                       if (Maximum == 0)
-                               return;
-
-                       Rectangle rBack = ClientRectangle;
-                       rBack.Width = (int)((double)rBack.Width / Maximum * Value);
-                       Foreground.SetAsSource (gr, rBack);
-
-                       CairoHelpers.CairoRectangle(gr,rBack,CornerRadius);
-                       gr.Fill();
-               }
-               #endregion
-    }
-}
diff --git a/src/GraphicObjects/RadioButton.cs b/src/GraphicObjects/RadioButton.cs
deleted file mode 100644 (file)
index 993ead5..0000000
+++ /dev/null
@@ -1,82 +0,0 @@
-//
-// RadioButton.cs
-//
-// Author:
-//       Jean-Philippe Bruyère <jp.bruyere@hotmail.com>
-//
-// Copyright (c) 2013-2017 Jean-Philippe Bruyère
-//
-// 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.Xml.Serialization;
-
-namespace Crow
-{
-    public class RadioButton : TemplatedControl
-    {                  
-               bool isChecked;
-
-               #region CTOR
-               public RadioButton() : base(){} 
-               #endregion
-
-               public event EventHandler Checked;
-               public event EventHandler Unchecked;
-
-               #region GraphicObject overrides
-               public override void onMouseClick (object sender, MouseButtonEventArgs e)
-               {                                               
-                       Group pg = Parent as Group;
-                       if (pg != null) {
-                               for (int i = 0; i < pg.Children.Count; i++) {
-                                       RadioButton c = pg.Children [i] as RadioButton;
-                                       if (c == null)
-                                               continue;
-                                       c.IsChecked = (c == this);
-                               }
-                       } else
-                               IsChecked = !IsChecked;
-
-                       base.onMouseClick (sender, e);
-               }
-               #endregion
-
-        [XmlAttributeAttribute()][DefaultValue(false)]
-        public bool IsChecked
-        {
-                       get { return isChecked; }
-            set
-            {
-                               if (isChecked == value)
-                                       return;
-                               
-                               isChecked = value;
-
-                               NotifyValueChanged ("IsChecked", value);
-
-                               if (isChecked)
-                                       Checked.Raise (this, null);
-                               else
-                                       Unchecked.Raise (this, null);
-            }
-        }
-       }
-}
diff --git a/src/GraphicObjects/ScrollBar.cs b/src/GraphicObjects/ScrollBar.cs
deleted file mode 100644 (file)
index 91ce50e..0000000
+++ /dev/null
@@ -1,68 +0,0 @@
-//
-// ScrollBar.cs
-//
-// Author:
-//       Jean-Philippe Bruyère <jp.bruyere@hotmail.com>
-//
-// Copyright (c) 2013-2017 Jean-Philippe Bruyère
-//
-// 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.Xml.Serialization;
-using System.ComponentModel;
-using OpenTK.Input;
-
-namespace Crow
-{
-       public class ScrollBar : NumericControl
-       {
-               Orientation _orientation;
-
-               #region CTOR
-               public ScrollBar() : base()     {}
-               #endregion
-
-               [XmlAttributeAttribute()][DefaultValue(Orientation.Vertical)]
-               public virtual Orientation Orientation
-               {
-                       get { return _orientation; }
-                       set {                           
-                               if (_orientation == value)
-                                       return;
-                               _orientation = value;
-                               NotifyValueChanged ("Orientation", _orientation);
-                               RegisterForGraphicUpdate ();
-                       }
-               }
-               public void onScrollBack (object sender, MouseButtonEventArgs e)
-               {
-                       Value -= SmallIncrement;
-               }
-               public void onScrollForth (object sender, MouseButtonEventArgs e)
-               {
-                       Value += SmallIncrement;
-               }
-
-               public void onSliderValueChange(object sender, ValueChangeEventArgs e){
-                       if (e.MemberName == "Value")
-                               Value = Convert.ToDouble(e.NewValue);
-               }
-       }
-}
diff --git a/src/GraphicObjects/Scroller.cs b/src/GraphicObjects/Scroller.cs
deleted file mode 100644 (file)
index 640fcfe..0000000
+++ /dev/null
@@ -1,239 +0,0 @@
-//
-// Scroller.cs
-//
-// Author:
-//       Jean-Philippe Bruyère <jp.bruyere@hotmail.com>
-//
-// Copyright (c) 2013-2017 Jean-Philippe Bruyère
-//
-// 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.Xml.Serialization;
-using System.ComponentModel;
-using System.Diagnostics;
-using Cairo;
-
-namespace Crow
-{
-       public class Scroller : Container
-       {
-               bool _verticalScrolling;
-               bool _horizontalScrolling;
-               bool _scrollbarVisible;
-               double _scrollX = 0.0;
-               double _scrollY = 0.0;
-               int scrollSpeed;
-
-               public event EventHandler<ScrollingEventArgs> Scrolled;
-
-               #region public properties
-               [XmlAttributeAttribute][DefaultValue(true)]
-               public bool VerticalScrolling {
-                       get { return _verticalScrolling; }
-                       set { _verticalScrolling = value; }
-               }
-
-               [XmlAttributeAttribute][DefaultValue(false)]
-        public bool HorizontalScrolling {
-                       get { return _horizontalScrolling; }
-                       set { _horizontalScrolling = value; }
-               }
-               [XmlAttributeAttribute][DefaultValue(true)]
-               public bool ScrollbarVisible {
-                       get { return _scrollbarVisible; }
-                       set { _scrollbarVisible = value; }
-               }
-               [XmlAttributeAttribute][DefaultValue(0.0)]
-               public double ScrollX {
-                       get {
-                               return _scrollX;
-                       }
-                       set {
-                               if (_scrollX == value)
-                                       return;
-                               if (value < 0.0)
-                                       _scrollX = 0.0;
-                               else if (value > Child.Slot.Width - ClientRectangle.Width)
-                                       _scrollX = Math.Max(0.0, Child.Slot.Width - ClientRectangle.Width);
-                               else
-                                       _scrollX = value;
-                               NotifyValueChanged("ScrollX", _scrollX);
-                               RegisterForRedraw ();
-                               Scrolled.Raise (this, new ScrollingEventArgs (Orientation.Horizontal));
-                       }
-               }
-               [XmlAttributeAttribute][DefaultValue(0.0)]
-               public double ScrollY {
-                       get {
-                               return _scrollY;
-                       }
-                       set {
-                               if (_scrollY == value)
-                                       return;
-                               if (value < 0.0)
-                                       _scrollY = 0.0;
-                               else if (value > Child.Slot.Height - ClientRectangle.Height)
-                                       _scrollY = Math.Max(0.0,Child.Slot.Height - ClientRectangle.Height);
-                               else
-                                       _scrollY = value;
-                               NotifyValueChanged("ScrollY", _scrollY);
-                               RegisterForRedraw ();
-                               Scrolled.Raise (this, new ScrollingEventArgs (Orientation.Vertical));
-                       }
-               }
-
-               [XmlIgnore]
-               public int MaximumScroll {
-                       get {
-                               try {
-                                       return VerticalScrolling ?
-                                               Math.Max(Child.Slot.Height - ClientRectangle.Height,0) :
-                                               Math.Max(Child.Slot.Width - ClientRectangle.Width,0);
-                               } catch {
-                                       return 0;
-                               }
-                       }
-               }
-
-               [XmlAttributeAttribute][DefaultValue(30)]
-               public int ScrollSpeed {
-                       get { return scrollSpeed; }
-                       set {
-                               scrollSpeed = value;
-                               NotifyValueChanged("ScrollSpeed", scrollSpeed);
-                       }
-               }
-               #endregion
-
-        public Scroller()
-            : base(){}
-
-               #region GraphicObject Overrides
-               public override void OnLayoutChanges (LayoutingType layoutType)
-               {
-                       base.OnLayoutChanges (layoutType);
-
-                       NotifyValueChanged("MaximumScroll", MaximumScroll);
-               }
-               void OnChildLayoutChanges (object sender, LayoutingEventArgs arg)
-               {
-                       //Debug.WriteLine ("scroller childLayoutChanges");
-                       int maxScroll = MaximumScroll;
-                       //Debug.WriteLine ("maxscroll={0}", maxScroll);
-                       if (_verticalScrolling) {
-                               if (arg.LayoutType == LayoutingType.Height) {
-                                       if (maxScroll < ScrollY) {
-                                               //Debug.WriteLine ("scrolly={0} maxscroll={1}", ScrollY, maxScroll);
-                                               ScrollY = maxScroll;
-                                       }
-                                       NotifyValueChanged("MaximumScroll", maxScroll);
-                               }
-                       } else if (arg.LayoutType == LayoutingType.Width) {
-                               if (maxScroll < ScrollX) {
-                                       //Debug.WriteLine ("scrolly={0} maxscroll={1}", ScrollY, maxScroll);
-                                       ScrollX = maxScroll;
-                               }
-                               NotifyValueChanged("MaximumScroll", maxScroll);
-                       }
-               }
-               void onChildListCleared(object sender, EventArgs e){
-                       ScrollY = 0;
-                       ScrollX = 0;
-               }
-               public override void SetChild (GraphicObject _child)
-               {
-                       GraphicObject c = child as GraphicObject;
-                       Group g = child as Group;
-                       if (c != null) {
-                               c.LayoutChanged -= OnChildLayoutChanges;
-                               if (g != null)
-                                       g.ChildrenCleared -= onChildListCleared;
-                       }
-                       c = _child as GraphicObject;
-                       g = _child as Group;
-                       if (c != null) {
-                               c.LayoutChanged += OnChildLayoutChanges;
-                               if (g != null)
-                                       g.ChildrenCleared += onChildListCleared;
-                       }
-                       base.SetChild (_child);
-               }
-               public override Rectangle ScreenCoordinates (Rectangle r)
-               {
-                       return base.ScreenCoordinates (r) - new Point((int)ScrollX,(int)ScrollY);
-               }
-               protected override void onDraw (Context gr)
-               {
-                       Rectangle rBack = new Rectangle (Slot.Size);
-
-                       Background.SetAsSource (gr, rBack);
-                       CairoHelpers.CairoRectangle(gr,rBack, CornerRadius);
-                       gr.Fill ();
-
-                       gr.Save ();
-                       if (ClipToClientRect) {
-                               //clip to scrolled client zone
-                               CairoHelpers.CairoRectangle (gr, ClientRectangle, CornerRadius);
-                               gr.Clip ();
-                       }
-
-                       gr.Translate (-ScrollX, -ScrollY);
-                       if (child != null)
-                               child.Paint (ref gr);
-                       gr.Restore ();
-               }
-
-               #region Mouse handling
-               internal Point savedMousePos;
-               public override bool MouseIsIn (Point m)
-               {
-                       return Visible ? base.ScreenCoordinates(Slot).ContainsOrIsEqual (m) : false;
-               }
-               public override void checkHoverWidget (MouseMoveEventArgs e)
-               {
-                       savedMousePos = e.Position;
-                       Point m = e.Position - new Point ((int)ScrollX, (int)ScrollY);
-                       base.checkHoverWidget (new MouseMoveEventArgs(m.X,m.Y,e.XDelta,e.YDelta));
-               }
-               public override void onMouseWheel (object sender, MouseWheelEventArgs e)
-               {
-                       if (Child == null)
-                               return;
-
-                       if (VerticalScrolling )
-                               ScrollY -= e.Delta * ScrollSpeed;
-                       if (HorizontalScrolling )
-                               ScrollX -= e.Delta * ScrollSpeed;
-               }
-               public override void onMouseMove (object sender, MouseMoveEventArgs e)
-               {
-                       savedMousePos.X += e.XDelta;
-                       savedMousePos.Y += e.YDelta;
-                       base.onMouseMove (sender, new MouseMoveEventArgs(savedMousePos.X,savedMousePos.Y,e.XDelta,e.YDelta));
-               }
-               public override void RegisterClip (Rectangle clip)
-               {
-                       base.RegisterClip (clip - new Point((int)ScrollX,(int)ScrollY));
-               }
-               #endregion
-
-               #endregion
-    }
-}
diff --git a/src/GraphicObjects/Slider.cs b/src/GraphicObjects/Slider.cs
deleted file mode 100644 (file)
index 36f7e73..0000000
+++ /dev/null
@@ -1,219 +0,0 @@
-//
-// Slider.cs
-//
-// Author:
-//       Jean-Philippe Bruyère <jp.bruyere@hotmail.com>
-//
-// Copyright (c) 2013-2017 Jean-Philippe Bruyère
-//
-// 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 Cairo;
-using System.Xml.Serialization;
-using System.ComponentModel;
-using System.Diagnostics;
-
-namespace Crow
-{
-       public class Slider : NumericControl
-    {
-               #region CTOR
-               public Slider() : base()
-               {}
-               public Slider(double minimum, double maximum, double step)
-                       : base(minimum,maximum,step)
-               {
-               }
-               #endregion
-
-               #region implemented abstract members of TemplatedControl
-
-               protected override void loadTemplate (GraphicObject template = null)
-               {
-                       
-               }
-
-               #endregion
-
-               #region private fields
-        Rectangle cursor;
-               int _cursorSize;
-               Fill _cursorColor;
-               Orientation _orientation;
-               bool holdCursor = false;
-               #endregion
-
-               protected double unity;
-
-               #region Public properties
-               [XmlAttributeAttribute()][DefaultValue("vgradient|0:White|0,1:LightGray|0,9:LightGray|1:DimGray")]
-               public virtual Fill CursorColor {
-                       get { return _cursorColor; }
-                       set {
-                               if (_cursorColor == value)
-                                       return;
-                               _cursorColor = value;
-                               RegisterForRedraw ();
-                               NotifyValueChanged ("CursorColor", _cursorColor);
-                       }
-               }
-               [XmlAttributeAttribute()][DefaultValue(20)]
-               public virtual int CursorSize {
-                       get { return _cursorSize; }
-                       set {
-                               if (_cursorSize == value)
-                                       return;
-                               _cursorSize = value;
-                               RegisterForGraphicUpdate ();
-                               NotifyValueChanged ("CursorSize", _cursorSize);
-                       }
-               }
-               [XmlAttributeAttribute()][DefaultValue(Orientation.Horizontal)]
-               public virtual Orientation Orientation
-               {
-                       get { return _orientation; }
-                       set { 
-                               if (_orientation == value)
-                                       return;
-                               _orientation = value; 
-
-                               RegisterForLayouting (LayoutingType.All);
-                               NotifyValueChanged ("Orientation", _orientation);
-                       }
-               }
-               #endregion
-
-               [XmlAttributeAttribute()][DefaultValue(10.0)]
-               public override double Maximum {
-                       get { return base.Maximum; }
-                       set {                           
-                               if (value == base.Maximum)
-                                       return;
-                               base.Maximum = value;
-                               LargeIncrement = base.Maximum / 10.0;
-                               SmallIncrement = LargeIncrement / 5.0;
-                       }
-               }
-
-               #region GraphicObject Overrides
-               protected override void onDraw (Context gr)
-               {
-                       base.onDraw (gr);
-                       if (Maximum <= 0)
-                               return;
-
-                       computeCursorPosition ();
-
-                       Rectangle r = ClientRectangle;
-                       PointD pStart;
-                       PointD pEnd;
-                       if (_orientation == Orientation.Horizontal) {
-                               pStart = r.TopLeft + new Point (_cursorSize / 2, r.Height / 2);
-                               pEnd = r.TopRight + new Point (-_cursorSize / 2, r.Height / 2);
-                       } else {
-                               pStart = r.TopLeft + new Point (r.Width / 2, _cursorSize / 2);
-                               pEnd = r.BottomLeft + new Point (r.Width / 2,- _cursorSize / 2);
-                       }
-
-                       DrawGraduations (gr, pStart,pEnd);
-
-                       DrawCursor (gr, cursor);
-               }
-               #endregion
-
-               protected virtual void DrawGraduations(Context gr, PointD pStart, PointD pEnd)
-               {
-                       Foreground.SetAsSource (gr);
-
-                       gr.LineWidth = 1;
-                       gr.MoveTo(pStart);
-                       gr.LineTo(pEnd);
-
-                       gr.Stroke();
-
-               }
-               protected virtual void DrawCursor(Context gr, Rectangle _cursor)
-               {
-                       CursorColor.SetAsSource (gr, _cursor);
-                       CairoHelpers.CairoRectangle (gr, _cursor, CornerRadius);
-                       gr.Fill();
-               }
-
-        void computeCursorPosition()
-        {            
-            Rectangle r = ClientRectangle;
-                       PointD p1; 
-
-                       if (_orientation == Orientation.Horizontal) {
-                               cursor = new Rectangle (new Size (_cursorSize, (int)(r.Height)));
-                               p1 = r.TopLeft + new Point (_cursorSize / 2, r.Height / 2);
-                               unity = (double)(r.Width - _cursorSize) / (Maximum - Minimum);
-                               cursor.TopLeft = new Point (r.Left + (int)(Value * unity),
-                                       (int)(p1.Y - cursor.Height / 2));
-                       } else {
-                               cursor = new Rectangle (new Size ((int)(r.Width), _cursorSize));
-                               p1 = r.TopLeft + new Point (r.Width / 2, _cursorSize / 2);
-                               unity = (double)(r.Height - _cursorSize) / (Maximum - Minimum);
-                               cursor.TopLeft = new Point ((int)(p1.X - r.Width / 2),
-                                       r.Top + (int)(Value * unity));                          
-                       }
-                       cursor.Inflate (-1);
-        }
-        
-               #region mouse handling
-               public override void onMouseDown (object sender, MouseButtonEventArgs e)
-               {
-                       base.onMouseDown (sender, e);
-
-                       Rectangle cursInScreenCoord = ScreenCoordinates (cursor + Slot.Position);
-                       if (cursInScreenCoord.ContainsOrIsEqual (e.Position))
-                               holdCursor = true;
-                       else if (_orientation == Orientation.Horizontal) {
-                               if (e.Position.X < cursInScreenCoord.Left)
-                                       Value -= LargeIncrement;
-                               else
-                                       Value += LargeIncrement;
-                       } else {
-                               if (e.Position.Y < cursInScreenCoord.Top)
-                                       Value -= LargeIncrement;
-                               else
-                                       Value += LargeIncrement;
-                       }
-               }
-               public override void onMouseUp (object sender,MouseButtonEventArgs e)
-               {
-                       base.onMouseUp (sender, e);
-
-                       holdCursor = false;
-               }
-               public override void onMouseMove (object sender, MouseMoveEventArgs e)
-               {
-                       if (holdCursor) {
-                               if (_orientation == Orientation.Horizontal)
-                                       Value += (double)e.XDelta / unity;
-                               else
-                                       Value += (double)e.YDelta / unity;
-                       }
-                       
-                       base.onMouseMove (sender, e);
-               }
-               #endregion
-    }
-}
diff --git a/src/GraphicObjects/Spinner.cs b/src/GraphicObjects/Spinner.cs
deleted file mode 100644 (file)
index 1bf93a3..0000000
+++ /dev/null
@@ -1,55 +0,0 @@
-//
-// Spinner.cs
-//
-// Author:
-//       Jean-Philippe Bruyère <jp.bruyere@hotmail.com>
-//
-// Copyright (c) 2013-2017 Jean-Philippe Bruyère
-//
-// 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 Crow
-{
-       public class Spinner : NumericControl
-       {
-               #region CTOR
-               public Spinner () : base()
-               {
-               }
-               public Spinner (double minimum, double maximum, double step) : 
-               base (minimum, maximum, step)
-               {
-
-               }
-               #endregion
-
-               void onUp (object sender, MouseButtonEventArgs e)
-               {
-                       Value += this.SmallIncrement;
-               }
-               void onDown (object sender, MouseButtonEventArgs e)
-               {
-                       Value -= this.SmallIncrement;
-               }
-
-       }
-}
-
diff --git a/src/GraphicObjects/Splitter.cs b/src/GraphicObjects/Splitter.cs
deleted file mode 100644 (file)
index 2f5dd15..0000000
+++ /dev/null
@@ -1,218 +0,0 @@
-//
-// Splitter.cs
-//
-// Author:
-//       Jean-Philippe Bruyère <jp.bruyere@hotmail.com>
-//
-// Copyright (c) 2013-2017 Jean-Philippe Bruyère
-//
-// 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.Xml.Serialization;
-using System.ComponentModel;
-
-namespace Crow
-{
-       public class Splitter : GraphicObject
-       {
-               #region CTOR
-               public Splitter (): base(){}
-               #endregion
-
-               int thickness;
-
-               [XmlAttributeAttribute][DefaultValue(1)]
-               public virtual int Thickness {
-                       get { return thickness; }
-                       set {
-                               if (thickness == value)
-                                       return;
-                               thickness = value; 
-                               NotifyValueChanged ("Thickness", thickness);
-                               RegisterForLayouting (LayoutingType.Sizing);
-                               RegisterForGraphicUpdate ();
-                       }
-               }
-
-               Unit u1, u2;
-               int init1 = -1, init2 = -1, delta = 0, min1, min2, max1 , max2;
-               GraphicObject go1 = null, go2 = null;
-
-               void initSplit(Measure m1, int size1, Measure m2, int size2){
-                       if (m1 != Measure.Stretched) {
-                               init1 = size1;
-                               u1 = m1.Units;
-                       }
-                       if (m2 != Measure.Stretched) {
-                               init2 = size2;
-                               u2 = m2.Units;
-                       }
-               }
-               void convertSizeInPix(GraphicObject g1){
-
-               }
-
-               #region GraphicObject override
-               public override ILayoutable Parent {
-                       get { return base.Parent; }
-                       set {
-                               if (value != null) {                    
-                                       GenericStack gs = value as GenericStack;
-                                       if (gs == null)
-                                               throw new Exception ("Splitter may only be chil of stack");
-                                       
-                               }
-                               base.Parent = value;
-                       }
-               }
-               public override void onMouseEnter (object sender, MouseMoveEventArgs e)
-               {
-                       base.onMouseEnter (sender, e);
-                       if ((Parent as GenericStack).Orientation == Orientation.Horizontal)
-                               CurrentInterface.MouseCursor = XCursor.H;
-                       else
-                               CurrentInterface.MouseCursor = XCursor.V;
-               }
-               public override void onMouseLeave (object sender, MouseMoveEventArgs e)
-               {
-                       base.onMouseLeave (sender, e);
-                       CurrentInterface.MouseCursor = XCursor.Default;
-               }
-               public override void onMouseDown (object sender, MouseButtonEventArgs e)
-               {
-                       base.onMouseDown (sender, e);
-                       go1 = go2 = null;
-                       init1 = init2 = -1;
-                       delta = 0;
-
-                       GenericStack gs = Parent as GenericStack;
-                       int ptrSplit = gs.Children.IndexOf (this);
-                       if (ptrSplit == 0 || ptrSplit == gs.Children.Count - 1)
-                               return;
-
-                       go1 = gs.Children [ptrSplit - 1];
-                       go2 = gs.Children [ptrSplit + 1];
-
-                       if (gs.Orientation == Orientation.Horizontal) {
-                               initSplit (go1.Width, go1.Slot.Width, go2.Width, go2.Slot.Width);
-                               min1 = go1.MinimumSize.Width;
-                               min2 = go2.MinimumSize.Width;
-                               max1 = go1.MaximumSize.Width;
-                               max2 = go2.MaximumSize.Width;
-                               if (init1 >= 0)
-                                       go1.Width = init1;
-                               if (init2 >= 0)
-                                       go2.Width = init2;
-                       } else {
-                               initSplit (go1.Height, go1.Slot.Height, go2.Height, go2.Slot.Height);
-                               min1 = go1.MinimumSize.Height;
-                               min2 = go2.MinimumSize.Height;
-                               max1 = go1.MaximumSize.Height;
-                               max2 = go2.MaximumSize.Height;
-                               if (init1 >= 0)
-                                       go1.Height = init1;
-                               if (init2 >= 0)
-                                       go2.Height = init2;
-                       }
-               }
-               public override void onMouseMove (object sender, MouseMoveEventArgs e)
-               {
-                       base.onMouseMove (sender, e);
-
-                       if (!IsActive)
-                               return;
-
-                       GenericStack gs = Parent as GenericStack;
-                       int newDelta = delta, size1 = init1 , size2 = init2;
-                       if (gs.Orientation == Orientation.Horizontal) {
-                               newDelta -= e.XDelta;
-                               if (size1 < 0)
-                                       size1 = go1.Slot.Width + delta;
-                               if (size2 < 0)
-                                       size2 = go2.Slot.Width - delta;
-                       } else {
-                               newDelta -= e.YDelta;
-                               if (size1 < 0)
-                                       size1 = go1.Slot.Height + delta;
-                               if (size2 < 0)
-                                       size2 = go2.Slot.Height - delta;
-                       }
-
-                       if (size1 - newDelta < min1 || (max1 > 0 && size1 - newDelta > max1) ||
-                               size2 + newDelta < min2 || (max2 > 0 && size2 + newDelta > max2))
-                               return;
-
-                       delta = newDelta;
-
-                       if (gs.Orientation == Orientation.Horizontal) {
-                               if (init1 >= 0)
-                                       go1.Width = init1 - delta;
-                               if (init2 >= 0)
-                                       go2.Width = init2 + delta;
-                       } else {
-                               if (init1 >= 0)
-                                       go1.Height = init1 - delta;
-                               if (init2 >= 0)
-                                       go2.Height = init2 + delta;
-                       }
-               }
-               public override void onMouseUp (object sender, MouseButtonEventArgs e)
-               {
-                       base.onMouseUp (sender, e);
-
-                       GenericStack gs = Parent as GenericStack;
-
-                       if (init1 >= 0 && u1 == Unit.Percent) {
-                               if (gs.Orientation == Orientation.Horizontal)
-                                       go1.Width = new Measure ((int)Math.Ceiling (
-                                               go1.Width.Value * 100.0 / (double)gs.Slot.Width), Unit.Percent);
-                               else
-                                       go1.Height = new Measure ((int)Math.Ceiling (
-                                               go1.Height.Value * 100.0 / (double)gs.Slot.Height), Unit.Percent);
-                       }
-                       if (init2 >= 0 && u2 == Unit.Percent) {
-                               if (gs.Orientation == Orientation.Horizontal)
-                                       go2.Width = new Measure ((int)Math.Floor (
-                                               go2.Width.Value * 100.0 / (double)gs.Slot.Width), Unit.Percent);
-                               else
-                                       go2.Height = new Measure ((int)Math.Floor (
-                                               go2.Height.Value * 100.0 / (double)gs.Slot.Height), Unit.Percent);
-                       }
-               }
-               public override bool UpdateLayout (LayoutingType layoutType)
-               {
-                       GenericStack gs = Parent as GenericStack;
-                       if (layoutType == LayoutingType.Width){
-                               if (gs.Orientation == Orientation.Horizontal)
-                                       Width = thickness;
-                               else
-                                       Width = Measure.Stretched;
-                       } else if (layoutType == LayoutingType.Height){
-                               if (gs.Orientation == Orientation.Vertical)
-                                       Height = thickness;
-                               else
-                                       Height = Measure.Stretched;
-                       }
-                       return base.UpdateLayout (layoutType);
-               }
-               #endregion
-       }
-}
-
diff --git a/src/GraphicObjects/TabItem.cs b/src/GraphicObjects/TabItem.cs
deleted file mode 100644 (file)
index 7dac547..0000000
+++ /dev/null
@@ -1,210 +0,0 @@
-//
-// TabItem.cs
-//
-// Author:
-//       Jean-Philippe Bruyère <jp.bruyere@hotmail.com>
-//
-// Copyright (c) 2013-2017 Jean-Philippe Bruyère
-//
-// 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.Xml.Serialization;
-using System.ComponentModel;
-using System.Diagnostics;
-
-namespace Crow
-{
-       public class TabItem : TemplatedContainer
-       {
-               #region CTOR
-               public TabItem () : base() {}
-               #endregion
-
-               #region Private fields
-               string caption;
-               Container _contentContainer;
-               GraphicObject _tabTitle;
-               int tabOffset;
-               bool isSelected;
-               Measure tabThickness;
-               #endregion
-
-               #region TemplatedControl overrides
-               public override GraphicObject Content {
-                       get {
-                               return _contentContainer == null ? null : _contentContainer.Child;
-                       }
-                       set {
-                               if (Content != null) {
-                                       Content.LogicalParent = null;
-                                       _contentContainer.SetChild (null);
-                               }
-                               _contentContainer.SetChild(value);
-                               if (value != null)
-                                       value.LogicalParent = this;
-                       }
-               }
-               protected override void loadTemplate(GraphicObject template = null)
-               {
-                       base.loadTemplate (template);
-
-                       _contentContainer = this.child.FindByName ("Content") as Container;
-                       _tabTitle = this.child.FindByName ("TabTitle");
-               }
-               internal GraphicObject TabTitle { get { return _tabTitle; }}
-               #endregion
-
-               [XmlAttributeAttribute][DefaultValue("18")]
-               public virtual Measure TabThickness {
-                       get { return tabThickness; }
-                       set {
-                               if (tabThickness == value)
-                                       return;
-                               tabThickness = value;
-                               NotifyValueChanged ("TabThickness", tabThickness);
-                               RegisterForGraphicUpdate ();
-                       }
-               }
-               [XmlAttributeAttribute][DefaultValue(0)]
-               public virtual int TabOffset {
-                       get { return tabOffset; }
-                       set {
-                               if (tabOffset == value)
-                                       return;
-                               tabOffset = value;
-                               NotifyValueChanged ("TabOffset", tabOffset);
-
-                               RegisterForLayouting (LayoutingType.X);
-                               RegisterForGraphicUpdate ();
-                       }
-               }
-
-               [XmlAttributeAttribute][DefaultValue(false)]
-               public virtual bool IsSelected {
-                       get { return isSelected; }
-                       set {
-                               if (isSelected == value)
-                                       return;
-                               isSelected = value;
-                               NotifyValueChanged ("IsSelected", isSelected);
-                       }
-               }
-               protected override void onDraw (Cairo.Context gr)
-               {
-                       gr.Save ();
-
-                       int spacing = (Parent as TabView).Spacing;
-
-                       gr.MoveTo (0.5, TabTitle.Slot.Bottom-0.5);
-                       gr.LineTo (TabTitle.Slot.Left - spacing, TabTitle.Slot.Bottom-0.5);
-                       gr.CurveTo (
-                               TabTitle.Slot.Left - spacing / 2, TabTitle.Slot.Bottom-0.5,
-                               TabTitle.Slot.Left - spacing / 2, 0.5,
-                               TabTitle.Slot.Left, 0.5);
-                       gr.LineTo (TabTitle.Slot.Right, 0.5);
-                       gr.CurveTo (
-                               TabTitle.Slot.Right + spacing / 2, 0.5,
-                               TabTitle.Slot.Right + spacing / 2, TabTitle.Slot.Bottom-0.5,
-                               TabTitle.Slot.Right + spacing, TabTitle.Slot.Bottom-0.5);
-                       gr.LineTo (Slot.Width-0.5, TabTitle.Slot.Bottom-0.5);
-
-
-                       gr.LineTo (Slot.Width-0.5, Slot.Height-0.5);
-                       gr.LineTo (0.5, Slot.Height-0.5);
-                       gr.ClosePath ();
-                       gr.LineWidth = 2;
-                       Foreground.SetAsSource (gr);
-                       gr.StrokePreserve ();
-
-                       gr.Clip ();
-                       base.onDraw (gr);
-                       gr.Restore ();
-               }
-
-               #region Mouse Handling
-               public override bool MouseIsIn (Point m)
-               {
-                       if (!Visible)
-                               return false;
-
-                       bool mouseIsInTitle = TabTitle.ScreenCoordinates (TabTitle.Slot).ContainsOrIsEqual (m);
-                       if (!IsSelected)
-                               return mouseIsInTitle;
-
-                       return _contentContainer.ScreenCoordinates (_contentContainer.Slot).ContainsOrIsEqual (m)
-                               || mouseIsInTitle;
-               }
-               bool holdCursor = false;
-               public override void onMouseDown (object sender, MouseButtonEventArgs e)
-               {
-                       base.onMouseDown (sender, e);
-                       holdCursor = true;
-               }
-               public override void onMouseUp (object sender, MouseButtonEventArgs e)
-               {
-                       base.onMouseUp (sender, e);
-                       holdCursor = false;
-                       (Parent as TabView).UpdateLayout (LayoutingType.ArrangeChildren);
-               }
-               public override void onMouseMove (object sender, MouseMoveEventArgs e)
-               {
-                       base.onMouseMove (sender, e);
-
-                       if (!(HasFocus&&holdCursor))
-                               return;
-                       TabView tv = Parent as TabView;
-                       TabItem previous = null, next = null;
-                       int tmp = TabOffset + e.XDelta;
-                       if (tmp < tv.Spacing)
-                               TabOffset = tv.Spacing;
-                       else if (tmp > Parent.getSlot ().Width - TabTitle.Slot.Width - tv.Spacing)
-                               TabOffset = Parent.getSlot ().Width - TabTitle.Slot.Width - tv.Spacing;
-                       else{
-                               int idx = tv.Children.IndexOf (this);
-                               if (idx > 0 && e.XDelta < 0) {
-                                       previous = tv.Children [idx - 1] as TabItem;
-
-                                       if (tmp < previous.TabOffset + previous.TabTitle.Slot.Width / 2) {
-                                               tv.Children.RemoveAt (idx);
-                                               tv.Children.Insert (idx - 1, this);
-                                               tv.SelectedTab = idx - 1;
-                                               tv.UpdateLayout (LayoutingType.ArrangeChildren);
-                                       }
-
-                               }else if (idx < tv.Children.Count - 1 && e.XDelta > 0) {
-                                       next = tv.Children [idx + 1] as TabItem;
-                                       if (tmp > next.TabOffset - next.TabTitle.Slot.Width / 2){
-                                               tv.Children.RemoveAt (idx);
-                                               tv.Children.Insert (idx + 1, this);
-                                               tv.SelectedTab = idx + 1;
-                                               tv.UpdateLayout (LayoutingType.ArrangeChildren);
-                                       }
-                               }
-                               TabOffset = tmp;
-                       }
-               }
-               public void butCloseTabClick (object sender, MouseButtonEventArgs e){
-                       (Parent as TabView).RemoveChild(this);
-               }
-               #endregion
-
-       }
-}
-
diff --git a/src/GraphicObjects/TabView.cs b/src/GraphicObjects/TabView.cs
deleted file mode 100644 (file)
index ecf38f1..0000000
+++ /dev/null
@@ -1,210 +0,0 @@
-//
-// TabView.cs
-//
-// Author:
-//       Jean-Philippe Bruyère <jp.bruyere@hotmail.com>
-//
-// Copyright (c) 2013-2017 Jean-Philippe Bruyère
-//
-// 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.Xml.Serialization;
-using System.ComponentModel;
-using Cairo;
-using System.Diagnostics;
-
-namespace Crow
-{      
-       public class TabView : Group
-       {
-               #region CTOR
-               public TabView () : base() {}
-               #endregion
-
-               #region Private fields
-               int _spacing;
-               Measure tabThickness;
-               Orientation _orientation;
-               int selectedTab = 0;
-               #endregion
-
-
-               #region public properties
-               [XmlAttributeAttribute()][DefaultValue(Orientation.Horizontal)]
-               public virtual Orientation Orientation
-               {
-                       get { return _orientation; }
-                       set {
-                               if (_orientation == value)
-                                       return;
-                               _orientation = value;
-                               NotifyValueChanged ("Orientation", _orientation);
-                               if (_orientation == Orientation.Horizontal)
-                                       NotifyValueChanged ("TabOrientation", Orientation.Vertical);
-                               else
-                                       NotifyValueChanged ("TabOrientation", Orientation.Horizontal);
-                       }
-               }
-               [XmlAttributeAttribute()][DefaultValue(16)]
-               public int Spacing
-               {
-                       get { return _spacing; }
-                       set {
-                               if (_spacing == value)
-                                       return;
-                               _spacing = value;
-                               NotifyValueChanged ("Spacing", Spacing);
-                       }
-               }
-               [XmlAttributeAttribute()][DefaultValue(0)]
-               public virtual int SelectedTab {
-                       get { return selectedTab; }
-                       set {
-                               if (selectedTab < Children.Count && SelectedTab >= 0)
-                                       (Children [selectedTab] as TabItem).IsSelected = false;
-
-                               selectedTab = value;
-
-                               if (selectedTab < Children.Count && SelectedTab >= 0)
-                                       (Children [selectedTab] as TabItem).IsSelected = true;
-
-                               NotifyValueChanged ("SelectedTab", selectedTab);
-                               RegisterForRedraw ();
-                       }
-               }
-               #endregion
-
-               public override void AddChild (GraphicObject child)
-               {
-                       TabItem ti = child as TabItem;
-                       if (ti == null)
-                               throw new Exception ("TabView control accept only TabItem as child.");
-
-                       ti.MouseDown += Ti_MouseDown;
-
-                       if (Children.Count == 0) {
-                               ti.IsSelected = true;
-                               SelectedTab = 0;
-                       }
-
-                       base.AddChild (child);
-               }
-               public override void RemoveChild (GraphicObject child)
-               {
-                       base.RemoveChild (child);
-                       if (selectedTab > Children.Count - 1)
-                               SelectedTab--;
-                       else
-                               SelectedTab = selectedTab;
-               }
-               public override bool ArrangeChildren { get { return true; } }
-               public override bool UpdateLayout (LayoutingType layoutType)
-               {
-                       RegisteredLayoutings &= (~layoutType);
-
-                       if (layoutType == LayoutingType.ArrangeChildren) {
-                               int curOffset = Spacing;
-                               for (int i = 0; i < Children.Count; i++) {
-                                       if (!Children [i].Visible)
-                                               continue;
-                                       TabItem ti = Children [i] as TabItem;
-                                       ti.TabOffset = curOffset;
-                                       if (Orientation == Orientation.Horizontal) {
-                                               if (ti.TabTitle.RegisteredLayoutings.HasFlag (LayoutingType.Width))
-                                                       return false;
-                                               curOffset += ti.TabTitle.Slot.Width + Spacing;
-                                       } else {
-                                               if (ti.TabTitle.RegisteredLayoutings.HasFlag (LayoutingType.Height))
-                                                       return false;
-                                               curOffset += ti.TabTitle.Slot.Height + Spacing;
-                                       }
-                               }
-
-                               //if no layouting remains in queue for item, registre for redraw
-                               if (RegisteredLayoutings == LayoutingType.None && IsDirty)
-                                       CurrentInterface.EnqueueForRepaint (this);
-
-                               return true;
-                       }
-
-                       return base.UpdateLayout(layoutType);
-               }
-               protected override void onDraw (Context gr)
-               {
-                       Rectangle rBack = new Rectangle (Slot.Size);
-
-                       Background.SetAsSource (gr, rBack);
-                       CairoHelpers.CairoRectangle(gr,rBack, CornerRadius);
-                       gr.Fill ();
-
-                       gr.Save ();
-
-                       if (ClipToClientRect) {
-                               //clip to client zone
-                               CairoHelpers.CairoRectangle (gr, ClientRectangle, CornerRadius);
-                               gr.Clip ();
-                       }
-
-                       for (int i = 0; i < Children.Count; i++) {
-                               if (i == SelectedTab)
-                                       continue;
-                               Children [i].Paint (ref gr);
-                       }
-
-                       if (SelectedTab < Children.Count && SelectedTab >= 0)
-                               Children [SelectedTab].Paint (ref gr);
-
-                       gr.Restore ();
-               }
-
-               #region Mouse handling
-               public override void checkHoverWidget (MouseMoveEventArgs e)
-               {
-                       if (CurrentInterface.HoverWidget != this) {
-                               CurrentInterface.HoverWidget = this;
-                               onMouseEnter (this, e);
-                       }
-
-                       if (SelectedTab > Children.Count - 1)
-                               return;
-
-                       if (((Children[SelectedTab] as TabItem).Content.Parent as GraphicObject).MouseIsIn(e.Position))
-                       {
-                               Children[SelectedTab].checkHoverWidget (e);
-                               return;
-                       }
-                       for (int i = Children.Count - 1; i >= 0; i--) {
-                               TabItem ti = Children [i] as TabItem;
-                               if (ti.TabTitle.MouseIsIn(e.Position))
-                               {
-                                       Children[i].checkHoverWidget (e);
-                                       return;
-                               }
-                       }
-               }
-               #endregion
-
-               void Ti_MouseDown (object sender, MouseButtonEventArgs e)
-               {
-                       SelectedTab = Children.IndexOf (sender as GraphicObject);
-               }
-       }
-}
-
diff --git a/src/GraphicObjects/TemplatedContainer.cs b/src/GraphicObjects/TemplatedContainer.cs
deleted file mode 100644 (file)
index 1ab8cf7..0000000
+++ /dev/null
@@ -1,128 +0,0 @@
-//
-// TemplatedContainer.cs
-//
-// Author:
-//       Jean-Philippe Bruyère <jp.bruyere@hotmail.com>
-//
-// Copyright (c) 2013-2017 Jean-Philippe Bruyère
-//
-// 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.Xml.Serialization;
-using System.Xml;
-using System.Reflection;
-
-namespace Crow
-{
-       public abstract class TemplatedContainer : TemplatedControl
-       {
-               #region CTOR
-               public TemplatedContainer () : base(){}
-               #endregion
-
-               [XmlAttributeAttribute]public virtual GraphicObject Content{ get; set;}
-
-               #region GraphicObject overrides
-               public override GraphicObject FindByName (string nameToFind)
-               {
-                       if (Name == nameToFind)
-                               return this;
-
-                       return Content == null ? null : Content.FindByName (nameToFind);
-               }
-               public override bool Contains (GraphicObject goToFind)
-               {
-                       if (Content == null)
-                               return base.Contains (goToFind);
-
-                       if (Content == goToFind)
-                               return true;
-                       return Content.Contains (goToFind);
-               }
-               #endregion
-
-               #region IXmlSerialisation Overrides
-               public override void ReadXml(System.Xml.XmlReader reader)
-               {
-                       using (System.Xml.XmlReader subTree = reader.ReadSubtree ()) {
-                               subTree.Read ();
-                               string tmp = subTree.ReadOuterXml ();
-
-                               //seek for template tag
-                               using (XmlReader xr = new XmlTextReader (tmp, XmlNodeType.Element, null)) {
-                                       xr.Read ();
-                                       base.ReadXml (xr);
-                               }
-                               //process content
-                               using (XmlReader xr = new XmlTextReader (tmp, XmlNodeType.Element, null)) {
-                                       xr.Read (); //skip current node
-
-                                       while (!xr.EOF) {
-                                               xr.Read (); //read first child
-
-                                               if (!xr.IsStartElement ())
-                                                       continue;
-
-                                               if (xr.Name == "Template"){
-                                                       xr.Skip ();
-                                                       if (!xr.IsStartElement ())
-                                                               continue;
-                                               }
-
-                                               Type t = Type.GetType ("Crow." + xr.Name);
-                                               if (t == null) {
-                                                       Assembly a = Assembly.GetEntryAssembly ();
-                                                       foreach (Type expT in a.GetExportedTypes ()) {
-                                                               if (expT.Name == xr.Name) {
-                                                                       t = expT;
-                                                                       break;
-                                                               }
-                                                       }
-                                               }
-                                               if (t == null)
-                                                       throw new Exception (xr.Name + " type not found");
-
-                                               GraphicObject go = (GraphicObject)Activator.CreateInstance (t);
-
-                                               (go as IXmlSerializable).ReadXml (xr);
-
-                                               Content = go;
-
-                                               xr.Read (); //closing tag
-                                       }
-
-                               }
-                       }
-               }
-               public override void WriteXml(System.Xml.XmlWriter writer)
-               {
-                       base.WriteXml(writer);
-
-                       if (Content == null)
-                               return;
-                       //TODO: if template is not the default one, we have to save it
-                       writer.WriteStartElement(Content.GetType().Name);
-                       (Content as IXmlSerializable).WriteXml(writer);
-                       writer.WriteEndElement();
-               }
-               #endregion
-       }
-}
-
diff --git a/src/GraphicObjects/TemplatedControl.cs b/src/GraphicObjects/TemplatedControl.cs
deleted file mode 100644 (file)
index 082d042..0000000
+++ /dev/null
@@ -1,210 +0,0 @@
-//
-// TemplatedControl.cs
-//
-// Author:
-//       Jean-Philippe Bruyère <jp.bruyere@hotmail.com>
-//
-// Copyright (c) 2013-2017 Jean-Philippe Bruyère
-//
-// 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.Xml.Serialization;
-using System.ComponentModel;
-using System.IO;
-using System.Xml;
-using System.Diagnostics;
-using System.Linq;
-using System.Collections.Generic;
-using System.Text;
-using System.Reflection;
-
-namespace Crow
-{
-       public abstract class TemplatedControl : PrivateContainer, IXmlSerializable
-       {
-               #region CTOR
-               public TemplatedControl () : base()
-               {
-               }
-               #endregion
-
-               string _template;
-               string caption;
-
-               [XmlAttributeAttribute][DefaultValue(null)]
-               public string Template {
-                       get { return _template; }
-                       set {
-                               if (Template == value)
-                                       return;
-                               _template = value;
-
-                               if (string.IsNullOrEmpty(_template))
-                                       loadTemplate ();
-                               else
-                                       loadTemplate (CurrentInterface.Load (_template));
-                       }
-               }
-               [XmlAttributeAttribute()][DefaultValue("Templated Control")]
-               public virtual string Caption {
-                       get { return caption; }
-                       set {
-                               if (caption == value)
-                                       return;
-                               caption = value;
-                               NotifyValueChanged ("Caption", caption);
-                       }
-               }
-               #region GraphicObject overrides
-               public override void Initialize ()
-               {
-                       loadTemplate ();
-                       base.Initialize ();
-               }
-               public override GraphicObject FindByName (string nameToFind)
-               {
-                       //prevent name searching in template
-                       return nameToFind == this.Name ? this : null;
-               }
-               protected override void onDraw (Cairo.Context gr)
-               {
-                       //onDraw is overrided to prevent default drawing of background, template top container
-                       //may have a binding to root background or a fixed one.
-                       //this allow applying root background to random template's component
-                       gr.Save ();
-
-                       if (ClipToClientRect) {
-                               //clip to client zone
-                               CairoHelpers.CairoRectangle (gr, ClientRectangle, CornerRadius);
-                               gr.Clip ();
-                       }
-
-                       if (child != null)
-                               child.Paint (ref gr);
-                       gr.Restore ();
-               }
-               #endregion
-
-               protected virtual void loadTemplate(GraphicObject template = null)
-               {
-                       if (template == null) {
-                               if (!Interface.DefaultTemplates.ContainsKey (this.GetType ().FullName))
-                                       throw new Exception (string.Format ("No default template found for '{0}'", this.GetType ().FullName));
-                               this.SetChild (CurrentInterface.Load (Interface.DefaultTemplates[this.GetType ().FullName]));
-                       }else
-                               this.SetChild (template);
-               }
-
-               //TODO:IXmlSerializable is not used anymore
-               #region IXmlSerializable
-               public override System.Xml.Schema.XmlSchema GetSchema(){ return null; }
-               public override void ReadXml(System.Xml.XmlReader reader)
-               {
-                       //Template could be either an attribute containing path or expressed inlined
-                       //as a Template Element
-                       using (System.Xml.XmlReader subTree = reader.ReadSubtree())
-                       {
-                               subTree.Read ();
-
-                               string template = reader.GetAttribute ("Template");
-                               string tmp = subTree.ReadOuterXml ();
-
-                               //Load template from path set as attribute in templated control
-                               if (string.IsNullOrEmpty (template)) {
-                                       //seek for template tag first
-                                       using (XmlReader xr = new XmlTextReader (tmp, XmlNodeType.Element, null)) {
-                                               //load template first if inlined
-
-                                               xr.Read (); //read first child
-                                               xr.Read (); //skip root node
-
-                                               while (!xr.EOF) {
-                                                       if (!xr.IsStartElement ()) {
-                                                               xr.Read ();
-                                                               continue;
-                                                       }
-                                                       if (xr.Name == "ItemTemplate") {
-                                                               string dataType = "default", datas = "", itemTmp;
-                                                               while (xr.MoveToNextAttribute ()) {
-                                                                       if (xr.Name == "DataType")
-                                                                               dataType = xr.Value;
-                                                                       else if (xr.Name == "Data")
-                                                                               datas = xr.Value;
-                                                               }
-                                                               xr.MoveToElement ();
-                                                               itemTmp = xr.ReadInnerXml ();
-
-//                                                             if (ItemTemplates == null)
-//                                                                     ItemTemplates = new Dictionary<string, ItemTemplate> ();
-//
-//                                                             using (IMLReader iTmp = new IMLReader (null, itemTmp)) {
-//                                                                     ItemTemplates [dataType] =
-//                                                                             new ItemTemplate (iTmp.RootType, iTmp.GetLoader (), dataType, datas);
-//                                                             }
-//                                                             if (!string.IsNullOrEmpty (datas))
-//                                                                     ItemTemplates [dataType].CreateExpandDelegate(this);
-
-                                                               continue;
-                                                       }
-                                                       if (xr.Name == "Template") {
-                                                               xr.Read ();
-
-                                                               Type t = Type.GetType ("Crow." + xr.Name);
-                                                               if (t == null) {
-                                                                       Assembly a = Assembly.GetEntryAssembly ();
-                                                                       foreach (Type expT in a.GetExportedTypes ()) {
-                                                                               if (expT.Name == xr.Name) {
-                                                                                       t = expT;
-                                                                                       break;
-                                                                               }
-                                                                       }
-                                                               }
-                                                               GraphicObject go = (GraphicObject)Activator.CreateInstance (t);
-                                                               (go as IXmlSerializable).ReadXml (xr);
-
-                                                               loadTemplate (go);
-                                                               continue;
-                                                       }
-                                                       xr.ReadInnerXml ();
-                                               }
-                                       }
-                               } else
-                                       loadTemplate (CurrentInterface.Load (template));
-
-                               //if no template found, load default one
-                               if (this.child == null)
-                                       loadTemplate ();
-
-                               //normal xml read
-                               using (XmlReader xr = new XmlTextReader (tmp, XmlNodeType.Element, null)) {
-                                       xr.Read ();
-                                       base.ReadXml(xr);
-                               }
-                       }
-               }
-               public override void WriteXml(System.Xml.XmlWriter writer)
-               {
-                       //TODO:
-                       throw new NotImplementedException();
-               }
-               #endregion
-       }
-}
-
diff --git a/src/GraphicObjects/TemplatedGroup.cs b/src/GraphicObjects/TemplatedGroup.cs
deleted file mode 100644 (file)
index e444716..0000000
+++ /dev/null
@@ -1,489 +0,0 @@
-//
-// TemplatedGroup.cs
-//
-// Author:
-//       Jean-Philippe Bruyère <jp.bruyere@hotmail.com>
-//
-// Copyright (c) 2013-2017 Jean-Philippe Bruyère
-//
-// 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.Xml.Serialization;
-using System.Xml;
-using System.Reflection;
-using System.Collections.Generic;
-using System.ComponentModel;
-using System.Collections;
-using System.Threading;
-using System.Linq;
-
-namespace Crow
-{
-       public abstract class TemplatedGroup : TemplatedControl
-       {
-               #region CTOR
-               public TemplatedGroup () : base(){}
-               #endregion
-
-               protected Group items;
-               string _itemTemplate, _dataTest;
-
-               #region events
-               public event EventHandler<SelectionChangeEventArgs> SelectedItemChanged;
-               public event EventHandler Loaded;
-               #endregion
-
-               IList data;
-               int _selectedIndex = -1;
-               Color selBackground, selForeground;
-
-               int itemPerPage = 50;
-               CrowThread loadingThread = null;
-               volatile bool cancelLoading = false;
-
-               bool isPaged = false;
-
-               #region Templating
-               //TODO: dont instantiate ItemTemplates if not used
-               //but then i should test if null in msil gen
-               public Dictionary<string, ItemTemplate> ItemTemplates = new Dictionary<string, Crow.ItemTemplate>();
-
-               /// <summary>
-               /// Default item template
-               /// </summary>
-               [XmlAttributeAttribute][DefaultValue("#Crow.Templates.ItemTemplate.goml")]
-               public string ItemTemplate {
-                       get { return _itemTemplate; }
-                       set {
-                               if (value == _itemTemplate)
-                                       return;
-
-                               _itemTemplate = value;
-
-                               //TODO:reload list with new template?
-                               NotifyValueChanged("ItemTemplate", _itemTemplate);
-                       }
-               }
-               protected override void loadTemplate(GraphicObject template = null)
-               {
-                       base.loadTemplate (template);
-
-                       items = this.child.FindByName ("ItemsContainer") as Group;
-                       if (items == null)
-                               throw new Exception ("TemplatedGroup template Must contain a Group named 'ItemsContainer'");
-                       if (items.Children.Count == 0)
-                               NotifyValueChanged ("HasChildren", false);
-                       else
-                               NotifyValueChanged ("HasChildren", true);
-               }
-               /// <summary>
-               /// Use to define condition on Data item for selecting among ItemTemplates.
-               /// Default value is 'TypeOf' for selecting Template depending on Type of Data.
-               /// Other possible values are properties of Data
-               /// </summary>
-               /// <value>The data property test.</value>
-               [XmlAttributeAttribute][DefaultValue("TypeOf")]
-               public string DataTest {
-                       get { return _dataTest; }
-                       set {
-                               if (value == _dataTest)
-                                       return;
-
-                               _dataTest = value;
-
-                               NotifyValueChanged("DataTest", _dataTest);
-                       }
-               }
-               #endregion
-
-               public virtual List<GraphicObject> Items{
-                       get {
-                               return isPaged ? items.Children.SelectMany(x => (x as Group).Children).ToList()
-                               : items.Children;
-                       }
-               }
-               [XmlAttributeAttribute][DefaultValue(-1)]public int SelectedIndex{
-                       get { return _selectedIndex; }
-                       set {
-                               if (value == _selectedIndex)
-                                       return;
-
-                               if (_selectedIndex >= 0 && Items.Count > _selectedIndex) {
-                                       Items[_selectedIndex].Foreground = Color.Transparent;
-                                       Items[_selectedIndex].Background = Color.Transparent;
-                               }
-
-                               _selectedIndex = value;
-
-                               if (_selectedIndex >= 0 && Items.Count > _selectedIndex) {
-                                       Items[_selectedIndex].Foreground = SelectionForeground;
-                                       Items[_selectedIndex].Background = SelectionBackground;
-                               }
-
-                               NotifyValueChanged ("SelectedIndex", _selectedIndex);
-                               NotifyValueChanged ("SelectedItem", SelectedItem);
-                               SelectedItemChanged.Raise (this, new SelectionChangeEventArgs (SelectedItem));
-                       }
-               }
-               [XmlIgnore]public virtual object SelectedItem{
-                       get { return data == null ? null : _selectedIndex < 0 ? null : data[_selectedIndex]; }
-               }
-               [XmlIgnore]public bool HasItems {
-                       get { return Items.Count > 0; }
-               }
-               [XmlAttributeAttribute]public IList Data {
-                       get { return data; }
-                       set {
-                               if (value == data)
-                                       return;
-
-                               cancelLoadingThread ();
-
-                               data = value;
-
-                               NotifyValueChanged ("Data", data);
-
-                               lock (CurrentInterface.LayoutMutex)
-                                       ClearItems ();
-
-                               if (data == null)
-                                       return;
-
-                               loadingThread = new CrowThread (this, loading);
-                               loadingThread.Finished += (object sender, EventArgs e) => (sender as TemplatedGroup).Loaded.Raise (sender, e);
-                               loadingThread.Start ();
-
-                               NotifyValueChanged ("SelectedIndex", _selectedIndex);
-                               NotifyValueChanged ("SelectedItem", SelectedItem);
-                               SelectedItemChanged.Raise (this, new SelectionChangeEventArgs (SelectedItem));
-                               NotifyValueChanged ("HasItems", HasItems);
-                       }
-               }
-
-               [XmlAttributeAttribute][DefaultValue("SteelBlue")]
-               public virtual Color SelectionBackground {
-                       get { return selBackground; }
-                       set {
-                               if (value == selBackground)
-                                       return;
-                               selBackground = value;
-                               NotifyValueChanged ("SelectionBackground", selBackground);
-                               RegisterForRedraw ();
-                       }
-               }
-               [XmlAttributeAttribute][DefaultValue("White")]
-               public virtual Color SelectionForeground {
-                       get { return selForeground; }
-                       set {
-                               if (value == selForeground)
-                                       return;
-                               selForeground = value;
-                               NotifyValueChanged ("SelectionForeground", selForeground);
-                               RegisterForRedraw ();
-                       }
-               }
-
-               protected void raiseSelectedItemChanged(){
-                       SelectedItemChanged.Raise (this, new SelectionChangeEventArgs (SelectedItem));
-               }
-
-
-               public virtual void AddItem(GraphicObject g){
-                       items.AddChild (g);
-                       g.LogicalParent = this;
-                       NotifyValueChanged ("HasChildren", true);
-               }
-               public virtual void RemoveItem(GraphicObject g)
-               {
-                       g.LogicalParent = null;
-                       items.RemoveChild (g);
-                       if (items.Children.Count == 0)
-                               NotifyValueChanged ("HasChildren", false);
-               }
-
-               public virtual void ClearItems()
-               {
-                       _selectedIndex = -1;
-                       NotifyValueChanged ("SelectedIndex", _selectedIndex);
-                       NotifyValueChanged ("SelectedItem", null);
-
-                       items.ClearChildren ();
-                       NotifyValueChanged ("HasChildren", false);
-               }
-
-
-               #region GraphicObject overrides
-               public override GraphicObject FindByName (string nameToFind)
-               {
-                       if (Name == nameToFind)
-                               return this;
-
-                       foreach (GraphicObject w in Items) {
-                               GraphicObject r = w.FindByName (nameToFind);
-                               if (r != null)
-                                       return r;
-                       }
-                       return null;
-               }
-               public override bool Contains (GraphicObject goToFind)
-               {
-                       foreach (GraphicObject w in Items) {
-                               if (w == goToFind)
-                                       return true;
-                               if (w.Contains (goToFind))
-                                       return true;
-                       }
-                       return base.Contains(goToFind);
-               }
-//             public override void ClearBinding ()
-//             {
-//                     if (items != null)
-//                             items.ClearBinding ();
-//
-//                     base.ClearBinding ();
-//             }
-//             public override void ResolveBindings ()
-//             {
-//                     base.ResolveBindings ();
-//                     if (items != null)
-//                             items.ResolveBindings ();
-//             }
-               #endregion
-
-               #region IXmlSerialisation Overrides
-               public override void ReadXml(System.Xml.XmlReader reader)
-               {
-                       using (System.Xml.XmlReader subTree = reader.ReadSubtree ()) {
-                               subTree.Read ();
-                               string tmp = subTree.ReadOuterXml ();
-
-                               //seek for template tag
-                               using (XmlReader xr = new XmlTextReader (tmp, XmlNodeType.Element, null)) {
-                                       xr.Read ();
-                                       base.ReadXml (xr);
-                               }
-                               //process content
-                               using (XmlReader xr = new XmlTextReader (tmp, XmlNodeType.Element, null)) {
-                                       xr.Read (); //skip current node
-
-                                       while (!xr.EOF) {
-                                               xr.Read (); //read first child
-
-                                               if (!xr.IsStartElement ())
-                                                       continue;
-
-                                               if (xr.Name == "Template" || Name == "ItemTemplate"){
-                                                       xr.Skip ();
-                                                       if (!xr.IsStartElement ())
-                                                               continue;
-                                               }
-
-                                               Type t = Type.GetType ("Crow." + xr.Name);
-                                               if (t == null) {
-                                                       Assembly a = Assembly.GetEntryAssembly ();
-                                                       foreach (Type expT in a.GetExportedTypes ()) {
-                                                               if (expT.Name == xr.Name) {
-                                                                       t = expT;
-                                                                       break;
-                                                               }
-                                                       }
-                                               }
-                                               if (t == null)
-                                                       throw new Exception (xr.Name + " type not found");
-
-                                               GraphicObject go = (GraphicObject)Activator.CreateInstance (t);
-
-                                               (go as IXmlSerializable).ReadXml (xr);
-
-                                               AddItem (go);
-
-                                               xr.Read (); //closing tag
-                                       }
-
-                               }
-                       }
-               }
-               public override void WriteXml(System.Xml.XmlWriter writer)
-               {
-                       throw new NotImplementedException ();
-               }
-               #endregion
-
-               void loading(){
-                       if (ItemTemplates == null)
-                               ItemTemplates = new Dictionary<string, ItemTemplate> ();
-                       if (!ItemTemplates.ContainsKey ("default"))
-                               ItemTemplates ["default"] = Interface.GetItemTemplate (ItemTemplate);
-
-                       for (int i = 1; i <= (data.Count / itemPerPage) + 1; i++) {
-                               if (cancelLoading)
-                                       return;
-                               loadPage (i);
-                               Thread.Sleep (1);
-                       }
-               }
-               void cancelLoadingThread(){
-                       if (loadingThread != null)
-                               loadingThread.Cancel ();
-               }
-               void loadPage(int pageNum)
-               {
-                       #if DEBUG_LOAD
-                       Stopwatch loadingTime = new Stopwatch ();
-                       loadingTime.Start ();
-                       #endif
-
-                       Group page;
-                       if (typeof(Wrapper).IsAssignableFrom (items.GetType ())) {
-                               page = items;
-                               itemPerPage = int.MaxValue;
-                       } else if (typeof(GenericStack).IsAssignableFrom (items.GetType ())) {
-                               GenericStack gs = new GenericStack ();
-                               gs.CurrentInterface = items.CurrentInterface;
-                               gs.Initialize ();
-                               gs.Orientation = (items as GenericStack).Orientation;
-                               gs.Width = items.Width;
-                               gs.Height = items.Height;
-                               gs.VerticalAlignment = items.VerticalAlignment;
-                               gs.HorizontalAlignment = items.HorizontalAlignment;
-                               page = gs;
-                               page.Name = "page" + pageNum;
-                               isPaged = true;
-                       } else {
-                               page = Activator.CreateInstance (items.GetType ()) as Group;
-                               page.Name = "page" + pageNum;
-                               isPaged = true;
-                       }
-
-                       for (int i = (pageNum - 1) * itemPerPage; i < pageNum * itemPerPage; i++) {
-                               if (i >= data.Count)
-                                       break;
-                               if (cancelLoading)
-                                       return;
-
-                               loadItem (i, page);
-                       }
-
-                       if (page == items)
-                               return;
-                       lock (CurrentInterface.LayoutMutex)
-                               items.AddChild (page);
-
-                       #if DEBUG_LOAD
-                       loadingTime.Stop ();
-                       Debug.WriteLine("Listbox {2} Loading: {0} ticks \t, {1} ms",
-                       loadingTime.ElapsedTicks,
-                       loadingTime.ElapsedMilliseconds, this.ToString());
-                       #endif
-               }
-               string getItempKey(Type dataType, object o){
-                       try {
-                               return dataType.GetProperty (_dataTest).GetGetMethod ().Invoke (o, null).ToString();
-                       } catch (Exception ex) {
-                               return dataType.FullName;
-                       }
-               }
-               protected void loadItem(int i, Group page){
-                       if (data [i] == null)//TODO:surely a threading sync problem
-                               return;
-                       GraphicObject g = null;
-                       ItemTemplate iTemp = null;
-                       Type dataType = data [i].GetType ();
-                       string itempKey = dataType.FullName;
-
-                       if (_dataTest != "TypeOf")
-                               itempKey = getItempKey (dataType, data [i]);
-
-                       if (ItemTemplates.ContainsKey (itempKey))
-                               iTemp = ItemTemplates [itempKey];
-                       else {
-                               foreach (string it in ItemTemplates.Keys) {
-                                       Type t = Type.GetType (it);
-                                       if (t == null) {
-                                               Assembly a = Assembly.GetEntryAssembly ();
-                                               foreach (Type expT in a.GetExportedTypes ()) {
-                                                       if (expT.Name == it) {
-                                                               t = expT;
-                                                               break;
-                                                       }
-                                               }
-                                       }
-                                       if (t == null)
-                                               continue;
-                                       if (t.IsAssignableFrom (dataType)) {//TODO:types could be cached
-                                               iTemp = ItemTemplates [it];
-                                               break;
-                                       }
-                               }
-                               if (iTemp == null)
-                                       iTemp = ItemTemplates ["default"];
-                       }
-
-                       lock (CurrentInterface.LayoutMutex) {
-                               g = iTemp.CreateInstance(CurrentInterface);
-                               page.AddChild (g);
-                               //g.LogicalParent = this;
-                               registerItemClick (g);
-                       }
-
-                       if (iTemp.Expand != null && g is Expandable) {
-                               (g as Expandable).Expand += iTemp.Expand;
-                               (g as Expandable).GetIsExpandable = iTemp.HasSubItems;
-                       }
-
-                       g.DataSource = data [i];
-               }
-               protected virtual void registerItemClick(GraphicObject g){
-                       g.MouseClick += itemClick;
-               }
-//             protected void _list_LayoutChanged (object sender, LayoutingEventArgs e)
-//             {
-//                     #if DEBUG_LAYOUTING
-//                     Debug.WriteLine("list_LayoutChanged");
-//                     #endif
-//                     if (_gsList.Orientation == Orientation.Horizontal) {
-//                             if (e.LayoutType == LayoutingType.Width)
-//                                     _gsList.Width = approxSize;
-//                     } else if (e.LayoutType == LayoutingType.Height)
-//                             _gsList.Height = approxSize;
-//             }
-               int approxSize
-               {
-                       get {
-                               if (data == null)
-                                       return -1;
-                               GenericStack page1 = items.FindByName ("page1") as GenericStack;
-                               if (page1 == null)
-                                       return -1;
-
-                               return page1.Orientation == Orientation.Horizontal ?
-                                       data.Count < itemPerPage ?
-                                       -1:
-                                       (int)Math.Ceiling ((double)page1.Slot.Width / (double)itemPerPage * (double)(data.Count+1)):
-                                       data.Count < itemPerPage ?
-                                       -1:
-                                       (int)Math.Ceiling ((double)page1.Slot.Height / (double)itemPerPage * (double)(data.Count+1));
-                       }
-               }
-               internal virtual void itemClick(object sender, MouseButtonEventArgs e){
-                       SelectedIndex = data.IndexOf((sender as GraphicObject).DataSource);
-               }
-       }
-}
diff --git a/src/GraphicObjects/TextBox.cs b/src/GraphicObjects/TextBox.cs
deleted file mode 100644 (file)
index 0cbee9f..0000000
+++ /dev/null
@@ -1,228 +0,0 @@
-//
-// TextBox.cs
-//
-// Author:
-//       Jean-Philippe Bruyère <jp.bruyere@hotmail.com>
-//
-// Copyright (c) 2013-2017 Jean-Philippe Bruyère
-//
-// 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 Cairo;
-using System.Diagnostics;
-using System.Xml.Serialization;
-
-namespace Crow
-{
-    public class TextBox : Label
-    {
-               #region CTOR
-               public TextBox()
-               { }
-               public TextBox(string _initialValue)
-                       : base(_initialValue)
-               {
-
-               }
-               #endregion
-
-               #region GraphicObject overrides
-               [XmlIgnore]public override bool HasFocus   //trigger update when lost focus to errase text beam
-        {
-            get
-            {
-                return base.HasFocus;
-            }
-            set
-            {
-                base.HasFocus = value;
-                RegisterForRedraw();
-            }
-        }
-
-               protected override void onDraw (Context gr)
-               {
-                       base.onDraw (gr);
-                       FontExtents fe = gr.FontExtents;
-               }
-               #endregion
-                       
-        #region Keyboard handling
-               public override void onKeyDown (object sender, KeyboardKeyEventArgs e)
-               {
-                       base.onKeyDown (sender, e);
-
-                       Key key = e.Key;
-
-                       switch (key)
-                       {
-                       case Key.Back:
-                               if (CurrentPosition == 0)
-                                       return;
-                               this.DeleteChar();
-                               break;
-                       case Key.Clear:
-                               break;
-                       case Key.Delete:
-                               if (selectionIsEmpty) {
-                                       if (!MoveRight ())
-                                               return;
-                               }else if (e.Shift)
-                                       CurrentInterface.Clipboard = this.SelectedText;
-                               this.DeleteChar ();
-                               break;
-                       case Key.Enter:
-                       case Key.KeypadEnter:
-                               if (!selectionIsEmpty)
-                                       this.DeleteChar ();
-                               if (Multiline)
-                                       this.InsertLineBreak ();
-                               else
-                                       OnTextChanged(this,new TextChangeEventArgs(Text));
-                               break;
-                       case Key.Escape:
-                               Text = "";
-                               CurrentColumn = 0;
-                               SelRelease = -1;
-                               break;
-                       case Key.Home:
-                               if (e.Shift) {
-                                       if (selectionIsEmpty)
-                                               SelBegin = new Point (CurrentColumn, CurrentLine);
-                                       if (e.Control)
-                                               CurrentLine = 0;
-                                       CurrentColumn = 0;
-                                       SelRelease = new Point (CurrentColumn, CurrentLine);
-                                       break;
-                               }
-                               SelRelease = -1;
-                               if (e.Control)
-                                       CurrentLine = 0;
-                               CurrentColumn = 0;
-                               break;
-                       case Key.End:
-                               if (e.Shift) {
-                                       if (selectionIsEmpty)
-                                               SelBegin = CurrentPosition;
-                                       if (e.Control)
-                                               CurrentLine = int.MaxValue;
-                                       CurrentColumn = int.MaxValue;
-                                       SelRelease = CurrentPosition;
-                                       break;
-                               }
-                               SelRelease = -1;
-                               if (e.Control)
-                                       CurrentLine = int.MaxValue;
-                               CurrentColumn = int.MaxValue;
-                               break;
-                       case Key.Insert:
-                               if (e.Shift)
-                                       this.Insert (CurrentInterface.Clipboard);
-                               else if (e.Control && !selectionIsEmpty)
-                                       CurrentInterface.Clipboard = this.SelectedText;
-                               break;
-                       case Key.Left:
-                               if (e.Shift) {
-                                       if (selectionIsEmpty)
-                                               SelBegin = new Point(CurrentColumn, CurrentLine);
-                                       if (e.Control)
-                                               GotoWordStart ();
-                                       else if (!MoveLeft ())
-                                               return;
-                                       SelRelease = CurrentPosition;
-                                       break;
-                               }
-                               SelRelease = -1;
-                               if (e.Control)
-                                       GotoWordStart ();
-                               else
-                                       MoveLeft();
-                               break;
-                       case Key.Right:
-                               if (e.Shift) {
-                                       if (selectionIsEmpty)
-                                               SelBegin = CurrentPosition;
-                                       if (e.Control)
-                                               GotoWordEnd ();
-                                       else if (!MoveRight ())
-                                               return;
-                                       SelRelease = CurrentPosition;
-                                       break;
-                               }
-                               SelRelease = -1;
-                               if (e.Control)
-                                       GotoWordEnd ();
-                               else
-                                       MoveRight ();
-                               break;
-                       case Key.Up:
-                               if (e.Shift) {
-                                       if (selectionIsEmpty)
-                                               SelBegin = CurrentPosition;
-                                       CurrentLine--;
-                                       SelRelease = CurrentPosition;
-                                       break;
-                               }
-                               SelRelease = -1;
-                               CurrentLine--;
-                               break;
-                       case Key.Down:
-                               if (e.Shift) {
-                                       if (selectionIsEmpty)
-                                               SelBegin = CurrentPosition;
-                                       CurrentLine++;
-                                       SelRelease = CurrentPosition;
-                                       break;
-                               }
-                               SelRelease = -1;
-                               CurrentLine++;                          
-                               break;
-                       case Key.Menu:
-                               break;
-                       case Key.NumLock:
-                               break;
-                       case Key.PageDown:                              
-                               break;
-                       case Key.PageUp:
-                               break;
-                       case Key.RWin:
-                               break;
-                       case Key.Tab:
-                               this.Insert ("\t");
-                               break;
-                       default:
-                               break;
-                       }
-                       RegisterForGraphicUpdate();
-               }
-               public override void onKeyPress (object sender, KeyPressEventArgs e)
-               {
-                       base.onKeyPress (sender, e);
-
-                       this.Insert (e.KeyChar.ToString());
-
-                       SelRelease = -1;
-                       SelBegin = new Point(CurrentColumn, SelBegin.Y);
-
-                       RegisterForGraphicUpdate();
-               }
-        #endregion
-       } 
-}
diff --git a/src/GraphicObjects/TextRun.cs b/src/GraphicObjects/TextRun.cs
deleted file mode 100644 (file)
index a312ca1..0000000
+++ /dev/null
@@ -1,315 +0,0 @@
-//
-// TextRun.cs
-//
-// Author:
-//       Jean-Philippe Bruyère <jp.bruyere@hotmail.com>
-//
-// Copyright (c) 2013-2017 Jean-Philippe Bruyère
-//
-// 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.Generic;
-using System.Linq;
-using System.Text;
-using System.Diagnostics;
-using Cairo;
-using System.Text.RegularExpressions;
-using System.Xml.Serialization;
-using System.ComponentModel;
-
-namespace Crow
-{
-       public class TextRun : GraphicObject
-       {
-               #region CTOR
-               public TextRun ()
-               {
-
-               }
-               public TextRun (string _text)
-                       : base ()
-               {
-                       Text = _text;
-               }
-               #endregion
-
-               //TODO:change protected to private
-
-               #region private and protected fields
-               protected string _text = "label";
-               Alignment _textAlignment = Alignment.Left;
-               bool horizontalStretch = false;
-               bool verticalStretch = false;
-               bool _multiline;
-               bool wordWrap;
-               protected Rectangle rText;
-               protected float widthRatio = 1f;
-               protected float heightRatio = 1f;
-               protected FontExtents fe;
-               protected TextExtents te;
-               #endregion
-
-
-               [XmlAttributeAttribute ()]
-               [DefaultValue (Alignment.Left)]
-               public Alignment TextAlignment {
-                       get { return _textAlignment; }
-                       set { _textAlignment = value; }
-               }
-               [XmlAttributeAttribute ()]
-               [DefaultValue (false)]
-               public virtual bool HorizontalStretch {
-                       get { return horizontalStretch; }
-                       set {
-                               if (horizontalStretch == value)
-                                       return;
-                               horizontalStretch = value;
-                               RegisterForRedraw ();
-                               NotifyValueChanged ("HorizontalStretch", horizontalStretch);
-                       }
-               }
-               [XmlAttributeAttribute ()]
-               [DefaultValue (false)]
-               public virtual bool VerticalStretch {
-                       get { return verticalStretch; }
-                       set {
-                               if (verticalStretch == value)
-                                       return;
-                               verticalStretch = value;
-                               RegisterForRedraw ();
-                               NotifyValueChanged ("VerticalStretch", verticalStretch);
-                       }
-               }
-               [XmlAttributeAttribute ()]
-               [DefaultValue ("label")]
-               public string Text {
-                       get {
-                               return lines == null ?
-                                       _text : lines.Aggregate ((i, j) => i + Interface.LineBreak + j);
-                       }
-                       set {
-                               if (_text == value)
-                                       return;
-
-                               RegisterForGraphicUpdate ();
-
-                               _text = value;
-
-                               if (string.IsNullOrEmpty (_text))
-                                       _text = "";
-
-                               lines = getLines;
-                       }
-               }
-               [XmlAttributeAttribute ()]
-               [DefaultValue (false)]
-               public bool Multiline {
-                       get { return _multiline; }
-                       set {
-                               _multiline = value;
-                               RegisterForGraphicUpdate ();
-                       }
-               }
-               [XmlAttributeAttribute ()]
-               [DefaultValue (false)]
-               public bool WordWrap {
-                       get {
-                               return wordWrap;
-                       }
-                       set {
-                               if (wordWrap == value)
-                                       return;
-                               wordWrap = value;
-                               RegisterForGraphicUpdate ();
-                       }
-               }
-
-               List<string> lines;
-               List<string> getLines {
-                       get {
-                               return _multiline ?
-                                       Regex.Split (_text, "\r\n|\r|\n").ToList () :
-                                       new List<string> (new string [] { _text });
-                       }
-               }
-
-               #region GraphicObject overrides
-               protected override int measureRawSize (LayoutingType lt)
-               {
-                       if (lines == null)
-                               lines = getLines;
-
-                       using (ImageSurface img = new ImageSurface (Format.Argb32, 10, 10)) {
-                               using (Context gr = new Context (img)) {
-                                       //Cairo.FontFace cf = gr.GetContextFontFace ();
-
-                                       gr.SelectFontFace (Font.Name, Font.Slant, Font.Wheight);
-                                       gr.SetFontSize (Font.Size);
-
-
-                                       fe = gr.FontExtents;
-                                       te = new TextExtents ();
-
-                                       if (lt == LayoutingType.Height) {
-                                               int lc = lines.Count;
-                                               //ensure minimal height = text line height
-                                               if (lc == 0)
-                                                       lc = 1;
-
-                                               return (int)(fe.Height * lc) + Margin * 2;
-                                       }
-
-                                       foreach (string s in lines) {
-                                               string l = s.Replace("\t", new String (' ', Interface.TabSize));
-                                               TextExtents tmp = gr.TextExtents (l);
-                                               if (tmp.XAdvance > te.XAdvance)
-                                                       te = tmp;
-                                       }
-                                       return (int)Math.Ceiling (te.XAdvance) + Margin * 2;
-                               }
-                       }
-               }
-               protected override void onDraw (Context gr)
-               {
-                       base.onDraw (gr);
-
-                       gr.SelectFontFace (Font.Name, Font.Slant, Font.Wheight);
-                       gr.SetFontSize (Font.Size);
-                       gr.FontOptions = Interface.FontRenderingOptions;
-                       gr.Antialias = Interface.Antialias;
-
-                       rText = new Rectangle (new Size (
-                               measureRawSize (LayoutingType.Width), measureRawSize (LayoutingType.Height)));
-                       rText.Width -= 2 * Margin;
-                       rText.Height -= 2 * Margin;
-
-                       widthRatio = 1f;
-                       heightRatio = 1f;
-
-                       Rectangle cb = ClientRectangle;
-
-                       //ignore text alignment if size to content = true
-                       //or if text size is larger than client bounds
-                       if (Width < 0 || Height < 0 || rText.Width > cb.Width) {
-                               rText.X = cb.X;
-                               rText.Y = cb.Y;
-                       } else {
-                               if (horizontalStretch) {
-                                       widthRatio = (float)cb.Width / rText.Width;
-                                       if (!verticalStretch)
-                                               heightRatio = widthRatio;
-                               }
-                               if (verticalStretch) {
-                                       heightRatio = (float)cb.Height / rText.Height;
-                                       if (!horizontalStretch)
-                                               widthRatio = heightRatio;
-                               }
-
-                               rText.Width = (int)(widthRatio * cb.Width);
-                               rText.Height = (int)(heightRatio * cb.Height);
-
-                               switch (TextAlignment) {
-                               case Alignment.TopLeft:     //ok
-                                       rText.X = cb.X;
-                                       rText.Y = cb.Y;
-                                       break;
-                               case Alignment.Top:   //ok                                              
-                                       rText.Y = cb.Y;
-                                       rText.X = cb.X + cb.Width / 2 - rText.Width / 2;
-                                       break;
-                               case Alignment.TopRight:    //ok
-                                       rText.Y = cb.Y;
-                                       rText.X = cb.Right - rText.Width;
-                                       break;
-                               case Alignment.Left://ok
-                                       rText.X = cb.X;
-                                       rText.Y = cb.Y + cb.Height / 2 - rText.Height / 2;
-                                       break;
-                               case Alignment.Right://ok
-                                       rText.X = cb.X + cb.Width - rText.Width;
-                                       rText.Y = cb.Y + cb.Height / 2 - rText.Height / 2;
-                                       break;
-                               case Alignment.Bottom://ok
-                                       rText.X = cb.Width / 2 - rText.Width / 2;
-                                       rText.Y = cb.Height - rText.Height;
-                                       break;
-                               case Alignment.BottomLeft://ok
-                                       rText.X = cb.X;
-                                       rText.Y = cb.Bottom - rText.Height;
-                                       break;
-                               case Alignment.BottomRight://ok
-                                       rText.Y = cb.Bottom - rText.Height;
-                                       rText.X = cb.Right - rText.Width;
-                                       break;
-                               case Alignment.Center://ok
-                                       rText.X = cb.X + cb.Width / 2 - rText.Width / 2;
-                                       rText.Y = cb.Y + cb.Height / 2 - rText.Height / 2;
-                                       break;
-                               }
-                       }
-
-                       gr.FontMatrix = new Matrix (widthRatio * Font.Size, 0, 0, heightRatio * Font.Size, 0, 0);
-
-
-                       int curLineCount = 0;
-                       for (int i = 0; i < lines.Count; i++) {
-                               string l = lines [i].Replace ("\t", new String (' ', Interface.TabSize));
-                               List<string> wl = new List<string> ();
-                               int lineLength = (int)gr.TextExtents (l).XAdvance;
-
-                               if (wordWrap && lineLength > cb.Width) {
-                                       string tmpLine = "";
-                                       int curChar = 0;
-                                       while (curChar < l.Length) {
-                                               tmpLine += l [curChar];
-                                               if ((int)gr.TextExtents (tmpLine).XAdvance > cb.Width) {
-                                                       tmpLine = tmpLine.Remove (tmpLine.Length - 1);
-                                                       wl.Add (tmpLine);
-                                                       tmpLine = "";
-                                                       continue;
-                                               }
-                                               curChar++;
-                                       }
-                                       wl.Add (tmpLine);
-                               } else
-                                       wl.Add (l);
-
-                               foreach (string ll in wl) {
-                                       lineLength = (int)gr.TextExtents (ll).XAdvance;
-
-
-                                       if (string.IsNullOrWhiteSpace (ll)) {
-                                               curLineCount++;
-                                               continue;
-                                       }
-
-                                       Foreground.SetAsSource (gr);
-                                       gr.MoveTo (rText.X, rText.Y + fe.Ascent + fe.Height * curLineCount);
-
-                                       gr.ShowText (ll);
-                                       gr.Fill ();
-
-                                       curLineCount++;
-                               }
-                       }
-               }
-               #endregion
-       }
-}
diff --git a/src/GraphicObjects/TreeView.cs b/src/GraphicObjects/TreeView.cs
deleted file mode 100644 (file)
index 6549f14..0000000
+++ /dev/null
@@ -1,120 +0,0 @@
-//
-// TreeView.cs
-//
-// Author:
-//       Jean-Philippe Bruyère <jp.bruyere@hotmail.com>
-//
-// Copyright (c) 2013-2017 Jean-Philippe Bruyère
-//
-// 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.Xml.Serialization;
-using System.Diagnostics;
-using System.ComponentModel;
-
-namespace Crow
-{
-       //treeview expect expandable child (or not)
-       //if their are expandable, some functions and events are added
-       public class TreeView : TemplatedGroup
-       {
-               GraphicObject selectedItemContainer = null;
-               bool isRoot;
-
-               #region CTOR
-               public TreeView () : base()
-               {
-               }
-               #endregion
-
-               [XmlAttributeAttribute()][DefaultValue(false)]
-               public virtual bool IsRoot {
-                       get { return isRoot; }
-                       set {
-                               if (isRoot == value)
-                                       return;
-                               isRoot = value;
-                               NotifyValueChanged ("IsRoot", isRoot);
-                       }
-               }
-               [XmlIgnore]public override object SelectedItem {
-                       get {
-                               return selectedItemContainer == null ?
-                                       "" : selectedItemContainer.DataSource;
-                       }
-               }
-
-               protected override void registerItemClick (GraphicObject g)
-               {
-                       //register ItemClick on the Root node
-                       TreeView tv = this as TreeView;
-                       while (!tv.IsRoot) {
-                               ILayoutable tmp = tv.Parent;
-                               while (!(tmp is TreeView)) {
-                                       tmp = tmp.Parent;
-                               }
-                               tv = tmp as TreeView;
-                       }
-                       g.MouseClick += tv.itemClick;
-               }
-               internal override void itemClick (object sender, MouseButtonEventArgs e)
-               {
-                       GraphicObject tmp = sender as GraphicObject;
-                       if (!tmp.HasFocus)
-                               return;
-                       if (selectedItemContainer != null) {
-                               selectedItemContainer.Foreground = Color.Transparent;
-                               selectedItemContainer.Background = Color.Transparent;
-                       }
-                       selectedItemContainer = tmp;
-                       selectedItemContainer.Foreground = SelectionForeground;
-                       selectedItemContainer.Background = SelectionBackground;
-                       NotifyValueChanged ("SelectedItem", SelectedItem);
-                       raiseSelectedItemChanged ();
-               }
-
-               void onExpandAll_MouseClick (object sender, MouseButtonEventArgs e)
-               {
-                       ExpandAll ();
-               }
-
-               public void ExpandAll(){
-                       foreach (Group grp in items.Children) {
-                               foreach (GraphicObject go in grp.Children) {
-                                       Expandable exp = go as Expandable;
-                                       if (exp == null)
-                                               continue;
-                                       TreeView subTV = exp.FindByName ("List") as TreeView;
-                                       if (subTV == null)
-                                               continue;
-                                       EventHandler handler = null;
-                                       handler = delegate(object sender, EventArgs e) {
-                                               TreeView tv = sender as TreeView;
-                                               tv.Loaded -= handler;
-                                               tv.ExpandAll ();
-                                       };
-                                       subTV.Loaded += handler;
-                                       exp.IsExpanded = true;
-                               }
-                       }
-               }
-       }
-}
-
diff --git a/src/GraphicObjects/VerticalStack.cs b/src/GraphicObjects/VerticalStack.cs
deleted file mode 100644 (file)
index d5d0236..0000000
+++ /dev/null
@@ -1,49 +0,0 @@
-//
-// VerticalStack.cs
-//
-// Author:
-//       Jean-Philippe Bruyère <jp.bruyere@hotmail.com>
-//
-// Copyright (c) 2013-2017 Jean-Philippe Bruyère
-//
-// 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.Generic;
-using System.Linq;
-using System.Text;
-
-namespace Crow
-{
-    public class VerticalStack : GenericStack
-    {
-        public VerticalStack()
-            : base()
-        {
-        }
-
-        [System.Xml.Serialization.XmlIgnore]
-        public override Orientation Orientation
-        {
-            get { return Orientation.Vertical; }            
-        }
-
-
-    }
-}
diff --git a/src/GraphicObjects/Window.cs b/src/GraphicObjects/Window.cs
deleted file mode 100644 (file)
index e282052..0000000
+++ /dev/null
@@ -1,399 +0,0 @@
-//
-// Window.cs
-//
-// Author:
-//       Jean-Philippe Bruyère <jp.bruyere@hotmail.com>
-//
-// Copyright (c) 2013-2017 Jean-Philippe Bruyère
-//
-// 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.Xml.Serialization;
-using System.ComponentModel;
-using System.Diagnostics;
-
-namespace Crow
-{
-       public class Window : TemplatedContainer
-       {
-               enum Direction
-               {
-                       None,
-                       N,
-                       S,
-                       E,
-                       W,
-                       NW,
-                       NE,
-                       SW,
-                       SE,
-               }
-
-               string _icon;
-               bool _resizable;
-               bool _movable;
-               bool hoverBorder = false;
-               bool alwaysOnTop = false;
-
-               Rectangle savedBounds;
-               bool _minimized = false;
-
-               Container _contentContainer;
-               Direction currentDirection = Direction.None;
-
-               #region Events
-               public event EventHandler Closing;
-               public event EventHandler Maximized;
-               public event EventHandler Unmaximized;
-               public event EventHandler Minimize;
-               #endregion
-
-               #region CTOR
-               public Window () : base() {
-                       
-               }
-               #endregion
-
-               #region TemplatedContainer overrides
-               public override GraphicObject Content {
-                       get { return _contentContainer == null ? null : _contentContainer.Child; }
-                       set { _contentContainer.SetChild(value); }
-               }
-               protected override void loadTemplate(GraphicObject template = null)
-               {
-                       base.loadTemplate (template);
-                       _contentContainer = this.child.FindByName ("Content") as Container;
-
-                       NotifyValueChanged ("ShowNormal", false);
-                       NotifyValueChanged ("ShowMinimize", true);
-                       NotifyValueChanged ("ShowMaximize", true);
-               }
-               #endregion
-
-               #region public properties
-               [XmlAttributeAttribute][DefaultValue("#Crow.Images.Icons.crow.png")]
-               public string Icon {
-                       get { return _icon; } 
-                       set {
-                               if (_icon == value)
-                                       return;
-                               _icon = value;
-                               NotifyValueChanged ("Icon", _icon);
-                       }
-               } 
-               [XmlAttributeAttribute][DefaultValue(true)]
-               public bool Resizable {
-                       get {
-                               return _resizable;
-                       }
-                       set {
-                               if (_resizable == value)
-                                       return;
-                               _resizable = value;
-                               NotifyValueChanged ("Resizable", _resizable);
-                       }
-               }
-               [XmlAttributeAttribute][DefaultValue(true)]
-               public bool Movable {
-                       get {
-                               return _movable;
-                       }
-                       set {
-                               if (_movable == value)
-                                       return;
-                               _movable = value;
-                               NotifyValueChanged ("Movable", _movable);
-                       }
-               }
-               [XmlAttributeAttribute][DefaultValue(false)]
-               public bool IsMinimized {
-                       get { return _minimized; }
-                       set{
-                               if (value == IsMinimized)
-                                       return;
-
-                               _minimized = value;
-                               _contentContainer.Visible = !_minimized;
-
-                               NotifyValueChanged ("IsMinimized", _minimized);
-                       }
-               }
-               [XmlIgnore]public bool IsMaximized {
-                       get { return Width == Measure.Stretched & Height == Measure.Stretched & !_minimized; }
-               }
-               [XmlIgnore]public bool IsNormal {
-                       get { return !(IsMaximized|_minimized); }
-               }
-               [XmlAttributeAttribute][DefaultValue(false)]
-               public bool AlwaysOnTop {
-                       get {
-                               return alwaysOnTop;
-                       }
-                       set {
-                               if (alwaysOnTop == value)
-                                       return;
-                               alwaysOnTop = value;
-                               if (alwaysOnTop) {
-                                       CurrentInterface.PutOnTop (this);
-                                       CurrentInterface.TopWindows++;
-                               }else
-                                       CurrentInterface.TopWindows--;
-                               NotifyValueChanged ("AlwaysOnTop", alwaysOnTop);
-                       }
-               }
-//             [XmlAttributeAttribute()][DefaultValue(WindowState.Normal)]
-//             public virtual WindowState State {
-//                     get { return _state; }
-//                     set {
-//                             if (_state == value)
-//                                     return;
-//                             _state = value;
-//                             NotifyValueChanged ("State", _state);
-//                             NotifyValueChanged ("IsNormal", IsNormal);
-//                             NotifyValueChanged ("IsMaximized", IsMaximized);
-//                             NotifyValueChanged ("IsMinimized", IsMinimized);
-//                             NotifyValueChanged ("IsNotMinimized", IsNotMinimized);
-//                     }
-//             } 
-               #endregion
-
-               #region GraphicObject Overrides
-               public override void onMouseMove (object sender, MouseMoveEventArgs e)
-               {
-                       base.onMouseMove (sender, e);
-
-                       Interface otkgw = CurrentInterface;
-
-                       if (!hoverBorder) {
-                               currentDirection = Direction.None;
-                               CurrentInterface.MouseCursor = XCursor.Default;
-                               return;
-                       }
-
-                       if (this.HasFocus && _movable) {
-                               if (e.Mouse.IsButtonDown (MouseButton.Left)) {
-                                       int currentLeft = this.Left;
-                                       int currentTop = this.Top;
-                                       int currentWidth, currentHeight;
-
-                                       if (currentLeft == 0) {
-                                               currentLeft = this.Slot.Left;
-                                               this.Left = currentLeft;
-                                       }
-                                       if (currentTop == 0) {
-                                               currentTop = this.Slot.Top;
-                                               this.Top = currentTop;
-                                       }
-                                       if (this.Width.IsFixed)
-                                               currentWidth = this.Width;
-                                       else
-                                               currentWidth = this.Slot.Width;
-                               
-                                       if (this.Height.IsFixed)
-                                               currentHeight = this.Height;
-                                       else
-                                               currentHeight = this.Slot.Height;
-
-                                       switch (currentDirection) {
-                                       case Direction.None:
-                                               this.Left = currentLeft + e.XDelta;                             
-                                               this.Top = currentTop + e.YDelta;
-                                               break;
-                                       case Direction.N:
-                                               this.Height = currentHeight - e.YDelta;
-                                               if (this.Height == currentHeight - e.YDelta)
-                                                       this.Top = currentTop + e.YDelta;
-                                               break;
-                                       case Direction.S:
-                                               this.Height = currentHeight + e.YDelta;
-                                               break;
-                                       case Direction.W:
-                                               this.Width = currentWidth - e.XDelta;
-                                               if (this.Width == currentWidth - e.XDelta)
-                                                       this.Left = currentLeft + e.XDelta;
-                                               break;
-                                       case Direction.E:
-                                               this.Width = currentWidth + e.XDelta;
-                                               break;
-                                       case Direction.NW:
-                                               this.Height = currentHeight - e.YDelta;
-                                               if (this.Height == currentHeight - e.YDelta)
-                                                       this.Top = currentTop + e.YDelta;
-                                               this.Width = currentWidth - e.XDelta;
-                                               if (this.Width == currentWidth - e.XDelta)
-                                                       this.Left = currentLeft + e.XDelta;
-                                               break;
-                                       case Direction.NE:
-                                               this.Height = currentHeight - e.YDelta;
-                                               if (this.Height == currentHeight - e.YDelta)
-                                                       this.Top = currentTop + e.YDelta;
-                                               this.Width = currentWidth + e.XDelta;
-                                               break;
-                                       case Direction.SW:
-                                               this.Width = currentWidth - e.XDelta;
-                                               if (this.Width == currentWidth - e.XDelta)
-                                                       this.Left = currentLeft + e.XDelta;
-                                               this.Height = currentHeight + e.YDelta;
-                                               break;
-                                       case Direction.SE:
-                                               this.Height = currentHeight + e.YDelta;
-                                               this.Width = currentWidth + e.XDelta;
-                                               break;
-                                       }
-                                       return;
-                               }
-                       }
-                       if (Resizable) {
-                               Direction lastDir = currentDirection;
-
-                               if (Math.Abs (e.Position.Y - this.Slot.Y) < Interface.BorderThreshold) {
-                                       if (Math.Abs (e.Position.X - this.Slot.X) < Interface.BorderThreshold)
-                                               currentDirection = Direction.NW;
-                                       else if (Math.Abs (e.Position.X - this.Slot.Right) < Interface.BorderThreshold)
-                                               currentDirection = Direction.NE;
-                                       else
-                                               currentDirection = Direction.N;
-                               } else if (Math.Abs (e.Position.Y - this.Slot.Bottom) < Interface.BorderThreshold) {
-                                       if (Math.Abs (e.Position.X - this.Slot.X) < Interface.BorderThreshold)
-                                               currentDirection = Direction.SW;
-                                       else if (Math.Abs (e.Position.X - this.Slot.Right) < Interface.BorderThreshold)
-                                               currentDirection = Direction.SE;
-                                       else
-                                               currentDirection = Direction.S;
-                               } else if (Math.Abs (e.Position.X - this.Slot.X) < Interface.BorderThreshold)
-                                       currentDirection = Direction.W;
-                               else if (Math.Abs (e.Position.X - this.Slot.Right) < Interface.BorderThreshold)
-                                       currentDirection = Direction.E;
-                               else
-                                       currentDirection = Direction.None;
-
-                               if (currentDirection != lastDir) {
-                                       switch (currentDirection) {
-                                       case Direction.None:
-                                               otkgw.MouseCursor = XCursor.Default;
-                                               break;
-                                       case Direction.N:
-                                               otkgw.MouseCursor = XCursor.V;
-                                               break;
-                                       case Direction.S:
-                                               otkgw.MouseCursor = XCursor.V;
-                                               break;
-                                       case Direction.E:
-                                               otkgw.MouseCursor = XCursor.H;
-                                               break;
-                                       case Direction.W:
-                                               otkgw.MouseCursor = XCursor.H;
-                                               break;
-                                       case Direction.NW:
-                                               otkgw.MouseCursor = XCursor.NW;
-                                               break;
-                                       case Direction.NE:
-                                               otkgw.MouseCursor = XCursor.NE;
-                                               break;
-                                       case Direction.SW:
-                                               otkgw.MouseCursor = XCursor.SW;
-                                               break;
-                                       case Direction.SE:
-                                               otkgw.MouseCursor = XCursor.SE;
-                                               break;
-                                       }
-                               }                               
-                       }                               
-               }
-               public override void onMouseDown (object sender, MouseButtonEventArgs e)
-               {
-                       base.onMouseDown (sender, e);
-               }
-               #endregion
-
-               protected void onMaximized (object sender, EventArgs e){
-                       lock (CurrentInterface.LayoutMutex) {
-                               if (!IsMinimized)
-                                       savedBounds = this.LastPaintedSlot;
-                               this.Left = this.Top = 0;
-                               this.RegisterForLayouting (LayoutingType.Positioning);
-                               this.Width = this.Height = Measure.Stretched;
-                               IsMinimized = false;
-                               Resizable = false;
-                               NotifyValueChanged ("ShowNormal", true);
-                               NotifyValueChanged ("ShowMinimize", true);
-                               NotifyValueChanged ("ShowMaximize", false);
-                       }
-
-                       Maximized.Raise (sender, e);
-
-
-
-               }
-               protected void onUnmaximized (object sender, EventArgs e){
-                       lock (CurrentInterface.LayoutMutex) {
-                               this.Left = savedBounds.Left;
-                               this.Top = savedBounds.Top;
-                               this.Width = savedBounds.Width;
-                               this.Height = savedBounds.Height;
-                               IsMinimized = false;
-                               Resizable = true;
-                               NotifyValueChanged ("ShowNormal", false);
-                               NotifyValueChanged ("ShowMinimize", true);
-                               NotifyValueChanged ("ShowMaximize", true);
-                       }
-
-                       Unmaximized.Raise (sender, e);
-               }
-               protected void onMinimized (object sender, EventArgs e){
-                       lock (CurrentInterface.LayoutMutex) {
-                               if (IsNormal)
-                                       savedBounds = this.LastPaintedSlot;
-                               Width = 200;
-                               Height = 20;
-                               Resizable = false;
-                               IsMinimized = true;
-                               NotifyValueChanged ("ShowNormal", true);
-                               NotifyValueChanged ("ShowMinimize", false);
-                               NotifyValueChanged ("ShowMaximize", true);
-                       }
-
-                       Minimize.Raise (sender, e);
-               }
-               protected void onBorderMouseLeave (object sender, MouseMoveEventArgs e)
-               {
-                       hoverBorder = false;
-                       currentDirection = Direction.None;
-                       CurrentInterface.MouseCursor = XCursor.Default;
-               }
-               protected void onBorderMouseEnter (object sender, MouseMoveEventArgs e)
-               {
-                       hoverBorder = true;
-               }
-
-
-               protected void butQuitPress (object sender, MouseButtonEventArgs e)
-               {
-                       CurrentInterface.MouseCursor = XCursor.Default;
-                       close ();
-               }
-
-               protected void close(){
-                       Closing.Raise (this, null);
-                       CurrentInterface.DeleteWidget (this);
-               }
-       }
-}
-
diff --git a/src/GraphicObjects/Wrapper.cs b/src/GraphicObjects/Wrapper.cs
deleted file mode 100644 (file)
index 8b282eb..0000000
+++ /dev/null
@@ -1,233 +0,0 @@
-//
-// Wrapper.cs
-//
-// Author:
-//       Jean-Philippe Bruyère <jp.bruyere@hotmail.com>
-//
-// Copyright (c) 2013-2017 Jean-Philippe Bruyère
-//
-// 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 Crow
-{
-       public class Wrapper : GenericStack
-       {
-               public Wrapper () : base()
-               {}
-
-               #region Group Overrides
-               public override void ChildrenLayoutingConstraints (ref LayoutingType layoutType)
-               {
-                       layoutType &= (~LayoutingType.Positioning);
-               }
-               public override void ComputeChildrenPositions()
-               {
-                       int dx = 0;
-                       int dy = 0;
-
-                       if (Orientation == Orientation.Vertical) {
-                               int tallestChild = 0;
-                               foreach (GraphicObject c in Children) {
-                                       if (!c.Visible)
-                                               continue;
-                                       if (dx + c.Slot.Width > ClientRectangle.Width) {
-                                               dx = 0;
-                                               dy += tallestChild + Spacing;
-                                               c.Slot.X = dx;
-                                               c.Slot.Y = dy;
-                                               tallestChild = c.Slot.Height;
-                                       } else {
-                                               if (tallestChild < c.Slot.Height)
-                                                       tallestChild = c.Slot.Height;
-                                               c.Slot.X = dx;
-                                               c.Slot.Y = dy;
-                                       }
-                                       dx += c.Slot.Width + Spacing;
-                               }
-                       } else {
-                               int largestChild = 0;
-                               foreach (GraphicObject c in Children) {
-                                       if (!c.Visible)
-                                               continue;
-                                       if (dy + c.Slot.Height > ClientRectangle.Height) {
-                                               dy = 0;
-                                               dx += largestChild + Spacing;
-                                               c.Slot.X = dx;
-                                               c.Slot.Y = dy;
-                                               largestChild = c.Slot.Width;
-                                       } else {
-                                               if (largestChild < c.Slot.Width)
-                                                       largestChild = c.Slot.Width;
-                                               c.Slot.X = dx;
-                                               c.Slot.Y = dy;
-                                       }
-                                       dy += c.Slot.Height + Spacing;
-                               }
-                       }
-                       IsDirty = true;
-               }
-               public override void OnChildLayoutChanges (object sender, LayoutingEventArgs arg)
-               {
-                       //children can't stretch in a wrapper
-                       GraphicObject go = sender as GraphicObject;
-                       //System.Diagnostics.Debug.WriteLine ("wrapper child layout change: " + go.LastSlots.ToString() + " => " + go.Slot.ToString());
-                       switch (arg.LayoutType) {
-                       case LayoutingType.Width:
-                               if (Orientation == Orientation.Horizontal && go.Width.Units == Unit.Percent){
-                                       go.Width = Measure.Fit;
-                                       return;
-                               }
-                               this.RegisterForLayouting (LayoutingType.Width);
-                               break;
-                       case LayoutingType.Height:
-                               if (Orientation == Orientation.Vertical && go.Height.Units == Unit.Percent) {
-                                       go.Height = Measure.Fit;
-                                       return;
-                               }
-                               this.RegisterForLayouting (LayoutingType.Height);
-                               break;
-                       default:
-                               return;
-                       }
-                       this.RegisterForLayouting (LayoutingType.ArrangeChildren);
-               }
-               #endregion
-
-               #region GraphicObject Overrides
-               protected override int measureRawSize (LayoutingType lt)
-               {
-                       int tmp = 0;
-                       //Wrapper can't fit in the opposite direction of the wrapper, this func is called only if Fit
-                       if (lt == LayoutingType.Width) {
-                               if (Orientation == Orientation.Vertical) {
-                                       Width = Measure.Stretched;
-                                       return -1;
-                               } else if (RegisteredLayoutings.HasFlag (LayoutingType.Height))
-                                       return -1;
-                               else {
-                                       int dy = 0;
-                                       int largestChild = 0;
-                                       lock (Children) {
-                                               foreach (GraphicObject c in Children) {
-                                                       if (!c.Visible)
-                                                               continue;
-                                                       if (c.Height.Units == Unit.Percent &&
-                                                               c.RegisteredLayoutings.HasFlag (LayoutingType.Height))
-                                                               return -1;
-                                                       if (dy + c.Slot.Height > ClientRectangle.Height) {
-                                                               dy = 0;
-                                                               tmp += largestChild + Spacing;
-                                                               largestChild = c.Slot.Width;
-                                                       } else if (largestChild < c.Slot.Width)
-                                                               largestChild = c.Slot.Width;
-
-                                                       dy += c.Slot.Height + Spacing;
-                                               }
-                                               if (dy == 0)
-                                                       tmp -= Spacing;
-                                               return tmp + largestChild + 2 * Margin;
-                                       }
-                               }
-                       } else if (Orientation == Orientation.Horizontal) {
-                               Height = Measure.Stretched;
-                               return -1;
-                       } else if (RegisteredLayoutings.HasFlag (LayoutingType.Width))
-                               return -1;
-                       else {
-                               int dx = 0;
-                               int tallestChild = 0;
-                               lock (Children) {
-                                       foreach (GraphicObject c in Children) {
-                                               if (!c.Visible)
-                                                       continue;
-                                               if (c.Width.Units == Unit.Percent &&
-                                                       c.RegisteredLayoutings.HasFlag (LayoutingType.Width))
-                                                       return -1;
-                                               if (dx + c.Slot.Width > ClientRectangle.Width) {
-                                                       dx = 0;
-                                                       tmp += tallestChild + Spacing;
-                                                       tallestChild = c.Slot.Height;
-                                               } else if (tallestChild < c.Slot.Height)
-                                                       tallestChild = c.Slot.Height;
-
-                                               dx += c.Slot.Width + Spacing;
-                                       }
-                                       if (dx == 0)
-                                               tmp -= Spacing;
-                                       return tmp + tallestChild + 2 * Margin;
-                               }
-                       }
-               }
-
-               public override bool UpdateLayout (LayoutingType layoutType)
-               {
-                       RegisteredLayoutings &= (~layoutType);
-
-                       if (layoutType == LayoutingType.ArrangeChildren) {
-                               if ((RegisteredLayoutings & LayoutingType.Sizing) != 0)
-                                       return false;
-
-                               ComputeChildrenPositions ();
-
-                               //if no layouting remains in queue for item, registre for redraw
-                               if (RegisteredLayoutings == LayoutingType.None && IsDirty)
-                                       CurrentInterface.EnqueueForRepaint (this);
-
-                               return true;
-                       }
-
-                       return base.UpdateLayout(layoutType);
-               }
-               public override void OnLayoutChanges (LayoutingType layoutType)
-               {
-                       #if DEBUG_LAYOUTING
-                       CurrentInterface.currentLQI.Slot = LastSlots;
-                       CurrentInterface.currentLQI.Slot = Slot;
-                       #endif
-                       switch (layoutType) {
-                       case LayoutingType.Width:
-                               foreach (GraphicObject c in Children) {
-                                       if (c.Width.Units == Unit.Percent)
-                                               c.RegisterForLayouting (LayoutingType.Width);
-                               }
-                               if (Height == Measure.Fit)
-                                       RegisterForLayouting (LayoutingType.Height);
-                               RegisterForLayouting (LayoutingType.X);
-                               break;
-                       case LayoutingType.Height:
-                               foreach (GraphicObject c in Children) {
-                                       if (c.Height.Units == Unit.Percent)
-                                               c.RegisterForLayouting (LayoutingType.Height);
-                               }
-                               if (Width == Measure.Fit)
-                                       RegisterForLayouting (LayoutingType.Width);
-                               RegisterForLayouting (LayoutingType.Y);
-                               break;
-                       default:
-                               return;
-                       }
-                       RegisterForLayouting (LayoutingType.ArrangeChildren);
-                       raiseLayoutChanged (new LayoutingEventArgs (layoutType));
-               }
-               #endregion
-       }
-}
-
index 47288b0695b6a0d4726fd139628ac51ddd45ba42..c73370e4aad1aae7e6611100f967de5a6b290c16 100644 (file)
@@ -99,6 +99,18 @@ namespace Crow
             else
                 return false;
         }
+               public static bool operator <(Size s1, Size s2)
+               {
+                       if (s1.Width < s2.Width)
+                               if (s1.Height <= s2.Height)
+                                       return true;
+                       else
+                               return false;
+                       else if (s1.Width == s2.Width && s1.Height < s2.Height)
+                               return true;
+
+                       return false;
+               }
         public static bool operator >=(Size s1, Size s2)
         {
             if (s1.Width >= s2.Width && s1.Height >= s2.Height)
@@ -106,18 +118,13 @@ namespace Crow
             else
                 return false;
         }
-        public static bool operator <(Size s1, Size s2)
-        {
-            if (s1.Width < s2.Width)
-                if (s1.Height <= s2.Height)
-                    return true;
-                else
-                    return false;
-            else if (s1.Width == s2.Width && s1.Height < s2.Height)
-                return true;
-
-            return false;
-        }
+               public static bool operator <=(Size s1, Size s2)
+               {
+                       if (s1.Width <= s2.Width && s1.Height <= s2.Height)
+                               return true;
+                       else
+                               return false;
+               }
                public static bool operator <(Size s, int i)
                {
                        return s.Width < i && s.Height < i ? true : false;
@@ -126,13 +133,15 @@ namespace Crow
                {
                        return s.Width <= i && s.Height <= i ? true : false;
                }
-        public static bool operator <=(Size s1, Size s2)
-        {
-            if (s1.Width <= s2.Width && s1.Height <= s2.Height)
-                return true;
-            else
-                return false;
-        }
+               public static bool operator >(Size s, int i)
+               {
+                       return s.Width > i && s.Height > i ? true : false;
+               }
+               public static bool operator >=(Size s, int i)
+               {
+                       return s.Width >= i && s.Height >= i ? true : false;
+               }
+
         public static bool operator ==(Size s, int i)
         {
             if (s.Width == i && s.Height == i)