]> O.S.I.I.S - jp/crow.git/commitdiff
crowIde wip, docker wip, stack remove child debug
authorJean-Philippe Bruyère <jp_bruyere@hotmail.com>
Sun, 4 Mar 2018 10:28:09 +0000 (11:28 +0100)
committerJean-Philippe Bruyère <jp_bruyere@hotmail.com>
Sun, 4 Mar 2018 10:28:09 +0000 (11:28 +0100)
39 files changed:
Crow.csproj
CrowIDE/CrowIDE.csproj
CrowIDE/src/CrowIDE.cs
CrowIDE/src/ImlVisualEditor.cs
CrowIDE/src/MemberView/CategoryContainer.cs [new file with mode: 0644]
CrowIDE/src/MemberView/MembersView.cs [new file with mode: 0644]
CrowIDE/src/MemberView/PropertyContainer.cs [new file with mode: 0644]
CrowIDE/src/MembersView.cs [deleted file]
CrowIDE/src/Project.cs
CrowIDE/src/ProjectNodes.cs
CrowIDE/src/PropertyContainer.cs [deleted file]
CrowIDE/src/Solution.cs
CrowIDE/src/SourceEditor/CodeBuffer.cs
CrowIDE/src/SourceEditor/SourceEditor.cs
CrowIDE/ui/MembersItem.template
CrowIDE/ui/ProjectTree.template
CrowIDE/ui/SrcEdit.itemp
Default.style
Templates/DockWindow.template
Tests/Interfaces/Experimental/testDock.crow
Tests/Interfaces/Experimental/testStack.crow [new file with mode: 0644]
Tests/Tests.csproj
src/CompilerServices/CompilerServices.cs
src/GraphicObjects/ColorPicker.cs
src/GraphicObjects/DockStack.cs [new file with mode: 0644]
src/GraphicObjects/DockWindow.cs
src/GraphicObjects/Docker.cs
src/GraphicObjects/Expandable.cs
src/GraphicObjects/GenericStack.cs
src/GraphicObjects/GraphicObject.cs
src/GraphicObjects/Group.cs
src/GraphicObjects/PrivateContainer.cs
src/GraphicObjects/TemplatedGroup.cs
src/GraphicObjects/Wrapper.cs
src/IMLAttributes.cs [new file with mode: 0644]
src/Instantiator.cs
src/Interface.cs
src/Measure.cs
src/StyleReader.cs

index 91b16e313ca1513089c58a586ccdc151b8650555..7a0ffadaee265d9c44fb44cab2edd6653725e62b 100644 (file)
     <Compile Include="src\GraphicObjects\Docker.cs" />
     <Compile Include="src\GraphicObjects\DockWindow.cs" />
     <Compile Include="src\ParsingException.cs" />
+    <Compile Include="src\IMLAttributes.cs" />
+    <Compile Include="src\GraphicObjects\DockStack.cs" />
   </ItemGroup>
   <ItemGroup>
     <Reference Include="System" />
index 9a9a222f60ca60491c7a0bf7cd4d39375e0e703f..0a8150e4e71888477773ade73a9f9c75e19d262b 100644 (file)
@@ -77,7 +77,6 @@
   <ItemGroup>
     <Compile Include="src\CrowIDE.cs" />
     <Compile Include="src\ImlVisualEditor.cs" />
-    <Compile Include="src\MembersView.cs" />
     <Compile Include="src\Extensions.cs" />
     <Compile Include="src\Solution.cs" />
     <Compile Include="src\Project.cs" />
     <Compile Include="src\SourceEditor\Token.cs" />
     <Compile Include="src\SourceEditor\XMLParser.cs" />
     <Compile Include="src\SourceEditor\StyleParser.cs" />
-    <Compile Include="src\PropertyContainer.cs" />
     <Compile Include="src\SourceEditor\BufferParser.cs" />
+    <Compile Include="src\MemberView\MembersView.cs" />
+    <Compile Include="src\MemberView\PropertyContainer.cs" />
+    <Compile Include="src\MemberView\CategoryContainer.cs" />
   </ItemGroup>
   <ItemGroup>
     <Folder Include="ui\" />
     <Folder Include="images\" />
     <Folder Include="src\SourceEditor\" />
     <Folder Include="ui\ItemTemplates\" />
+    <Folder Include="src\MemberView\" />
   </ItemGroup>
   <ItemGroup>
     <EmbeddedResource Include="images\save.svg" />
index c08dd663ebc6ff94d9d39b00f802a679bb58a1df..6f6e376ba817d1f3919cb7ebfac42106af41c203 100644 (file)
@@ -103,13 +103,16 @@ namespace Crow.Coding
                        //this.CrowInterface.LoadInterface ("#Crow.Coding.ui.imlEditor.crow").DataSource = this;
                        //GraphicObject go = this.CrowInterface.LoadInterface (@"ui/test.crow");
                        GraphicObject go = AddWidget (@"#Crow.Coding.ui.CrowIDE.crow");
+                       go.DataSource = this;
 
                        MainIFace = ifaceControl[0].CrowInterface;
 
-                       if (ReopenLastSolution && !string.IsNullOrEmpty(LastOpenSolution))
+                       if (ReopenLastSolution && !string.IsNullOrEmpty (LastOpenSolution)) {
                                CurrentSolution = Solution.LoadSolution (LastOpenSolution);
+                               //lock(MainIFace.UpdateMutex)
+                               CurrentSolution.ReopenItemsSavedInUserConfig ();
+                       }
 
-                       go.DataSource = this;
 
                        instFileDlg = Instantiator.CreateFromImlFragment
                                (MainIFace, "<FileDialog Caption='Open File' CurrentDirectory='{²CurrentDirectory}' SearchPattern='*.sln' OkClicked='onFileOpen'/>");
index 69ae551533dad7ac54a382e394b9e92559e792ee..c9e5484e96d10ec6c145d598ff0edda71ef25499 100644 (file)
@@ -158,7 +158,7 @@ namespace Crow.Coding
                                                SelectedItem = go;
                                                IMLError = null;
                                                projFile.RegisteredEditors[this] = true;
-                                       }else if ((bool)projFile.Instance?.HasChanged){
+                                       }else if ((bool)projFile.Instance?.design_HasChanged){
                                                projFile.UpdateSource(this, projFile.Instance.GetIML());
                                        }
                                        imlVE.Update ();
diff --git a/CrowIDE/src/MemberView/CategoryContainer.cs b/CrowIDE/src/MemberView/CategoryContainer.cs
new file mode 100644 (file)
index 0000000..fbf3fe2
--- /dev/null
@@ -0,0 +1,65 @@
+//
+// CategoryContainer.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.Coding
+{
+       public class CategoryContainer : IValueChange
+       {
+               #region IValueChange implementation
+               public event EventHandler<ValueChangeEventArgs> ValueChanged;
+               public virtual void NotifyValueChanged(string MemberName, object _value)
+               {
+                       ValueChanged.Raise(this, new ValueChangeEventArgs(MemberName, _value));
+               }
+               #endregion
+
+               bool _isExpanded = true;
+
+               public PropertyContainer[] Properties;
+               public string Name;
+
+               public bool IsExpanded
+               {
+                       get { return _isExpanded; }
+                       set
+                       {
+                               if (value == _isExpanded)
+                                       return;
+
+                               _isExpanded = value;
+
+                               NotifyValueChanged ("IsExpanded", _isExpanded);
+                       }
+               }
+
+               public CategoryContainer (string categoryName, PropertyContainer[] properties){
+                       Name = categoryName;
+                       Properties = properties;
+               }
+       }
+}
+
diff --git a/CrowIDE/src/MemberView/MembersView.cs b/CrowIDE/src/MemberView/MembersView.cs
new file mode 100644 (file)
index 0000000..65dc959
--- /dev/null
@@ -0,0 +1,136 @@
+//
+//  MembersView.cs
+//
+//  Author:
+//       Jean-Philippe Bruyère <jp.bruyere@hotmail.com>
+//
+//  Copyright (c) 2016 jp
+//
+//  This program is free software: you can redistribute it and/or modify
+//  it under the terms of the GNU General Public License as published by
+//  the Free Software Foundation, either version 3 of the License, or
+//  (at your option) any later version.
+//
+//  This program is distributed in the hope that it will be useful,
+//  but WITHOUT ANY WARRANTY; without even the implied warranty of
+//  MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
+//  GNU General Public License for more details.
+//
+//  You should have received a copy of the GNU General Public License
+//  along with this program.  If not, see <http://www.gnu.org/licenses/>.
+using System;
+using Crow;
+using System.Xml.Serialization;
+using System.ComponentModel;
+using System.Reflection;
+using System.Collections.Generic;
+using System.Linq;
+using Cairo;
+
+namespace Crow.Coding
+{      
+       public class MembersView : ListBox
+       {               
+               object instance;
+               ImlProjectItem projFile;
+
+               public MembersView () : base() {}
+
+               //cache property containers per type
+               Dictionary<string,PropertyContainer[]> propContainersCache = new Dictionary<string, PropertyContainer[]>();
+               Dictionary<string,List<CategoryContainer>> categoryContainersCache = new Dictionary<string,List<CategoryContainer>> ();
+
+               [XmlAttributeAttribute][DefaultValue(null)]
+               public virtual object Instance {
+                       get { return instance; }
+                       set {
+                               if (instance == value)
+                                       return;
+                               object lastInst = instance;
+
+                               instance = value;
+                               NotifyValueChanged ("Instance", instance);
+
+                               if (Instance is GraphicObject) {
+                                       NotifyValueChanged ("SelectedItemName", Instance.GetType().Name + (Instance as GraphicObject).design_id
+                                               + ":" + (Instance as GraphicObject).design_imlPath );
+                               }else
+                                       NotifyValueChanged ("SelectedItemName", "");
+
+                               if (instance == null) { 
+                                       Data = null;
+                                       return;
+                               }       
+
+                               Type it = instance.GetType ();
+                               if (!propContainersCache.ContainsKey (it.FullName)) {
+                                       MemberInfo[] members = it.GetMembers (BindingFlags.Public | BindingFlags.Instance);
+                                       List<PropertyContainer> props = new List<PropertyContainer> ();
+                                       foreach (MemberInfo m in members) {
+                                               if (m.MemberType == MemberTypes.Property) {
+                                                       PropertyInfo pi = m as PropertyInfo;
+                                                       if (!pi.CanWrite)
+                                                               continue;
+                                                       if (pi.GetCustomAttribute (typeof(XmlIgnoreAttribute)) != null)
+                                                               continue;
+                                                       props.Add (new PropertyContainer (this, pi));
+                                               }
+                                       }
+                                       propContainersCache.Add (it.FullName, props.OrderBy (p => p.Name).ToArray ());
+                               }
+
+                               List<CategoryContainer> categories = new List<CategoryContainer> ();
+
+                               foreach (IGrouping<string,PropertyContainer> ig in propContainersCache[it.FullName].GroupBy(pc=>pc.DesignCategory)) {
+                                       categories.Add(new CategoryContainer(ig.Key, ig.ToArray()));
+                               }
+
+                               Data = categories;
+
+                               if (lastInst != instance) {
+                                       foreach (PropertyContainer pc in propContainersCache [it.FullName]) {
+                                               pc.NotifyValueChanged ("Value", pc.Value);
+                                       }
+                               }
+                       }
+               }
+               public ImlProjectItem ProjectNode {
+                       get { return projFile; }
+                       set {
+                               if (projFile == value)
+                                       return;
+                               
+//                             if (projFile != null)
+//                                     projFile.UnregisterEditor (this);
+                               
+                               projFile = value;
+
+//                             if (projFile != null)
+//                                     projFile.RegisterEditor (this);
+
+                               NotifyValueChanged ("ProjectNode", projFile);
+                       }
+               }
+
+               public void updateSource () {
+                       if (projFile == null)
+                               return;
+                       projFile.UpdateSource (this, (Instance as GraphicObject).GetIML ());
+               }
+
+//             public override void Paint (ref Context ctx)
+//             {
+//                     base.Paint (ref ctx);
+//
+//                     if (SelectedIndex < 0)
+//                             return;
+//
+//                     Rectangle r =  Parent.ContextCoordinates(Items [SelectedIndex].Slot);
+//                     ctx.SetSourceRGB (0, 0, 1);
+//                     ctx.Rectangle (r);
+//                     ctx.LineWidth = 2;
+//                     ctx.Stroke ();
+//             }
+
+       }
+}
diff --git a/CrowIDE/src/MemberView/PropertyContainer.cs b/CrowIDE/src/MemberView/PropertyContainer.cs
new file mode 100644 (file)
index 0000000..46cbbd7
--- /dev/null
@@ -0,0 +1,212 @@
+//
+// PropertyContainer.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.Reflection;
+using System.Linq;
+using System.Collections.Generic;
+using System.Diagnostics;
+using System.ComponentModel;
+
+namespace Crow.Coding
+{      
+       public class PropertyContainer : IValueChange
+       {
+               #region IValueChange implementation
+               public event EventHandler<ValueChangeEventArgs> ValueChanged;
+               public virtual void NotifyValueChanged(string MemberName, object _value)
+               {
+                       ValueChanged.Raise(this, new ValueChangeEventArgs(MemberName, _value));
+               }
+               #endregion
+
+               PropertyInfo pi;
+               MembersView mview;
+               Command cmdReset, cmdGoToStyle;
+
+               public List<Crow.Command> Commands;
+
+               #region CTOR
+               public PropertyContainer(MembersView mv, PropertyInfo prop){
+                       mview = mv;
+                       pi = prop;
+
+                       cmdReset = new Crow.Command (new Action (() => Reset ())) { Caption = "Reset to default" };
+                       cmdGoToStyle = new Crow.Command (new Action (() => GotoStyle ())) { Caption = "Goto style" };
+
+                       Commands = new List<Crow.Command> (new Crow.Command[] { cmdReset, cmdGoToStyle });
+               }
+               #endregion
+
+               public string DesignCategory {
+                       get {
+                               DesignCategory dca = (DesignCategory)pi.GetCustomAttribute (typeof(DesignCategory));
+                               return dca == null ? "Divers" : dca.Name;                                       
+                       }
+               }
+               public string Name { get { return pi.Name; }}
+               public object Value {
+                       get {
+                               return mview.ProjectNode.SelectedItem == null ? null : pi.GetValue(mview.ProjectNode.SelectedItem);
+                       }
+                       set {
+                               try {
+                                       GraphicObject g = Instance;
+                                       string valstr = null, oldval = null;
+
+                                       if (value != null)
+                                               valstr = value.ToString();
+
+                                       if (HasStyling)
+                                               oldval = g.design_style_values[Name];
+                                       else if (HasDefaultValue)
+                                               oldval = DefaultValue?.ToString();
+                                       else if (IsSetByIML)
+                                               oldval = g.design_iml_values [Name];
+                                       
+                                       if (valstr == oldval){
+                                               if (IsSetByIML){
+                                                       g.design_iml_values.Remove(Name);
+                                                       Debug.WriteLine("iml attrib removed {0}.{1}", g.Name, Name);
+                                               }else
+                                                       return;
+                                       }else{
+                                               if (IsSetByIML){
+                                                       g.design_iml_values [Name] = valstr;
+                                                       Debug.WriteLine("iml update {0}.{1} = {2}", g.Name, Name, valstr);
+                                               }else{
+                                                       g.design_iml_values.Add(Name,valstr);
+                                                       Debug.WriteLine("iml add {0}.{1} = {2}", g.Name, Name, valstr);
+                                               }
+                                       }
+
+                                       if (!pi.PropertyType.IsAssignableFrom(value.GetType()) && pi.PropertyType != typeof(string)){
+                                               if (pi.PropertyType.IsEnum) {
+                                                       if (value is string) {
+                                                               pi.SetValue (g, Enum.Parse (pi.PropertyType, (string)value));
+                                                       }else
+                                                               pi.SetValue (g, value);
+                                               } else {
+                                                       MethodInfo me = pi.PropertyType.GetMethod
+                                                               ("Parse", BindingFlags.Static | BindingFlags.Public,
+                                                                       System.Type.DefaultBinder, new Type [] {typeof (string)},null);
+                                                       pi.SetValue (g, me.Invoke (null, new object[] { value }), null);
+                                               }
+                                       }else
+                                               pi.SetValue(g, value);
+                                       
+                                       mview.ProjectNode.Instance.design_HasChanged = true;
+                                       NotifyValueChanged ("Value", value);
+                                       NotifyValueChanged ("LabForeground", LabForeground);
+                               } catch (Exception ex) {
+                                       System.Diagnostics.Debug.WriteLine ("Error setting property:"+ ex.ToString());
+                               }
+                               //
+                       }
+               }
+               /// <summary>
+               /// for style attribute which is a string, return Style as type
+               /// </summary>
+               public string Type { get { return pi.PropertyType.IsEnum ?
+                               "System.Enum"
+                                       : pi.Name == "Style" ? "Style" : pi.PropertyType.FullName; }}
+               
+               public object[] Choices {
+                       get {
+                               return pi.PropertyType.IsEnum ?
+                                       Enum.GetValues (pi.PropertyType).Cast<object>().ToArray() :
+                                       mview.ProjectNode.Project.solution.AvailaibleStyles;
+                       }
+               }
+               /// <summary>
+               /// Current graphicobject instance
+               /// </summary>
+               public GraphicObject Instance {
+                       get { return mview.ProjectNode.SelectedItem as GraphicObject; }
+               }
+               public object DefaultValue {
+                       get { return ((DefaultValueAttribute)(pi.GetCustomAttribute (typeof (DefaultValueAttribute)))).Value; }
+               }
+               public bool HasDefaultValue {
+                       get { return pi.GetCustomAttribute (typeof(DefaultValueAttribute))!=null; }
+               }
+               /// <summary>
+               /// return true if current value comes from IML attributes
+               /// </summary>
+               public bool IsSetByIML {
+                       get { return Instance.design_iml_values.ContainsKey (Name); }
+               }
+               /// <summary>
+               /// return true if member default value comes from style
+               /// </summary>
+               public bool HasStyling {
+                       get { return Instance.design_style_locations.ContainsKey(Name); }
+               }
+               /// <summary>
+               /// Return true if current value comes from styling
+               /// </summary>
+               public bool IsSetByStyling {
+                       get { return IsSetByIML ? false : HasStyling; }
+               }
+
+
+               public Fill LabForeground {
+                       get { return IsSetByIML ? Color.DarkBlue : HasStyling ? Color.Black : Color.DimGray;}
+               }
+
+               /// <summary>
+               /// reset to default value
+               /// </summary>
+               public void Reset () {
+                       GraphicObject inst = mview.ProjectNode.SelectedItem as GraphicObject;
+                       if (!inst.design_iml_values.ContainsKey (Name))
+                               return;
+                       inst.design_iml_values.Remove (Name);
+                       //NotifyValueChanged ("Value", Value);
+                       mview.ProjectNode.Instance.design_HasChanged = true;
+                       //should reinstantiate to get default
+               }
+               public void GotoStyle(){
+                       GraphicObject g = Instance;
+                       if (!g.design_style_locations.ContainsKey (Name))
+                               return;
+                       FileLocation fl = g.design_style_locations [Name];
+                       ProjectFile pf;
+                       if (!mview.ProjectNode.Project.TryGetProjectFileFromPath ("#" + fl.FilePath, out pf))
+                               return;
+                       Solution s = mview.ProjectNode.Project.solution;
+                       if (!s.OpenedItems.Contains (pf))                               
+                               s.OpenedItems.AddElement (pf);
+                       pf.CurrentLine = fl.Line;
+                       pf.CurrentColumn = fl.Column;
+               }
+
+               public override string ToString ()
+               {
+                       return string.Format ("{0} = {1}", Name, Value);
+               }
+       }
+}
+
diff --git a/CrowIDE/src/MembersView.cs b/CrowIDE/src/MembersView.cs
deleted file mode 100644 (file)
index f0c3a13..0000000
+++ /dev/null
@@ -1,129 +0,0 @@
-//
-//  MembersView.cs
-//
-//  Author:
-//       Jean-Philippe Bruyère <jp.bruyere@hotmail.com>
-//
-//  Copyright (c) 2016 jp
-//
-//  This program is free software: you can redistribute it and/or modify
-//  it under the terms of the GNU General Public License as published by
-//  the Free Software Foundation, either version 3 of the License, or
-//  (at your option) any later version.
-//
-//  This program is distributed in the hope that it will be useful,
-//  but WITHOUT ANY WARRANTY; without even the implied warranty of
-//  MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
-//  GNU General Public License for more details.
-//
-//  You should have received a copy of the GNU General Public License
-//  along with this program.  If not, see <http://www.gnu.org/licenses/>.
-using System;
-using Crow;
-using System.Xml.Serialization;
-using System.ComponentModel;
-using System.Reflection;
-using System.Collections.Generic;
-using System.Linq;
-using Cairo;
-
-namespace Crow.Coding
-{      
-       public class MembersView : ListBox
-       {               
-               object instance;
-               ImlProjectItem projFile;
-
-               public MembersView () : base() {}
-
-               //cache property containers per type
-               Dictionary<string,PropertyContainer[]> propContainersCache = new Dictionary<string, PropertyContainer[]>();
-
-               [XmlAttributeAttribute][DefaultValue(null)]
-               public virtual object Instance {
-                       get { return instance; }
-                       set {
-                               if (instance == value)
-                                       return;
-                               object lastInst = instance;
-
-                               instance = value;
-                               NotifyValueChanged ("Instance", instance);
-
-                               if (Instance is GraphicObject) {
-                                       NotifyValueChanged ("SelectedItemName", Instance.GetType().Name + (Instance as GraphicObject).design_id
-                                               + ":" + (Instance as GraphicObject).design_imlPath );
-                               }else
-                                       NotifyValueChanged ("SelectedItemName", "");
-
-                               if (instance == null) { 
-                                       Data = null;
-                                       return;
-                               }       
-
-                               Type it = instance.GetType ();
-                               if (!propContainersCache.ContainsKey (it.FullName)) {
-                                       MemberInfo[] members = it.GetMembers (BindingFlags.Public | BindingFlags.Instance);
-                                       List<PropertyContainer> props = new List<PropertyContainer> ();
-                                       foreach (MemberInfo m in members) {
-                                               if (m.MemberType == MemberTypes.Property) {
-                                                       PropertyInfo pi = m as PropertyInfo;
-                                                       if (!pi.CanWrite)
-                                                               continue;
-                                                       if (pi.GetCustomAttribute (typeof(XmlIgnoreAttribute)) != null)
-                                                               continue;
-                                                       props.Add (new PropertyContainer (this, pi));
-                                               }
-                                       }
-                                       propContainersCache.Add (it.FullName, props.OrderBy (p => p.Name).ToArray ());
-                               }
-
-                               Data = propContainersCache [it.FullName];
-
-                               if (lastInst != instance) {
-                                       foreach (PropertyContainer pc in propContainersCache [it.FullName]) {
-                                               pc.NotifyValueChanged ("Value", pc.Value);
-                                       }
-                               }
-                       }
-               }
-               public ImlProjectItem ProjectNode {
-                       get { return projFile; }
-                       set {
-                               if (projFile == value)
-                                       return;
-                               
-//                             if (projFile != null)
-//                                     projFile.UnregisterEditor (this);
-                               
-                               projFile = value;
-
-//                             if (projFile != null)
-//                                     projFile.RegisterEditor (this);
-
-                               NotifyValueChanged ("ProjectNode", projFile);
-                       }
-               }
-
-               public void updateSource () {
-                       if (projFile == null)
-                               return;
-                       projFile.UpdateSource (this, (Instance as GraphicObject).GetIML ());
-               }
-
-//             public override void Paint (ref Context ctx)
-//             {
-//                     base.Paint (ref ctx);
-//
-//                     if (SelectedIndex < 0)
-//                             return;
-//
-//                     Rectangle r =  Parent.ContextCoordinates(Items [SelectedIndex].Slot);
-//                     ctx.SetSourceRGB (0, 0, 1);
-//                     ctx.Rectangle (r);
-//                     ctx.LineWidth = 2;
-//                     ctx.Stroke ();
-//             }
-
-       }
-}
index ff3469de759db5395727be4c4d0c120766e9d788..5e6c98d9e76a66d69de6c34a76fee135ae11ed25 100644 (file)
@@ -46,6 +46,7 @@ namespace Crow.Coding
                #endregion
 
                bool isLoaded = false;
+               bool isExpanded;
                XmlDocument xmlDoc;
                XmlNode nodeProject;
                XmlNode nodeProps;
@@ -72,6 +73,17 @@ namespace Crow.Coding
                                NotifyValueChanged ("IsLoaded", isLoaded);
                        }
                }
+               public bool IsExpanded
+               {
+                       get { return isExpanded; }
+                       set
+                       {
+                               if (value == isExpanded)
+                                       return;
+                               isExpanded = value;
+                               NotifyValueChanged ("IsExpanded", isExpanded);
+                       }
+               }
                public bool IsStartupProject {
                        get { return solution.StartupProject == this; }
                }
@@ -100,17 +112,17 @@ namespace Crow.Coding
                        flattenNodes = new List<ProjectNode> ();
 
                        ProjectNode refs = new ProjectNode (this, ItemType.ReferenceGroup, "References");
-                       root.ChildNodes.Add (refs);
+                       root.AddChild (refs);
 
                        foreach (ProjectItem pn in items) {
                                switch (pn.Type) {
                                case ItemType.Reference:
-                                       refs.ChildNodes.Add (pn);
+                                       refs.AddChild (pn);
                                        flattenNodes.Add (pn);
                                        break;                                  
                                case ItemType.ProjectReference:
                                        ProjectReference pr = new ProjectReference (pn); 
-                                       refs.ChildNodes.Add (pr);
+                                       refs.AddChild (pr);
                                        flattenNodes.Add (pr);
                                        break;                                  
                                case ItemType.Compile:
@@ -122,7 +134,7 @@ namespace Crow.Coding
                                                ProjectNode nextNode = curNode.ChildNodes.FirstOrDefault (n => n.DisplayName == folds [i] && n.Type == ItemType.VirtualGroup);
                                                if (nextNode == null) {
                                                        nextNode = new ProjectNode (this, ItemType.VirtualGroup, folds [i]);
-                                                       curNode.ChildNodes.Add (nextNode);
+                                                       curNode.AddChild (nextNode);
                                                }
                                                curNode = nextNode;
                                        }
@@ -136,7 +148,7 @@ namespace Crow.Coding
                                                f = new ProjectFile (pn);
                                                break;
                                        }
-                                       curNode.ChildNodes.Add (f);
+                                       curNode.AddChild (f);
                                        flattenNodes.Add (f);
                                        break;
                                }
index c334826674e7883efbb2d191dc03796ae59e8a6f..bf213c277cdca8c52ecd8713c9e21bd3c96ed82d 100644 (file)
@@ -74,6 +74,8 @@ namespace Crow.Coding
                        Commands = new List<Crow.Command> ();
                }
 
+               ProjectNode parent;
+               bool isExpanded;
                ItemType type;
                string name;
                List<ProjectNode> childNodes = new List<ProjectNode>();
@@ -81,6 +83,10 @@ namespace Crow.Coding
                public Project Project;
                public List<Crow.Command> Commands;//list of command available for that node
 
+               public ProjectNode Parent {
+                       get { return parent; }
+                       set { parent = value; }
+               }
                public virtual ItemType Type {
                        get { return type; }
                }
@@ -90,12 +96,32 @@ namespace Crow.Coding
                public List<ProjectNode> ChildNodes {
                        get { return childNodes;        }
                }
-
+               public void AddChild (ProjectNode pn) {
+                       childNodes.Add(pn);
+                       pn.Parent = this;
+               }
+               public void RemoveChild (ProjectNode pn){
+                       pn.Parent = null;
+                       childNodes.Remove (pn);
+               }
                public void SortChilds () {
                        foreach (ProjectNode pn in childNodes)
                                pn.SortChilds ();                       
                        childNodes = childNodes.OrderBy(c=>c.Type).ThenBy(cn=>cn.DisplayName).ToList();
                }
+
+               public bool IsExpanded
+               {
+                       get { return isExpanded; }
+                       set
+                       {
+                               if (value == isExpanded)
+                                       return;
+                               isExpanded = value;
+                               NotifyValueChanged ("IsExpanded", isExpanded);
+                       }
+               }
+
                public override string ToString ()
                {
                        return DisplayName;
diff --git a/CrowIDE/src/PropertyContainer.cs b/CrowIDE/src/PropertyContainer.cs
deleted file mode 100644 (file)
index c89273c..0000000
+++ /dev/null
@@ -1,169 +0,0 @@
-//
-// PropertyContainer.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.Reflection;
-using System.Linq;
-using System.Collections.Generic;
-using System.Diagnostics;
-
-namespace Crow.Coding
-{
-       public class PropertyContainer : IValueChange
-       {
-               #region IValueChange implementation
-               public event EventHandler<ValueChangeEventArgs> ValueChanged;
-               public virtual void NotifyValueChanged(string MemberName, object _value)
-               {
-                       ValueChanged.Raise(this, new ValueChangeEventArgs(MemberName, _value));
-               }
-               #endregion
-
-               public List<Crow.Command> Commands;
-               Command cmdReset, cmdGoToStyle;
-               PropertyInfo pi;
-               MembersView mview;
-//             object instance;
-//             GraphicObject go;
-
-               public PropertyContainer(MembersView mv, PropertyInfo prop){
-                       mview = mv;
-                       pi = prop;
-//                     instance = _instance;
-//                     go = instance as GraphicObject;
-
-                       cmdReset = new Crow.Command (new Action (() => Reset ())) { Caption = "Reset to default" };
-                       cmdGoToStyle = new Crow.Command (new Action (() => GotoStyle ())) { Caption = "Goto style" };
-
-                       Commands = new List<Crow.Command> (new Crow.Command[] { cmdReset, cmdGoToStyle });
-               }
-
-               public string Name { get { return pi.Name; }}
-               public object Value {
-                       get {
-                               return pi.GetValue(mview.ProjectNode.SelectedItem);
-//                             GraphicObject inst = mview.ProjectNode.SelectedItem as GraphicObject;
-//                             Debug.WriteLine("read {0}.{1}", inst.Name, Name);
-//                             if (!inst.design_members.ContainsKey (Name))
-//                                     return pi.GetValue (inst);
-//                             
-//                             if (inst.design_members [Name].StartsWith ("{"))
-//                                     return inst.design_members [Name];
-//                             else
-//                                     return pi.GetValue (inst);
-                       }
-                       set {
-                               try {
-                                       GraphicObject inst = mview.ProjectNode.SelectedItem as GraphicObject;
-                                       string valstr = null;
-                                       if (value != null)
-                                               valstr = value.ToString();
-                                       if (inst.design_members.ContainsKey (Name)) {
-                                               if (inst.design_members [Name] == valstr)
-                                                       return;
-                                               Debug.WriteLine("update {0} : {1} = {2}", inst.Name, Name, valstr);
-                                               inst.design_members [Name] = value.ToString();
-                                       } else {
-                                               Debug.WriteLine("add {0} : {1} = {2}", inst.Name, Name, valstr);
-                                               inst.design_members.Add (Name, value.ToString());
-                                       }                               
-
-                                       if (!pi.PropertyType.IsAssignableFrom(value.GetType()) && pi.PropertyType != typeof(string)){
-                                               if (pi.PropertyType.IsEnum) {
-                                                       if (value is string) {
-                                                               pi.SetValue (inst, Enum.Parse (pi.PropertyType, (string)value));
-                                                       }else
-                                                               pi.SetValue (inst, value);
-                                               } else {
-                                                       MethodInfo me = pi.PropertyType.GetMethod
-                                                               ("Parse", BindingFlags.Static | BindingFlags.Public,
-                                                                       System.Type.DefaultBinder, new Type [] {typeof (string)},null);
-                                                       pi.SetValue (inst, me.Invoke (null, new object[] { value }), null);
-                                               }
-                                       }else
-                                               pi.SetValue(inst, value);
-                                       
-                                       mview.ProjectNode.Instance.HasChanged = true;
-                                       NotifyValueChanged ("Value", value);
-                                       NotifyValueChanged ("LabForeground", LabForeground);
-                               } catch (Exception ex) {
-                                       System.Diagnostics.Debug.WriteLine ("Error setting property:"+ ex.ToString());
-                               }
-                               //
-                       }
-               }
-               /// <summary>
-               /// for style attribute which is a string, return Style as type
-               /// </summary>
-               public string Type { get { return pi.PropertyType.IsEnum ?
-                               "System.Enum"
-                                       : pi.Name == "Style" ? "Style" : pi.PropertyType.FullName; }}
-               
-               public object[] Choices {
-                       get {
-                               return pi.PropertyType.IsEnum ?
-                                       Enum.GetValues (pi.PropertyType).Cast<object>().ToArray() :
-                                       mview.ProjectNode.Project.solution.AvailaibleStyles;
-                       }
-               }
-
-               public Fill LabForeground {
-                       get {
-                               GraphicObject go = mview.ProjectNode.SelectedItem as GraphicObject;
-                               return go.design_members.ContainsKey (Name) ? Color.Black :
-                                       go.design_defaults.ContainsKey(Name) ? Color.DarkBlue : Color.DimGray;}
-               }
-
-               /// <summary>
-               /// reset to default value
-               /// </summary>
-               public void Reset () {
-                       GraphicObject inst = mview.ProjectNode.SelectedItem as GraphicObject;
-                       if (!inst.design_members.ContainsKey (Name))
-                               return;
-                       inst.design_members.Remove (Name);
-                       //NotifyValueChanged ("Value", Value);
-                       mview.ProjectNode.Instance.HasChanged = true;
-                       //should reinstantiate to get default
-               }
-               public void GotoStyle(){
-                       GraphicObject inst = mview.ProjectNode.SelectedItem as GraphicObject;
-                       if (!inst.design_defaults.ContainsKey (Name))
-                               return;
-                       FileLocation fl = inst.design_defaults [Name];
-                       ProjectFile pf;
-                       if (!mview.ProjectNode.Project.TryGetProjectFileFromPath ("#" + fl.FilePath, out pf))
-                               return;
-                       Solution s = mview.ProjectNode.Project.solution;
-                       if (!s.OpenedItems.Contains (pf))                               
-                               s.OpenedItems.Add (pf);
-                       //pf.CurrentLine = fl.Line;
-                       //pf.CurrentColumn = fl.Column;
-               }
-
-
-       }
-}
-
index 7ed6b7800d8141c296457876ebba2810ad91659f..b1ccedca8744dce74acf6b5cd8fda63289c86d0d 100644 (file)
@@ -138,10 +138,13 @@ namespace Crow.Coding{
                        NotifyValueChanged ("CompilerErrors", CompilerErrors);
                }
 
-               void saveOpenedItemsInUserConfig (){                    
-                       UserConfig.Set ("OpenedItems", openedItems.Select(o => o.AbsolutePath).Aggregate((a,b)=>a + ";" + b));
+               void saveOpenedItemsInUserConfig (){
+                       if (openedItems.Count == 0)
+                               UserConfig.Set ("OpenedItems", "");
+                       else
+                               UserConfig.Set ("OpenedItems", openedItems.Select(o => o.AbsolutePath).Aggregate((a,b)=>a + ";" + b));
                }
-               void reopenItemsSavedInUserConfig () {
+               public void ReopenItemsSavedInUserConfig () {
                        string tmp = UserConfig.Get<string> ("OpenedItems");
                        string sel = UserConfig.Get<string> ("SelectedProjItems");
                        ProjectFile selItem = null;
@@ -151,7 +154,13 @@ namespace Crow.Coding{
                                foreach (Project p in Projects) {
                                        ProjectFile pi;
                                        if (p.TryGetProjectFileFromAbsolutePath (f, out pi)) {
-                                               OpenedItems.Add (pi);
+                                               OpenedItems.AddElement (pi);
+                                               pi.Project.IsExpanded = true;
+                                               ProjectNode pn = pi.Parent;
+                                               while (pn != null) {
+                                                       pn.IsExpanded = true;
+                                                       pn = pn.Parent;
+                                               }
                                                if (pi.AbsolutePath == sel)
                                                        selItem = pi;
                                                break;
@@ -442,7 +451,6 @@ namespace Crow.Coding{
                        s.UserConfig = new Configuration (s.path + ".user");
                        s.ReloadStyling ();
                        s.ReloadDefaultTemplates ();
-                       s.reopenItemsSavedInUserConfig ();
                return s;
            } //LoadSolution
                #endregion
index 66c24857ca810b771dfbdac999bf8200db2aef57..ec9bbc3eb60c99ea68586d39a08fdc9d54e85d91 100644 (file)
@@ -69,70 +69,70 @@ namespace Crow.Coding
                                        return;
                                editMutex.EnterWriteLock ();
                                lines [i] = value;
-                               LineUpadateEvent.Raise (this, new CodeBufferEventArgs (i));
                                editMutex.ExitWriteLock ();
+                               LineUpadateEvent.Raise (this, new CodeBufferEventArgs (i));
                        }
                }
 
                public void RemoveAt(int i){
                        editMutex.EnterWriteLock ();
                        lines.RemoveAt (i);
-                       LineRemoveEvent.Raise (this, new CodeBufferEventArgs (i));
                        editMutex.ExitWriteLock ();
+                       LineRemoveEvent.Raise (this, new CodeBufferEventArgs (i));
                }
                public void Insert(int i, string item){
                        editMutex.EnterWriteLock ();
                        lines.Insert (i, item);
-                       LineAdditionEvent.Raise (this, new CodeBufferEventArgs (i));
                        editMutex.ExitWriteLock ();
+                       LineAdditionEvent.Raise (this, new CodeBufferEventArgs (i));
                }
                public void Add(CodeLine item){
                        editMutex.EnterWriteLock ();
                        lines.Add (item);
-                       LineAdditionEvent.Raise (this, new CodeBufferEventArgs (lines.Count - 1));
                        editMutex.ExitWriteLock ();
+                       LineAdditionEvent.Raise (this, new CodeBufferEventArgs (lines.Count - 1));
                }
                public void AddRange (string[] items){
                        int start = lines.Count;
                        editMutex.EnterWriteLock ();
                        for (int i = 0; i < items.Length; i++)
                                lines.Add (items [i]);
-                       LineAdditionEvent.Raise (this, new CodeBufferEventArgs (start, items.Length));
                        editMutex.ExitWriteLock ();
+                       LineAdditionEvent.Raise (this, new CodeBufferEventArgs (start, items.Length));
                }
                public void AddRange (CodeLine[] items){
                        int start = lines.Count;
                        editMutex.EnterWriteLock ();
                        lines.AddRange (items);
-                       LineAdditionEvent.Raise (this, new CodeBufferEventArgs (start, items.Length));
                        editMutex.ExitWriteLock ();
+                       LineAdditionEvent.Raise (this, new CodeBufferEventArgs (start, items.Length));
                }
                public void Clear () {
                        editMutex.EnterWriteLock ();
                        longestLineCharCount = 0;
                        lines.Clear ();
-                       BufferCleared.Raise (this, null);
                        editMutex.ExitWriteLock ();
+                       BufferCleared.Raise (this, null);
                }
                public void UpdateLine(int i, string newContent){
                        editMutex.EnterWriteLock ();
                        this [i].Content = newContent;
-                       LineUpadateEvent.Raise (this, new CodeBufferEventArgs (i));
                        editMutex.ExitWriteLock ();
+                       LineUpadateEvent.Raise (this, new CodeBufferEventArgs (i));
                }
                public void AppenedLine(int i, string newContent){
                        editMutex.EnterWriteLock ();
                        this [i].Content += newContent;
-                       LineUpadateEvent.Raise (this, new CodeBufferEventArgs (i));
                        editMutex.ExitWriteLock ();
+                       LineUpadateEvent.Raise (this, new CodeBufferEventArgs (i));
                }
                public void ToogleFolding (int line) {
                        if (!this [line].IsFoldable)
                                return;
                        editMutex.EnterWriteLock ();
                        this [line].IsFolded = !this [line].IsFolded;
-                       FoldingEvent.Raise (this, new CodeBufferEventArgs (line));
                        editMutex.ExitWriteLock ();
+                       FoldingEvent.Raise (this, new CodeBufferEventArgs (line));
                }
                public void Load(string rawSource, string lineBrkRegex = @"\r\n|\r|\n|\\\n") {
                        this.Clear();
@@ -150,13 +150,15 @@ namespace Crow.Coding
                /// </summary>
                public void FindLongestVisualLine(){
                        longestLineCharCount = 0;
+                       editMutex.EnterReadLock ();
                        for (int i = 0; i < this.LineCount; i++) {
                                if (lines[i].PrintableLength > longestLineCharCount) {
                                        longestLineCharCount = lines[i].PrintableLength;
                                        longestLineIdx = i;
                                }
                        }
-                       Debug.WriteLine ("Longest line: {0}->{1}", longestLineIdx, longestLineCharCount);
+                       editMutex.ExitReadLock ();
+                       //Debug.WriteLine ("Longest line: {0}->{1}", longestLineIdx, longestLineCharCount);
                }
                /// <summary> line break could be '\r' or '\n' or '\r\n' </summary>
                static string detectLineBreakKind(string buffer){
@@ -190,9 +192,11 @@ namespace Crow.Coding
                                if (lines.Count == 0)
                                        return "";
                                string tmp = "";
+                               editMutex.EnterReadLock ();
                                for (int i = 0; i < lines.Count -1; i++)
                                        tmp += lines [i].Content + this.lineBreak;
                                tmp += lines [lines.Count - 1].Content;
+                               editMutex.ExitReadLock ();
                                return tmp;
                        }
                }
@@ -203,12 +207,14 @@ namespace Crow.Coding
                public int UnfoldedLines {
                        get {
                                int i = 0, vl = 0;
+                               editMutex.EnterReadLock ();
                                while (i < LineCount) {
                                        if (this [i].IsFolded)
                                                i = GetEndNodeIndex (i);
                                        i++;
                                        vl++;
                                }
+                               editMutex.ExitReadLock ();
                                //Debug.WriteLine ("unfolded lines: " + vl);
                                return vl;
                        }
@@ -249,7 +255,7 @@ namespace Crow.Coding
                        return i;
                }
 
-               int CurrentTabulatedColumn {
+               public int CurrentTabulatedColumn {
                        get {
                                return lines [_currentLine].Content.Substring (0, _currentCol).
                                        Replace ("\t", new String (' ', Interface.TabSize)).Length;
@@ -330,6 +336,9 @@ namespace Crow.Coding
                        set {
                                if (value == _currentCol)
                                        return;
+
+                               editMutex.EnterReadLock ();
+
                                if (value < 0)
                                        _currentCol = 0;
                                else if (value > lines [_currentLine].Length)
@@ -338,7 +347,8 @@ namespace Crow.Coding
                                        _currentCol = value;
 
                                requestedColumn = CurrentTabulatedColumn;
-                               //requestedColumn = _currentCol;
+
+                               editMutex.ExitReadLock ();
 
                                PositionChanged.Raise (this, null);
                        }
@@ -351,6 +361,9 @@ namespace Crow.Coding
                        set {
                                if (value == _currentLine)
                                        return;
+
+                               editMutex.EnterReadLock ();
+
                                if (value >= lines.Count)
                                        _currentLine = lines.Count-1;
                                else if (value < 0)
@@ -366,6 +379,9 @@ namespace Crow.Coding
                                        //_currentCol = requestedColumn;
                                        _currentCol = tabulatedRequestedCol;
                                //Debug.WriteLine ("buff cur line: " + _currentLine);
+
+                               editMutex.ExitReadLock();
+
                                PositionChanged.Raise (this, null);
                        }
                }
index b0e8a35fb90d57202a7c349c2ed1a27c411cde84..1264f4a164bd3e659e3f4b32c249558925398c54 100644 (file)
@@ -44,6 +44,8 @@ namespace Crow.Coding
        /// </summary>
        public class SourceEditor : ScrollingObject
        {
+               public ReaderWriterLockSlim seMutex = new ReaderWriterLockSlim(LockRecursionPolicy.SupportsRecursion);
+
                #region CTOR
                public SourceEditor (): base()
                {
@@ -91,6 +93,8 @@ namespace Crow.Coding
                                                loadSource ();
                                                isDirty = false;
                                                oldSource = projFile.Source;
+                                               CurrentLine = requestedLine;
+                                               CurrentColumn = requestedCol;
                                                projFile.RegisteredEditors [this] = true;
                                        }
                                        buffer.editMutex.EnterWriteLock ();
@@ -153,7 +157,7 @@ namespace Crow.Coding
                }
                void findLongestLineAndUpdateMaxScrollX() {
                        buffer.FindLongestVisualLine ();
-                       MaxScrollX = Math.Max (0, buffer.longestLineCharCount - visibleColumns);
+                       updateMaxScrollX ();
 //                     Debug.WriteLine ("SourceEditor: Find Longest line and update maxscrollx: {0} visible cols:{1}", MaxScrollX, visibleColumns);
                }
                /// <summary>
@@ -170,11 +174,16 @@ namespace Crow.Coding
                }
                void updateVisibleColumns(){
                        visibleColumns = (int)Math.Floor ((double)(ClientRectangle.Width - leftMargin)/ fe.MaxXAdvance);
-                       MaxScrollX = Math.Max (0, buffer.longestLineCharCount - visibleColumns);
-
+                       NotifyValueChanged ("VisibleColumns", visibleColumns);
+                       updateMaxScrollX ();
 //                     System.Diagnostics.Debug.WriteLine ("update visible columns: {0} leftMargin:{1}",visibleColumns, leftMargin);
 //                     System.Diagnostics.Debug.WriteLine ("update MaxScrollX: " + MaxScrollX);
                }
+               void updateMaxScrollX () {
+                       MaxScrollX = Math.Max (0, buffer.longestLineCharCount - visibleColumns);
+                       if (buffer.longestLineCharCount > 0)
+                               NotifyValueChanged ("ChildWidthRatio", Slot.Width * visibleColumns / buffer.longestLineCharCount);                      
+               }
                void updateMaxScrollY () {
                        if (parser == null || !foldingEnabled) {
                                MaxScrollY = Math.Max (0, buffer.LineCount - visibleLines);
@@ -188,6 +197,8 @@ namespace Crow.Coding
                }                       
                void updatePrintedLines () {
                        buffer.editMutex.EnterReadLock ();
+                       seMutex.EnterWriteLock ();
+
                        PrintedLines = new List<CodeLine> ();
                        int curL = 0;
                        int i = 0;
@@ -210,7 +221,9 @@ namespace Crow.Coding
                                curL++;
                                i++;
                        }
+
                        buffer.editMutex.ExitReadLock ();
+                       seMutex.ExitWriteLock ();
                }
                void toogleFolding (int line) {
                        if (parser == null || !foldingEnabled)
@@ -223,6 +236,8 @@ namespace Crow.Coding
                #region Buffer events handlers
                void Buffer_BufferCleared (object sender, EventArgs e)
                {
+                       seMutex.EnterWriteLock ();
+
                        buffer.longestLineCharCount = 0;
                        buffer.longestLineIdx = 0;
                        measureLeftMargin ();
@@ -231,6 +246,8 @@ namespace Crow.Coding
                        RegisterForGraphicUpdate ();
                        notifyPositionChanged ();
                        isDirty = true;
+
+                       seMutex.ExitWriteLock ();
                }
                void Buffer_LineAdditionEvent (object sender, CodeBufferEventArgs e)
                {
@@ -297,6 +314,14 @@ namespace Crow.Coding
                }
                void Buffer_PositionChanged (object sender, EventArgs e)
                {
+                       Console.WriteLine ("Position changes: ({0},{1})", buffer.CurrentLine, buffer.CurrentColumn);
+                       int cc = buffer.CurrentTabulatedColumn;
+
+                       if (cc > visibleColumns + ScrollX) {
+                               ScrollX = cc - visibleColumns;
+                       } else if (cc < ScrollX)
+                               ScrollX = cc;
+                       
                        RegisterForGraphicUpdate ();
                        updateOnScreenCurLineFromBuffCurLine ();
                        notifyPositionChanged ();
@@ -318,22 +343,29 @@ namespace Crow.Coding
                public int CurrentColumn{
                        get { return buffer == null ? 0 : buffer.CurrentColumn+1; }
                        set {
-                               try {
+                               try {                                   
+                                       if (value - 1 == buffer.CurrentColumn)
+                                               return;
                                        buffer.CurrentColumn = value - 1;
                                } catch (Exception ex) {
+                                       requestedCol = value - 1;
                                        Console.WriteLine ("Error cur column: " + ex.ToString ());
                                }
                        }
                }
+               int requestedLine = 0, requestedCol = 0;
                public int CurrentLine{
                        get { return buffer == null ? 0 : buffer.CurrentLine+1; }
                        set {
                                try {
                                        int l = value - 1;
+                                       if (l == buffer.CurrentLine)
+                                               return;
                                        buffer.CurrentLine = l;
                                        if (buffer [l].IsFolded)
                                                buffer.ToogleFolding (l);                                       
                                } catch (Exception ex) {
+                                       requestedLine = value - 1;
                                        Console.WriteLine ("Error cur column: " + ex.ToString ());
                                }
                        }
@@ -800,6 +832,8 @@ namespace Crow.Coding
                        }
                        #endregion
 
+                       seMutex.EnterReadLock ();
+
                        if (PrintedLines != null) {
                                for (int i = 0; i < visibleLines; i++) {
                                        if (i + ScrollY >= buffer.UnfoldedLines)//TODO:need optimize
@@ -807,6 +841,9 @@ namespace Crow.Coding
                                        drawLine (gr, cb, i);
                                }
                        }
+
+                       seMutex.ExitReadLock ();
+
                        buffer.editMutex.ExitReadLock ();
 
                }
index 812d7884acf00873b71e25762fb8961f98aec81e..3a9774908018bf50916048254cc7a6dea3c8acef 100755 (executable)
@@ -5,6 +5,28 @@
                <TextBox Margin="1" Text="{²Value}" Height="Fit" Foreground = "{LabForeground}"/>
        </HorizontalStack>
 </ItemTemplate>
+<ItemTemplate DataType="Crow.Coding.CategoryContainer" Data="Properties" DataTest="Type">
+       <Expandable Caption="{Name}" IsExpanded="{IsExpanded}" Background="Gray" Foreground="Black">
+               <Template>
+                       <VerticalStack>
+                               <HorizontalStack Spacing="1" Height="Fit" MouseDoubleClick="./onClickForExpand" Background="Gray">
+                                       <Container Margin="1" Width="9" Height="9" Focusable="true" MouseDown="./onClickForExpand"
+                                                                                                                               MouseEnter="{Background=LightGray}"
+                                                                                                                               MouseLeave="{Background=Transparent}">
+                                               <Image
+                                                       Path="#Crow.Images.Icons.expandable.svg"
+                                                       Visible="{./IsExpandable}"
+                                                       SvgSub="{./IsExpanded}"/>
+                                       </Container>
+                                       <Label Foreground="White" Text="{./Caption}"/>
+                               </HorizontalStack>
+                               <Container Name="Content" Visible="false"/>
+                       </VerticalStack>
+               </Template>
+               <VerticalStack Spacing="1" Height="Fit" Name="ItemsContainer"
+                       Margin="0" VerticalAlignment="Top"/>
+       </Expandable>
+</ItemTemplate>
 <ItemTemplate DataType="System.Boolean" >
        <HorizontalStack Style="MemberViewHStack" ContextCommands="{Commands}">
                <Label Style="MemberViewLabel" Text="{Name}" Foreground = "{LabForeground}"/>
index 2a9a7655658e5e9e9a9db4435e65091ad65eda3f..e0add31d373fe0303539248058a31dc1536891da 100644 (file)
@@ -3,7 +3,7 @@
        <Label Text="{}" Background="DarkRed" Foreground="White"/>
 </ItemTemplate>
 <ItemTemplate DataType="Crow.Coding.Project" Data="RootItems" DataTest="Type">
-       <Expandable Caption="{Name}" ContextCommands="{Commands}" >
+       <Expandable Caption="{Name}" ContextCommands="{Commands}" IsExpanded="{²IsExpanded}">
                <Template>
                        <VerticalStack>
                                <Border CornerRadius="2" Margin="0" Height="Fit" MouseDoubleClick="./onClickForExpand"                                          
@@ -32,8 +32,8 @@
                </HorizontalStack>
        </Expandable>
 </ItemTemplate>
-<ItemTemplate DataType="ReferenceGroup" Data="ChildNodes" DataTest="Type">
-       <Expandable Caption="{DisplayName}" Template="#Crow.TreeExpandable.template" >
+<ItemTemplate DataType="ReferenceGroup" Data="ChildNodes" DataTest="Type" >
+       <Expandable Caption="{DisplayName}" Template="#Crow.TreeExpandable.template" IsExpanded="{²IsExpanded}">
                <HorizontalStack Height="Fit">
                        <GraphicObject Width="8" Height="10"/>
                        <VerticalStack Height="Fit" Name="ItemsContainer"/>
@@ -41,7 +41,7 @@
        </Expandable>
 </ItemTemplate>
 <ItemTemplate DataType="VirtualGroup" Data="ChildNodes" DataTest="Type">
-       <Expandable Caption="{DisplayName}" Template="#Crow.TreeExpandable.template" >
+       <Expandable Caption="{DisplayName}" Template="#Crow.TreeExpandable.template" IsExpanded="{²IsExpanded}">
                <HorizontalStack Height="Fit">
                        <GraphicObject Width="8" Height="10"/>
                        <VerticalStack Height="Fit" Name="ItemsContainer"/>
index 17f491ae6422eecedc8088bffd43a55fa43794ee..a35184dbac7d99687a1b26d686c0b74f0faa6c9d 100644 (file)
@@ -3,6 +3,7 @@
        <VerticalStack>
                <HorizontalStack Height="Stretched" >
                        <SourceEditor Focusable="true" Name="editor" Font="monospace, 12" VerticalAlignment="Top" Margin="10"
+                                       CurrentLine="{²CurrentLine}" CurrentColumn="{²CurrentColumn}"
                                        Foreground="Jet" Background="White" Width="Stretched" Height="Stretched"
                                        ProjectNode="{}"  KeyDown="textView_KeyDown"/>
                        <ScrollBar Name="scrollbarY" Value="{²../editor.ScrollY}"
                </HorizontalStack>
                <ScrollBar Name="scrollbarX" Value="{²../editor.ScrollX}"
                                Maximum="{../editor.MaxScrollX}" Orientation="Horizontal"
+                               LargeIncrement="{../editor.VisibleColumns}"
+                               CursorSize="{../editor.ChildWidthRatio}"
                                Height="14" />                  
                <HorizontalStack Height="Fit">
                        <GraphicObject Height="5" Width="Stretched"/>
                        <GraphicObject Background="Red" Width="5" Height="5" Visible="{../../editor.IsDirty}"/>
-                       <Label Text="column:"/>
-                       <Label Text="{../../editor.CurrentColumn}"/>
                        <Label Text="Line:"/>
-                       <Label Text="{../../editor.CurrentLine}"/>
+                       <Label Text="{CurrentLine}"/>
+                       <Label Text="column:"/>
+                       <Label Text="{CurrentColumn}"/>
                        <Label Text="ScrollX:"/>
                        <Label Text="{../../editor.ScrollX}"/>
                </HorizontalStack>
index c5e42347c95ddb33da07867a8aac3bdf2912bb2f..3c260b5c746f55c7aa7c44d5672b6d0b7b0f4b62 100644 (file)
@@ -58,12 +58,6 @@ MenuItem {
        MouseLeave = "{Foreground=LightGray;Background=Transparent;}";
        SelectionBackground = "Transparent";
 }
-Docker {
-       AllowDrop = "true";
-}
-DockWindow {
-       AllowDrag = "true";
-}
 MessageBox {
        Background = "0.1,0.1,0.2,0.7";
        Width = "Fit";
@@ -79,7 +73,8 @@ Slider {
 }
 Splitter {
        Focusable = "true";
-       Background = "DimGray";
+       Margin = "1";
+       Background = "White";
 }
 Spinner {
        Foreground = "DimGray";
@@ -114,10 +109,20 @@ ToolWindow {
        Width = "150";
        Height = "150";
 }
-DocksView {
+Docker {
+       AllowDrop = "false";
+       Margin="0";
+       Focusable="true";
+}
+DockStack {
+       Margin="1";
        AllowDrop = "true";
+       Focusable="true";
+       DragEnter="{Background=DarkBlue}";
+       DragLeave="{Background=Jet}";
+       EndDrag="{Background=Jet}";
 }
-DockingView {
+DockWindow {
        Focusable = "true";
        AllowDrag = "true";
 }
index 0a3b4e019e55f01986f1e6aa8bcf66822ca174e5..192c6f0966c7831c44c74476bffde4e118dba0cc 100755 (executable)
@@ -1,24 +1,22 @@
 <?xml version="1.0"?>
-<Border BorderWidth="1" Foreground="White" CornerRadius="{./CornerRadius}"
+<GraphicObject Background="{./Background}"/>
+<!--<Border BorderWidth="1" Foreground="White" CornerRadius="{./CornerRadius}"
                                Background="{./Background}"
                                MouseEnter="./onBorderMouseEnter"
                                MouseLeave="./onBorderMouseLeave">
        <VerticalStack Spacing="0">
-<!--           <Border Name="TitleBar" BorderWidth="1" Foreground="White" Width="{./WidthPolicy}" Height="Fit"
-                               Background="vgradient|0:0.4,0.6,0.0,0.5|1:0.0,0.8,0.8,0.9">-->
-                       <HorizontalStack Background="vgradient|0:0.5,0.6,0.5,0.5|1:0.2,0.3,0.3,0.7"
-                                       Name="hs" Margin="2" Spacing="0" Height="Fit">
-                               <GraphicObject Width="5"/>
-                               <Image Margin="1" Width="12" Height="12" Path="{./Icon}"/>
-                               <Label Width="Stretched" Foreground="White" Margin="1" TextAlignment="Center" Text="{./Caption}" />
-                               <Border CornerRadius="6" BorderWidth="1" Foreground="Transparent"  Height="12" Width="12"
-                                       MouseEnter="{Foreground=White}" MouseLeave="{Foreground=Transparent}">
-                                       <Image Focusable="true" Name="Image" Margin="0" Width="Stretched" Height="Stretched" Path="#Crow.Images.Icons.exit2.svg"
-                                                MouseClick="./butQuitPress"/>
-                               </Border>
-                               <GraphicObject Width="5"/>
-                       </HorizontalStack>
-<!--           </Border>-->
+               <HorizontalStack Background="vgradient|0:0.5,0.6,0.5,0.5|1:0.2,0.3,0.3,0.7"
+                               Name="hs" Margin="2" Spacing="0" Height="Fit">
+                       <GraphicObject Width="5"/>
+                       <Image Margin="1" Width="12" Height="12" Path="{./Icon}"/>
+                       <Label Width="Stretched" Foreground="White" Margin="1" TextAlignment="Center" Text="{./Caption}" />
+                       <Border CornerRadius="6" BorderWidth="1" Foreground="Transparent"  Height="12" Width="12"
+                               MouseEnter="{Foreground=White}" MouseLeave="{Foreground=Transparent}">
+                               <Image Focusable="true" Name="Image" Margin="0" Width="Stretched" Height="Stretched" Path="#Crow.Images.Icons.exit2.svg"
+                                        MouseClick="./butQuitPress"/>
+                       </Border>
+                       <GraphicObject Width="5"/>
+               </HorizontalStack>
                <Container Name="Content" MinimumSize="50,50" Background="0.5,0.5,0.5,0.5"/>
        </VerticalStack>
-</Border>
+</Border>-->
index 8a9df9c5a00613283c4109e8c0a17c5c4ee2a036..71301686b7522c7caa36a382d5f2bf0e9b7cb623 100644 (file)
@@ -1,19 +1,26 @@
 <?xml version="1.0"?>
-<!--<Docker Background="Jet" Margin = "0" Focusable="true" >
-       <DockWindow Focusable="true" Caption="View 1" Width="100" Height="100"><GraphicObject Background="Green"/></DockWindow>
-       <DockWindow Focusable="true" Caption="View 2" Resizable = "true" Width="100" Height="100"><GraphicObject Background="Blue"/></DockWindow>
-       <DockWindow Focusable="true" Caption="View 3" Resizable = "true" Width="100" Height="100"><GraphicObject Background="Yellow"/></DockWindow>
-       <DockWindow Focusable="true" Caption="View 4" Resizable = "true" Width="100" Height="100"><GraphicObject Background="Black"/></DockWindow>
-</Docker>-->
+<Docker >
+       <DockWindow Left="100" Top="100" Width="150" Height="150" Background="DarkRed"/>
+       <DockWindow Left="200" Top="200" Width="150" Height="150" Background="DarkGreen"/>
+       <DockWindow Left="300" Top="300" Width="150" Height="150" Background="Blue"/>
+       <DockWindow Left="400" Top="400" Width="150" Height="150" Background="DarkYellow"/>
+       <DockWindow Left="500" Top="500" Width="150" Height="150" Background="Yellow"/>
+</Docker>
 <!--<Group Background="Jet" Margin = "0" Focusable="true" >
        <Window Top="100" Left="100" Focusable="true" Caption="View 1" Width="300" Height="300"><GraphicObject Background="Green" Focusable="true" MouseEnter="{Background=Gray}" MouseLeave="{Background=Green}"/></Window>
        <Window Top="200" Left="200" Focusable="true" Caption="View 2" Resizable = "true" Width="300" Height="300"><GraphicObject Focusable="true" Background="Blue" MouseEnter="{Background=Gray}" MouseLeave="{Background=Blue}"/></Window>
        <Window Top="300" Left="300" Focusable="true" Caption="View 3" Resizable = "true" Width="300" Height="300"><GraphicObject Focusable="true" Background="Yellow" MouseEnter="{Background=Gray}" MouseLeave="{Background=Yellow}"/></Window>
        <Window Top="400" Left="400" Focusable="true" Caption="View 4" Resizable = "true" Width="300" Height="300"><GraphicObject Focusable="true" Background="Black" MouseEnter="{Background=Gray}" MouseLeave="{Background=Black}"/></Window>
 </Group>-->
-<Docker Background="Jet" Margin = "0" Focusable="true" >
-       <DockWindow Top="100" Left="100" Focusable="true" Caption="View 1" Width="300" Height="300"><GraphicObject Background="Green" Focusable="true" MouseEnter="{Background=Gray}" MouseLeave="{Background=Green}"/></DockWindow>
+<!--<Docker >
+       <DockWindow Resizable = "true" Top="100" Left="100" Caption="View 1" Width="300" Height="300">
+               <VerticalStack Background="DarkGreen" Focusable="true">
+                       <Label Text="{../../Left}" Background="Black" Width="Stretched"/>
+                       <Label Text="{../../Top}" Background="Black"/>
+                       <Label Text="{../../LogicalParent}" Background="Black"/>
+               </VerticalStack>
+       </DockWindow>
        <DockWindow Top="200" Left="200" Focusable="true" Caption="View 2" Resizable = "true" Width="300" Height="300"><GraphicObject Focusable="true" Background="Blue" MouseEnter="{Background=Gray}" MouseLeave="{Background=Blue}"/></DockWindow>
        <DockWindow Top="300" Left="300" Focusable="true" Caption="View 3" Resizable = "true" Width="300" Height="300"><GraphicObject Focusable="true" Background="Yellow" MouseEnter="{Background=Gray}" MouseLeave="{Background=Yellow}"/></DockWindow>
        <DockWindow Top="400" Left="400" Focusable="true" Caption="View 4" Resizable = "true" Width="300" Height="300"><GraphicObject Focusable="true" Background="Black" MouseEnter="{Background=Gray}" MouseLeave="{Background=Black}"/></DockWindow>
-</Docker>
\ No newline at end of file
+</Docker>-->
\ No newline at end of file
diff --git a/Tests/Interfaces/Experimental/testStack.crow b/Tests/Interfaces/Experimental/testStack.crow
new file mode 100644 (file)
index 0000000..054c3f5
--- /dev/null
@@ -0,0 +1,32 @@
+<?xml version="1.0"?>
+<Window Width="600" Height="500">
+<VerticalStack Margin="20" Background="Jet" Spacing="10">
+       <GraphicObject Height="100" Width="500" Background="Green"/>
+       <Splitter/>
+       <HorizontalStack>
+               <GraphicObject Height="Stretched" Width="100" Background="Red"/>
+               <Splitter/>
+               <GraphicObject Height="Stretched" Width="100" Background="DarkRed"/>
+       </HorizontalStack>
+       <Splitter/>
+       <GraphicObject Height="100" Width="500" Background="Green"/>
+</VerticalStack>
+</Window>
+<!--<Group Background="Jet" Margin = "0" Focusable="true" >
+       <Window Top="100" Left="100" Focusable="true" Caption="View 1" Width="300" Height="300"><GraphicObject Background="Green" Focusable="true" MouseEnter="{Background=Gray}" MouseLeave="{Background=Green}"/></Window>
+       <Window Top="200" Left="200" Focusable="true" Caption="View 2" Resizable = "true" Width="300" Height="300"><GraphicObject Focusable="true" Background="Blue" MouseEnter="{Background=Gray}" MouseLeave="{Background=Blue}"/></Window>
+       <Window Top="300" Left="300" Focusable="true" Caption="View 3" Resizable = "true" Width="300" Height="300"><GraphicObject Focusable="true" Background="Yellow" MouseEnter="{Background=Gray}" MouseLeave="{Background=Yellow}"/></Window>
+       <Window Top="400" Left="400" Focusable="true" Caption="View 4" Resizable = "true" Width="300" Height="300"><GraphicObject Focusable="true" Background="Black" MouseEnter="{Background=Gray}" MouseLeave="{Background=Black}"/></Window>
+</Group>-->
+<!--<Docker >
+       <DockWindow Resizable = "true" Top="100" Left="100" Caption="View 1" Width="300" Height="300">
+               <VerticalStack Background="DarkGreen" Focusable="true">
+                       <Label Text="{../../Left}" Background="Black" Width="Stretched"/>
+                       <Label Text="{../../Top}" Background="Black"/>
+                       <Label Text="{../../LogicalParent}" Background="Black"/>
+               </VerticalStack>
+       </DockWindow>
+       <DockWindow Top="200" Left="200" Focusable="true" Caption="View 2" Resizable = "true" Width="300" Height="300"><GraphicObject Focusable="true" Background="Blue" MouseEnter="{Background=Gray}" MouseLeave="{Background=Blue}"/></DockWindow>
+       <DockWindow Top="300" Left="300" Focusable="true" Caption="View 3" Resizable = "true" Width="300" Height="300"><GraphicObject Focusable="true" Background="Yellow" MouseEnter="{Background=Gray}" MouseLeave="{Background=Yellow}"/></DockWindow>
+       <DockWindow Top="400" Left="400" Focusable="true" Caption="View 4" Resizable = "true" Width="300" Height="300"><GraphicObject Focusable="true" Background="Black" MouseEnter="{Background=Gray}" MouseLeave="{Background=Black}"/></DockWindow>
+</Docker>-->
\ No newline at end of file
index 677eec33cdda71d77b29d8b331242cc21e16c02d..30fe50c3e5077b5cb42ac3985e2800f156884cad 100644 (file)
     <None Include="Interfaces\Experimental\testDock.crow">
       <CopyToOutputDirectory>PreserveNewest</CopyToOutputDirectory>
     </None>
+    <None Include="Interfaces\Experimental\testStack.crow">
+      <CopyToOutputDirectory>PreserveNewest</CopyToOutputDirectory>
+    </None>
   </ItemGroup>
   <ItemGroup>
     <Folder Include="Interfaces\" />
index 955a0d69c773b7cafbd7aba12a96b2b471bcf36e..12a020ffa73c9d1f8b24a96a67764768f7f0678e 100644 (file)
@@ -97,6 +97,11 @@ namespace Crow.IML
                
                internal static MethodInfo miCreateExpDel = typeof(ItemTemplate).GetMethod ("CreateExpandDelegate");
                internal static FieldInfo fiFetchMethodName = typeof(ItemTemplate).GetField("fetchMethodName", BindingFlags.Instance | BindingFlags.NonPublic);
+
+               #if DESIGN_MODE
+               internal static MethodInfo miDicStrStrAdd = typeof(Dictionary<string, string>).GetMethod ("set_Item", new Type[] { typeof(string), typeof(string) });
+               #endif
+
                #region tree handling methods
                internal static FieldInfo fiChild = typeof(PrivateContainer).GetField ("child", BindingFlags.Instance | BindingFlags.NonPublic);
                internal static MethodInfo miSetChild = typeof (Container).GetMethod ("SetChild");
index 3a5ec23f4769eea17fd4d7ae46e2b0726a07c0ad..ee0d31daaadba10b89c199de0fa7bd13886535b3 100644 (file)
@@ -165,7 +165,11 @@ namespace Crow
                                NotifyValueChanged ("SelectedColorName", n);
                        else
                                NotifyValueChanged ("SelectedColorName", "-");
-                       NotifyValueChanged ("HexColor", ((int)R).ToString ("X2") + ((int)G).ToString ("X2") + ((int)B).ToString ("X2") + ((int)A).ToString ("X2"));
+                       NotifyValueChanged ("HexColor",
+                               ((int)Math.Round(R)).ToString ("X2") +
+                               ((int)Math.Round(G)).ToString ("X2") +
+                               ((int)Math.Round(B)).ToString ("X2") +
+                               ((int)Math.Round(A)).ToString ("X2"));
                }
                void notifyRGBAHasChanged(){
                        NotifyValueChanged ("R", R);
diff --git a/src/GraphicObjects/DockStack.cs b/src/GraphicObjects/DockStack.cs
new file mode 100644 (file)
index 0000000..29ebe0e
--- /dev/null
@@ -0,0 +1,299 @@
+//
+// DockStack.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 Crow.IML;
+
+namespace Crow
+{
+       public class DockStack : GenericStack
+       {
+               internal static Instantiator instStack, instSplit, instSpacer;
+
+               int dockingDiv = 5;
+
+               GraphicObject subStack = null;
+               public GraphicObject SubStack {
+                       get { return subStack;}
+                       set{ subStack=value; }
+               }
+
+               public DockStack ()     {}
+               public DockStack (Interface iface) : base (iface) {}
+
+               public override bool PointIsIn (ref Point m)
+               {                       
+                       if (!base.PointIsIn(ref m))
+                               return false;
+
+                       Group p = Parent as Group;
+                       if (p != null) {
+                               lock (p.Children) {
+                                       for (int i = p.Children.Count - 1; i >= 0; i--) {
+                                               if (p.Children [i] == this)
+                                                       break;
+                                               if (p.Children [i].IsDragged)
+                                                       continue;
+                                               if (p.Children [i].Slot.ContainsOrIsEqual (m)) {                                                
+                                                       return false;
+                                               }
+                                       }
+                               }
+                       }
+                       return Slot.ContainsOrIsEqual(m);
+               }
+//             protected override void onDragEnter (object sender, DragDropEventArgs e)
+//             {
+//                     base.onDragEnter (sender, e);
+//                     showDock = true;
+//             }
+//             protected override void onDragLeave (object sender, DragDropEventArgs e)
+//             {
+//                     base.onDragLeave (sender, e);
+//                     showDock = false;
+//             }
+               public override void onMouseMove (object sender, MouseMoveEventArgs e)
+               {
+                       if (IsDropTarget) {                             
+                               DockWindow dw = IFace.DragAndDropOperation.DragSource as DockWindow;
+                               if (dw.IsDocked) {
+                                       if (!dw.CheckUndock (e.Position)) {
+                                               base.onMouseMove (sender, e);
+                                               return;
+                                       }                                               
+                               }
+                               Point lm = ScreenPointToLocal (e.Position);
+
+                               Rectangle r = ClientRectangle;
+                               int vTreshold = r.Height / dockingDiv;
+                               int hTreshold = r.Width / dockingDiv;
+
+                               Alignment curDockPos = dw.DockingPosition;
+
+                               if (lm.X < hTreshold)
+                                       dw.DockingPosition = Alignment.Left;
+                               else if (lm.X > r.Right - hTreshold)
+                                       dw.DockingPosition = Alignment.Right;
+                               else if (lm.Y < vTreshold)
+                                       dw.DockingPosition = Alignment.Top;
+                               else if (lm.Y > r.Bottom - vTreshold)
+                                       dw.DockingPosition = Alignment.Bottom;
+                               else
+                                       dw.DockingPosition = Alignment.Center;
+
+                               if (curDockPos != dw.DockingPosition)
+                                       RegisterForGraphicUpdate ();
+                       }
+                       base.onMouseMove (sender, e);
+               }
+               static Orientation GetOrientation (Alignment a){
+                       return (a==Alignment.Left) ||(a==Alignment.Right) ? Orientation.Horizontal : Orientation.Vertical;
+               }
+               protected override void onDraw (Cairo.Context gr)
+               {
+                       gr.Save ();
+
+                       Rectangle rBack = new Rectangle (Slot.Size);
+
+                       Background.SetAsSource (gr, rBack);
+                       CairoHelpers.CairoRectangle (gr, rBack, CornerRadius);
+                       gr.Fill ();
+
+                       if (ClipToClientRect) {
+                               //clip to client zone
+                               CairoHelpers.CairoRectangle (gr, ClientRectangle, CornerRadius);
+                               gr.Clip ();
+                       }
+
+                       childrenRWLock.EnterReadLock ();
+
+                       foreach (GraphicObject g in Children)
+                               g.Paint (ref gr);                       
+
+                       childrenRWLock.ExitReadLock ();
+
+
+                       if (!IsDropTarget) {
+                               gr.Restore ();
+                               return;
+                       }
+
+                       DockWindow dw = IFace.DragAndDropOperation.DragSource as DockWindow;
+                       if (!dw.IsDocked) {
+                               
+                               Rectangle r;
+
+                               if (GetOrientation (dw.DockingPosition) == Orientation || SubStack == null)
+                                       r = ClientRectangle;
+                               else
+                                       r = SubStack.ClientRectangle + SubStack.Slot.Position + ClientRectangle.TopLeft;
+                               
+                               switch (dw.DockingPosition) {
+                               case Alignment.Top:
+                                       gr.Rectangle (r.Left, r.Top, r.Width, r.Height / dockingDiv);
+                                       break;
+                               case Alignment.Bottom:
+                                       gr.Rectangle (r.Left, r.Bottom - r.Height / dockingDiv, r.Width, r.Height / dockingDiv);
+                                       break;
+                               case Alignment.Left:
+                                       gr.Rectangle (r.Left, r.Top, r.Width / dockingDiv, r.Height);
+                                       break;
+                               case Alignment.Right:
+                                       gr.Rectangle (r.Right - r.Width / dockingDiv, r.Top, r.Width / dockingDiv, r.Height);
+                                       break;
+                               }
+                               gr.LineWidth = 1;
+                               gr.SetSourceRGBA (0.4, 0.4, 0.9, 0.4);
+                               gr.FillPreserve ();
+                               gr.SetSourceRGBA (0.9, 0.9, 1.0, 0.8);
+                               gr.Stroke ();
+                       }
+                       gr.Restore ();  
+               }
+               public void Undock (DockWindow dw){
+                       RemoveChild(dw);
+
+                       if (dw.DockingPosition == Alignment.Left || dw.DockingPosition == Alignment.Top)                                
+                               RemoveChild (0);
+                        else
+                               RemoveChild (Children.Count - 1);
+
+                       if (Children.Count > 1)
+                               return;
+                       DockStack dsp = Parent as DockStack;
+                       if (dsp == null) {
+                               SubStack = null;
+                               RemoveChild (0);
+                               return;
+                       }
+                       GraphicObject g = Children [0];
+                       RemoveChild (g);
+                       int i = dsp.Children.IndexOf (this);
+                       dsp.RemoveChild (this);
+                       dsp.AddChild (g);
+                       dsp.SubStack = g;
+//                     if (SubStack is DockStack) {
+//
+//                     } else {
+//                             int i = p.Children.IndexOf (this);
+//                             p.RemoveChild (this);
+//                             if (p is DockStack) {
+//                                     DockStack dsp = p as DockStack;
+//                                     dsp.SubStack = instSpacer.CreateInstance ();
+//                                     dsp.AddChild (dsp.SubStack);
+//                             }
+//                     }
+
+               }
+               public void Dock(DockWindow dw){
+                       checkInstantiators();
+
+                       Splitter splitter = instSplit.CreateInstance<Splitter> ();
+                       Rectangle r = ClientRectangle;
+
+                       int vTreshold = r.Height / dockingDiv;
+                       int hTreshold = r.Width / dockingDiv;
+
+                       DockStack activeStack = this;
+
+                       if (SubStack == null) {
+                               activeStack = this;
+                               SubStack = instSpacer.CreateInstance ();
+                       }else if (GetOrientation (dw.DockingPosition) != Orientation) {
+                               int i = Children.IndexOf (SubStack);
+                               RemoveChild (SubStack);
+                               activeStack = instStack.CreateInstance<DockStack> ();
+                               activeStack.SubStack = instSpacer.CreateInstance ();
+                               SubStack = activeStack;
+                               InsertChild(i, activeStack);                             
+                       }
+
+                       switch (dw.DockingPosition) {
+                       case Alignment.Top:                                             
+                               dw.Height = vTreshold;
+                               dw.Width = Measure.Stretched;
+                               if (activeStack.Children.Count == 0) {
+                                       activeStack.Orientation = Orientation.Vertical;
+                                       activeStack.AddChild (dw);
+                                       activeStack.AddChild (splitter);
+                                       activeStack.AddChild (activeStack.SubStack);
+                               } else {
+                                       activeStack.InsertChild (0, dw);
+                                       activeStack.InsertChild (0, splitter);
+                               }
+                               break;
+                       case Alignment.Bottom:
+                               dw.Height = vTreshold;
+                               dw.Width = Measure.Stretched;
+                               if (activeStack.Children.Count == 0) {
+                                       activeStack.Orientation = Orientation.Vertical;
+                                       activeStack.AddChild (activeStack.SubStack);
+                                       activeStack.AddChild (splitter);
+                                       activeStack.AddChild (dw);
+                               } else {
+                                       activeStack.AddChild (splitter);
+                                       activeStack.AddChild (dw);
+                               }
+                               break;
+                       case Alignment.Left:
+                               dw.Width = hTreshold;
+                               dw.Height = Measure.Stretched;
+                               if (activeStack.Children.Count == 0) {
+                                       activeStack.Orientation = Orientation.Horizontal;
+                                       activeStack.AddChild (dw);
+                                       activeStack.AddChild (splitter);
+                                       activeStack.AddChild (activeStack.SubStack);
+                               } else {
+                                       activeStack.InsertChild (0, dw);
+                                       activeStack.InsertChild (0, splitter);
+                               }
+                               break;
+                       case Alignment.Right:
+                               dw.Width = hTreshold;
+                               dw.Height = Measure.Stretched;
+                               if (activeStack.Children.Count == 0) {
+                                       activeStack.Orientation = Orientation.Horizontal;
+                                       activeStack.AddChild (activeStack.SubStack);
+                                       activeStack.AddChild (splitter);
+                                       activeStack.AddChild (dw);
+                               } else {
+                                       activeStack.AddChild (splitter);
+                                       activeStack.AddChild (dw);
+                               }
+                               break;
+                       }
+               }
+
+               void checkInstantiators () {
+                       if (instStack != null)
+                               return;
+                       instStack = IFace.CreateITorFromIMLFragment (@"<DockStack/>");
+                       instSplit = IFace.CreateITorFromIMLFragment (@"<Splitter/>");
+                       instSpacer = IFace.CreateITorFromIMLFragment (@"<GraphicObject Background='Jet' IsEnabled='false'/>");
+               }
+
+       }
+}
+
index b68a308566469affefdea19cf07e5704bb320f89..4c71c92d3c901ed6462793fbd0de3d58ccba4fec 100644 (file)
@@ -35,6 +35,7 @@ namespace Crow
                }
                #endregion
 
+               int undockThreshold = 10;
                bool isDocked = false;
                Alignment docking = Alignment.Center;
 
@@ -43,6 +44,8 @@ namespace Crow
                Rectangle savedSlot;    //last undocked slot recalled when view is undocked
                bool wasResizable;
 
+               public Docker RootDock { get { return LogicalParent as Docker; }}
+
                public bool IsDocked {
                        get { return isDocked; }
                        set {
@@ -61,12 +64,7 @@ namespace Crow
                                NotifyValueChanged ("DockingPosition", DockingPosition);
                        }
                }
-               protected override void onDrop (object sender, DragDropEventArgs e)
-               {
-                       base.onDrop (sender, e);
-                       Docker dv = Parent as Docker;
-                       dv.Dock (this);
-               }
+
                public override bool PointIsIn (ref Point m)
                {                       
                        if (!base.PointIsIn(ref m))
@@ -78,6 +76,8 @@ namespace Crow
                                        for (int i = p.Children.Count - 1; i >= 0; i--) {
                                                if (p.Children [i] == this)
                                                        break;
+                                               if (p.Children [i].IsDragged)
+                                                       continue;
                                                if (p.Children [i].Slot.ContainsOrIsEqual (m)) {                                                
                                                        return false;
                                                }
@@ -113,130 +113,75 @@ namespace Crow
 //                     }
 //             }
 //
-//             public override void onMouseMove (object sender, MouseMoveEventArgs e)
-//             {
-//                     lastMousePos = e.Position;
-//
-//                     if (this.HasFocus && e.Mouse.IsButtonDown (MouseButton.Left) && IsDocked) {
-//                             Docker dv = Parent as Docker;
-//                             if (docking == Alignment.Left) {
-//                                     if (lastMousePos.X - undockingMousePosOrig.X > dv.DockingThreshold)
-//                                             undock ();
-//                             } else if (docking == Alignment.Right) {
-//                                     if (undockingMousePosOrig.X - lastMousePos.X > dv.DockingThreshold)
-//                                             undock ();
-//                             } else if (docking == Alignment.Top) {
-//                                     if (lastMousePos.Y - undockingMousePosOrig.Y > dv.DockingThreshold)
-//                                             undock ();
-//                             } else if (docking == Alignment.Bottom) {
-//                                     if (undockingMousePosOrig.Y - lastMousePos.Y > dv.DockingThreshold)
-//                                             undock ();
-//                             }
-//                             return;
-//                     }
-//
-//                     base.onMouseMove (sender, e);
-//             }
-//             public override void onMouseDown (object sender, MouseButtonEventArgs e)
-//             {
-//                     base.onMouseDown (sender, e);
-//
-//                     if (this.HasFocus && IsDocked && e.Button == MouseButton.Left)
-//                             undockingMousePosOrig = lastMousePos;
-//             }
+               public override void onMouseMove (object sender, MouseMoveEventArgs e)
+               {
+                       lastMousePos = e.Position;
 
-//             protected override void onBorderMouseEnter (object sender, MouseMoveEventArgs e)
-//             {
-//                     base.onBorderMouseEnter (sender, e);
-//
-//                     if (isDocked) {
-//                             switch (docking) {
-//                             case Alignment.Top:
-//                                     if (this.currentDirection != Window.Direction.S)
-//                                             onBorderMouseLeave (this, null);
-//                                     break;
-//                             case Alignment.Left:
-//                                     if (this.currentDirection != Window.Direction.E)
-//                                             onBorderMouseLeave (this, null);
-//                                     break;
-//                             case Alignment.TopLeft:
-//                                     break;
-//                             case Alignment.Right:
-//                                     if (this.currentDirection != Window.Direction.W)
-//                                             onBorderMouseLeave (this, null);
-//                                     break;
-//                             case Alignment.TopRight:
-//                                     break;
-//                             case Alignment.Bottom:
-//                                     if (this.currentDirection != Window.Direction.N)
-//                                             onBorderMouseLeave (this, null);                                        
-//                                     break;
-//                             case Alignment.BottomLeft:
-//                                     break;
-//                             case Alignment.BottomRight:
-//                                     break;
-//                             case Alignment.Center:
-//                                     break;
-//                             default:
-//                                     break;
-//                             }
-//                     }
-//             }
+                       if (this.HasFocus && e.Mouse.IsButtonDown (MouseButton.Left) && IsDocked) {
+                               if (Math.Abs (e.Position.X - undockingMousePosOrig.X) > 10 ||
+                                   Math.Abs (e.Position.X - undockingMousePosOrig.X) > 10)
+                                       Undock ();
+                       }
 
-               void undock () {
-                       this.Left = savedSlot.Left;
-                       this.Top = savedSlot.Top;
-                       this.Width = savedSlot.Width;
-                       this.Height = savedSlot.Height;
+                       base.onMouseMove (sender, e);
+               }
+               public override void onMouseDown (object sender, MouseButtonEventArgs e)
+               {
+                       base.onMouseDown (sender, e);
+
+                       if (this.HasFocus && IsDocked && e.Button == MouseButton.Left)
+                               undockingMousePosOrig = e.Position;
+               }
+               public bool CheckUndock (Point mousePos) {
+                       if (Math.Abs (mousePos.X - undockingMousePosOrig.X) < undockThreshold ||
+                           Math.Abs (mousePos.X - undockingMousePosOrig.X) < undockThreshold)
+                               return false;
+                       Undock ();
+                       return true;
+               }
+
+               protected override void onStartDrag (object sender, DragDropEventArgs e)
+               {
+                       base.onStartDrag (sender, e);
+
+                       undockingMousePosOrig = IFace.Mouse.Position;
+               }
+               protected override void onDrop (object sender, DragDropEventArgs e)
+               {
+                       if (!isDocked && DockingPosition != Alignment.Center)
+                               dock (e.DropTarget as DockStack);
+                       base.onDrop (sender, e);
+               }
+               public void Undock () {
+                       lock (IFace.UpdateMutex) {
+                               DockStack ds = Parent as DockStack;
+                               ds.Undock (this);
+
+                               RootDock.AddChild (this);
 
-                       IsDocked = false;
-                       Resizable = wasResizable;
+                               this.Left = savedSlot.Left;
+                               this.Top = savedSlot.Top;
+                               this.Width = savedSlot.Width;
+                               this.Height = savedSlot.Height;
+
+                               IsDocked = false;
+                               Resizable = wasResizable;
+                       }
                }
-               void dock (Alignment align){
-                       IsDocked = true;
-                       docking = align;
-                       undockingMousePosOrig = lastMousePos;
-                       savedSlot = this.LastPaintedSlot;
-                       wasResizable = Resizable;
-                       Resizable = false;
-
-                       this.Left = this.Top = 0;
-
-                       switch (align) {
-                       case Alignment.Top:
-                               this.HorizontalAlignment = HorizontalAlignment.Left;
-                               this.VerticalAlignment = VerticalAlignment.Top;
-                               this.Width = Measure.Stretched;
-                               break;
-                       case Alignment.Left:
-                               this.HorizontalAlignment = HorizontalAlignment.Left;
-                               this.VerticalAlignment = VerticalAlignment.Top;
-                               this.Height = Measure.Stretched;
-                               break;
-                       case Alignment.TopLeft:
-                               break;
-                       case Alignment.Right:
-                               this.HorizontalAlignment = HorizontalAlignment.Right;
-                               this.VerticalAlignment = VerticalAlignment.Top;
-                               this.Height = Measure.Stretched;
-                               break;
-                       case Alignment.TopRight:
-                               break;
-                       case Alignment.Bottom:
-                               this.HorizontalAlignment = HorizontalAlignment.Left;
-                               this.VerticalAlignment = VerticalAlignment.Bottom;
-                               this.Width = Measure.Stretched;
-                               break;
-                       case Alignment.BottomLeft:
-                               break;
-                       case Alignment.BottomRight:
-                               break;
-                       case Alignment.Center:
-                               break;
-                       default:
-                               break;
+               void dock (DockStack target){                   
+                       lock (IFace.UpdateMutex) {
+                               IsDocked = true;
+                               undockingMousePosOrig = lastMousePos;
+                               savedSlot = this.LastPaintedSlot;
+                               wasResizable = Resizable;
+                               Resizable = false;
+                               LastSlots = LastPaintedSlot = Slot = default(Rectangle);
+                               Left = Top = 0;
+
+                               RootDock.RemoveChild (this);
+
+                               target.Dock (this);
                        }
-                       
                }
        }
 }
index bb816dd9e4c850cf160852e3986329d3fb7a7d43..dfd386aac328dcc3ab98b5f6b41de001585181af 100644 (file)
@@ -27,45 +27,32 @@ using System;
 using System.Xml.Serialization;
 using System.ComponentModel;
 using Crow.IML;
+using System.Collections.Generic;
+using System.Diagnostics;
 
 namespace Crow
 {
        public class Docker : Group
-       {
-               static Instantiator instStack, instSplit, instSpacer;
+       {               
                #region CTOR
                static Docker () {
                }
                public Docker () : base ()
                {
-                       instStack = IFace.CreateITorFromIMLFragment (@"<GenericStack Background='Blue' AllowDrop='true' DragEnter='onStackDragEnter'/>");
-                       instSplit = IFace.CreateITorFromIMLFragment (@"<Splitter/>");
-                       instSpacer = IFace.CreateITorFromIMLFragment (@"<GraphicObject Background='Red' IsEnabled='false'/>");
                }
                #endregion
 
-               GenericStack rootStack = null;
+               //GenericStack rootStack = null;
+               DockStack stack = null;
+               int dockingThreshold;
+
+               List<DockWindow> windows = new List<DockWindow>();
 
                public override void AddChild (GraphicObject g)
-               {
-                       DockWindow dw = g as DockWindow;
-                       if (dw == null)
-                               throw new Exception ("Docker accept only DockWindow as child");
-                       
+               {                               
                        base.AddChild (g);
-
-                       dw.LogicalParent = this;
+                       g.LogicalParent = this;
                }
-               public override void RemoveChild (GraphicObject child)
-               {
-                       child.LogicalParent = null;
-
-
-                       base.RemoveChild (child);
-               }
-
-               GenericStack mainStack = null;
-               int dockingThreshold;
 
                [XmlAttributeAttribute][DefaultValue(10)]
                public virtual int DockingThreshold {
@@ -79,57 +66,39 @@ namespace Crow
                        }
                }
 
-               bool showDockingTarget = false;
-               Alignment dockingDirection = Alignment.Center;
-               int dockingDiv = 5;
+               //bool showDockingTarget = false;
+               //Alignment dockingDirection = Alignment.Center;
+               //int dockingDiv = 8;
+               //bool showDock = false;
 
                public override void onMouseMove (object sender, MouseMoveEventArgs e)
                {                       
                        if (IFace.DragAndDropOperation?.DragSource as DockWindow != null) {
-                               DockWindow dw = IFace.DragAndDropOperation?.DragSource as DockWindow;
-                               if (IFace.DragAndDropOperation.DragSource.Parent == this && !dw.IsDocked)
+                               DockWindow dw = IFace.DragAndDropOperation.DragSource as DockWindow;
+                               if (!dw.IsDocked)
                                        dw.MoveAndResize (e.XDelta, e.YDelta);
-
-                               Rectangle r = ClientRectangle;
-                               int vTreshold = r.Height / dockingDiv;
-                               int hTreshold = r.Width / dockingDiv;
-
-
-                               bool showDock = true;
-
-                               if (dw.Slot.Left < hTreshold)
-                                       dockingDirection = Alignment.Left;
-                               else if (dw.Slot.Right > r.Right - hTreshold)
-                                       dockingDirection = Alignment.Right;
-                               else if (dw.Slot.Top < vTreshold)
-                                       dockingDirection = Alignment.Top;
-                               else if (dw.Slot.Bottom > r.Bottom - vTreshold)
-                                       dockingDirection = Alignment.Bottom;
-                               else {
-                                       dockingDirection = Alignment.Center;
-                                       showDock = false;
+                               if (stack == null) {                            
+                                       stack = new DockStack (IFace);
+                                       InsertChild (0, stack);
+                                       stack.LogicalParent = this;
                                }
-
-                               showDockingTarget = showDock;
-
-                               RegisterForGraphicUpdate ();
-
-                               //System.Diagnostics.Debug.WriteLine ("Dock: {0}", dockingDirection);
-                       } else
-                               showDockingTarget = false;
-
+                       }
                        base.onMouseMove (sender, e);
                }
+               /*
                protected override void onDragEnter (object sender, DragDropEventArgs e)
                {
                        base.onDragEnter (sender, e);
+                       showDock = true;
+                       Console.WriteLine ("showdock=" + showDock);
                }
-               void onStackDragEnter (object sender, DragDropEventArgs e)
+               protected override void onDragLeave (object sender, DragDropEventArgs e)
                {
-                       base.onDragEnter (sender, e);
-
-                       mainStack = sender as GenericStack;
+                       base.onDragLeave (sender, e);
+                       showDock = false;
+                       Console.WriteLine ("showdock=" + showDock);
                }
+
                protected override void onDraw (Cairo.Context gr)
                {
                        gr.Save ();
@@ -149,8 +118,8 @@ namespace Crow
                        childrenRWLock.EnterReadLock ();
 
                        foreach (GraphicObject g in Children) {
-                               if (IFace.DragAndDropOperation?.DragSource == g)
-                                       continue;
+//                             if (IFace.DragAndDropOperation?.DragSource == g)
+//                                     continue;
                                g.Paint (ref gr);
                        }
 
@@ -158,10 +127,10 @@ namespace Crow
 
                        if (showDockingTarget) {
                                Rectangle r;
-                               if (mainStack == null)
+                               if (stack == null)
                                        r = ClientRectangle;
                                else
-                                       r = mainStack.ClientRectangle;
+                                       r = stack.ClientRectangle;
                                
                                switch (dockingDirection) {
                                case Alignment.Top:
@@ -184,73 +153,83 @@ namespace Crow
                                gr.Stroke ();
                        }
 
-                       if (IFace.DragAndDropOperation != null)
-                               IFace.DragAndDropOperation.DragSource.Paint (ref gr);
-
-
                        gr.Restore ();  
                }
+*/
 
+               /*
                public void Dock(DockWindow dw){
+                       checkInstantiators();
+
                        if (dockingDirection == Alignment.Center)
                                return;
+                       
                        lock (IFace.UpdateMutex) {
 
                                Splitter splitter = instSplit.CreateInstance<Splitter> ();
+                               Rectangle r = ClientRectangle;
 
-                               dw.Resizable = false;
-                               dw.Left = dw.Top = 0;
-                               this.RemoveChild (dw);
-
-                               Rectangle r;
-                               if (mainStack == null) {
-                                       mainStack = instStack.CreateInstance<GenericStack> ();
-                                       this.AddChild (mainStack);
-                                       this.putWidgetOnBottom (mainStack);
-                                       r = ClientRectangle;
-                               } else
-                                       r = mainStack.ClientRectangle;                          
+                               if (stack == null) {
+                                       stack = instStack.CreateInstance<GenericStack> ();
+                                       this.AddChild (stack);
+                                       this.putWidgetOnBottom (stack);
+                               } 
                                 
                                int vTreshold = r.Height / dockingDiv;
                                int hTreshold = r.Width / dockingDiv;
 
                                switch (dockingDirection) {
                                case Alignment.Top:                                             
-                                       dw.Width = Measure.Stretched;
-                                       mainStack.Orientation = Orientation.Vertical;
-                                       mainStack.AddChild (dw);
-                                       mainStack.AddChild (splitter);
-                                       //mainStack.AddChild (instSpacer.CreateInstance (CurrentInterface));
+                                       dw.Height = vTreshold;
+                                       stack.Orientation = Orientation.Vertical;
+                                       if (stack.Children.Count == 0) {
+                                               stack.AddChild (dw);
+                                               stack.AddChild (splitter);
+                                               stack.AddChild (instSpacer.CreateInstance ());
+                                       } else {
+                                               stack.AddChild (splitter);
+                                               stack.AddChild (dw);
+                                       }
                                        break;
                                case Alignment.Bottom:
-                                       dw.Width = Measure.Stretched;
-                                       mainStack.Orientation = Orientation.Vertical;
-                                       //mainStack.AddChild (instSpacer.CreateInstance (CurrentInterface));
-                                       mainStack.AddChild (splitter);
-                                       mainStack.AddChild (dw);
+                                       dw.Height = vTreshold;
+                                       stack.Orientation = Orientation.Vertical;
+                                       if (stack.Children.Count == 0) {
+                                               stack.AddChild (instSpacer.CreateInstance ());
+                                               stack.AddChild (splitter);
+                                               stack.AddChild (dw);
+                                       } else {
+                                               stack.InsertChild (0, dw);
+                                               stack.InsertChild (0, splitter);
+                                       }
                                        break;
                                case Alignment.Left:
-                                       dw.Height = Measure.Stretched;
-                                       mainStack.Orientation = Orientation.Horizontal;
-                                       mainStack.AddChild (dw);
-                                       mainStack.AddChild (splitter);
-                                       //mainStack.AddChild (instSpacer.CreateInstance (CurrentInterface));
+                                       dw.Width = hTreshold;
+                                       stack.Orientation = Orientation.Horizontal;
+                                       if (stack.Children.Count == 0) {
+                                               stack.AddChild (dw);
+                                               stack.AddChild (splitter);
+                                               stack.AddChild (instSpacer.CreateInstance ());
+                                       } else {
+                                               stack.AddChild (splitter);
+                                               stack.AddChild (dw);
+                                       }
                                        break;
                                case Alignment.Right:
-                                       dw.Height = Measure.Stretched;
-                                       mainStack.Orientation = Orientation.Horizontal;
-                                       //mainStack.AddChild (instSpacer.CreateInstance (CurrentInterface));
-                                       mainStack.AddChild (splitter);
-                                       mainStack.AddChild (dw);
+                                       dw.Width = hTreshold;
+                                       stack.Orientation = Orientation.Horizontal;
+                                       if (stack.Children.Count == 0) {
+                                               stack.AddChild (instSpacer.CreateInstance ());
+                                               stack.AddChild (splitter);
+                                               stack.AddChild (dw);
+                                       } else {
+                                               stack.InsertChild (0, dw);
+                                               stack.InsertChild (0, splitter);
+                                       }
                                        break;
                                }
-
                        }
-               }
-               protected override void onDrop (object sender, DragDropEventArgs e)
-               {
-                       base.onDrop (sender, e);
-               }
+               }*/
        }
 }
 
index aff804f8e16b9e54f1b1782e9fd4942a34c4de11..83d919566a4069b9a41f25b06a4717a90b4e36ac 100644 (file)
@@ -77,7 +77,7 @@ namespace Crow
                                NotifyValueChanged ("Image", image);
                        }
                }
-               [XmlAttributeAttribute][DefaultValue(false)]
+               [DefaultValue(false)]
         public bool IsExpanded
         {
                        get { return _isExpanded; }
index 3d6884e157c36fb1f3a3a3196c5e5783dbf769a4..2df681e480e53cc67ebe936b11f602611efbeb82 100644 (file)
@@ -136,6 +136,46 @@ namespace Crow
                        return base.UpdateLayout(layoutType);
         }
 
+               void adjustStretchedGo (LayoutingType lt){
+                       if (stretchedGO == null)
+                               return;
+                       if (lt == LayoutingType.Width) {
+                               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;
+                               }
+                       } else {
+                               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;
+                               }                               
+                       }
+               }
+
                public override void OnChildLayoutChanges (object sender, LayoutingEventArgs arg)
                {
                        GraphicObject go = sender as GraphicObject;
@@ -154,24 +194,7 @@ namespace Crow
                                        } 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;
-                                               }
-                                       }
+                                       adjustStretchedGo (LayoutingType.Width);                                        
                                        
                                        if (Width == Measure.Fit)
                                                this.RegisterForLayouting (LayoutingType.Width);
@@ -193,24 +216,7 @@ namespace Crow
                                        } 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;
-                                               }
-                                       }
+                                       adjustStretchedGo (LayoutingType.Height);
 
                                        if (Height == Measure.Fit)
                                                this.RegisterForLayouting (LayoutingType.Height);
@@ -224,6 +230,23 @@ namespace Crow
                }
                #endregion
 
-    
+       public override void RemoveChild (GraphicObject child)
+               {
+                       base.RemoveChild (child);
+                       if (child == stretchedGO) {
+                               stretchedGO = null;
+                               return;
+                       }
+                       if (Orientation == Orientation.Horizontal) {
+                               contentSize.Width -= child.LastSlots.Width;
+                               adjustStretchedGo (LayoutingType.Width);
+                       } else {
+                               contentSize.Height -= child.LastSlots.Height;
+                               adjustStretchedGo (LayoutingType.Height);
+                       }
+
+
+//                     RegisterForLayouting (LayoutingType.ArrangeChildren);
+               }
        }
 }
index adb29e54fb5f71ec618f72eac090e62a29e1102e..db49832e80206cbd8aa4f328604a30a76e3bde5d 100644 (file)
@@ -52,24 +52,37 @@ namespace Crow
                internal ReaderWriterLockSlim parentRWLock = new ReaderWriterLockSlim();
 
                #if DESIGN_MODE
-               static MethodInfo miDesignAddDefLoc = typeof(GraphicObject).GetMethod("design_add_default_location",
+               static MethodInfo miDesignAddDefLoc = typeof(GraphicObject).GetMethod("design_add_style_location",
                        BindingFlags.Instance | BindingFlags.NonPublic);
-               public volatile bool HasChanged = false;
+               static MethodInfo miDesignAddValLoc = typeof(GraphicObject).GetMethod("design_add_iml_location",
+                       BindingFlags.Instance | BindingFlags.NonPublic);
+               
+               public volatile bool design_HasChanged = false;
                public string design_id;
                public int design_line;
                public int design_column;
                public string design_imlPath;
-               public Dictionary<string,string> design_members = new Dictionary<string, string>();
-               public Dictionary<string,FileLocation> design_defaults = new Dictionary<string, FileLocation>();
-               internal void design_add_default_location (string memberName, string path, int line, int col) {
-                       if (design_defaults.ContainsKey(memberName)){
+               public bool design_isTGItem = false;//true if this is a templated item's root
+               public Dictionary<string,string> design_iml_values = new Dictionary<string, string>();
+               public Dictionary<string,string> design_style_values = new Dictionary<string, string>();
+               //public Dictionary<string,FileLocation> design_iml_locations = new Dictionary<string, FileLocation>();
+               public Dictionary<string,FileLocation> design_style_locations = new Dictionary<string, FileLocation>();
+
+               internal void design_add_style_location (string memberName, string path, int line, int col) {
+                       if (design_style_locations.ContainsKey(memberName)){
                                Console.WriteLine ("default value localtion already set for {0}{1}.{2}", this.GetType().Name, this.design_id, memberName);
                                return;
                        }
-                       design_defaults.Add(memberName, new FileLocation(path,line,col));
+                       design_style_locations.Add(memberName, new FileLocation(path,line,col));
                }
-               public bool design_isTGItem = false;
-
+//             internal void design_add_iml_location (string memberName, string path, int line, int col) {
+//                     if (design_iml_locations.ContainsKey(memberName)){
+//                             Console.WriteLine ("IML value localtion already set for {0}{1}.{2}", this.GetType().Name, this.design_id, memberName);
+//                             return;
+//                     }
+//                     design_iml_locations.Add(memberName, new FileLocation(path,line,col));
+//             }
+                       
                public virtual bool FindByDesignID(string designID, out GraphicObject go){
                        go = null;
                        if (this.design_id == designID){
@@ -94,7 +107,7 @@ namespace Crow
                                        getIML (doc, (XmlNode)doc);
                                        doc.WriteTo (xtw);
                                }
-                               this.HasChanged = false;
+                               this.design_HasChanged = false;
                                return sw.ToString ();
                        }
                }
@@ -105,7 +118,7 @@ namespace Crow
                        
                        XmlElement xe = doc.CreateElement(this.GetType().Name);
 
-                       foreach (KeyValuePair<string,string> kv in design_members) {
+                       foreach (KeyValuePair<string,string> kv in design_iml_values) {
                                XmlAttribute xa = doc.CreateAttribute (kv.Key);
                                xa.Value = kv.Value;
                                xe.Attributes.Append (xa);
@@ -257,6 +270,7 @@ namespace Crow
                bool focusable = false;
                bool hasFocus = false;
                bool isActive = false;
+               bool isHover = false;
                bool mouseRepeat;
                protected bool isVisible = true;
                bool isEnabled = true;
@@ -307,6 +321,9 @@ namespace Crow
                internal Size contentSize;
                #endregion
 
+               public void ResetSlots () {
+                       LastSlots = LastPaintedSlot = Slot = default(Rectangle);
+               }
                #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
@@ -364,6 +381,14 @@ namespace Crow
                }
                public virtual Rectangle getSlot () { return Slot;}
                #endregion
+               public Point ScreenPointToLocal(Point p){
+                       Point pt = p - ScreenCoordinates(Slot).TopLeft - ClientRectangle.TopLeft;
+                       if (pt.X < 0)
+                               pt.X = 0;
+                       if (pt.Y < 0)
+                               pt.Y = 0;
+                       return pt;
+               }
 
                #region EVENT HANDLERS
                /// <summary>Occurs when mouse wheel is rolled in this object. It bubbles to the root</summary>
@@ -392,7 +417,11 @@ namespace Crow
                public event EventHandler Focused;
                /// <summary>Occurs when this object loose focus</summary>
                public event EventHandler Unfocused;
-               /// <summary>Occurs when the enabled state this object is set to true</summary>
+               /// <summary>Occurs when mouse is over</summary>
+               public event EventHandler Hover;
+               /// <summary>Occurs when this control is no longer the Hover one</summary>
+               public event EventHandler UnHover;
+               /// <summary>Occurs when this object loose focus</summary>
                public event EventHandler Enabled;
                /// <summary>Occurs when the enabled state this object is set to false</summary>
                public event EventHandler Disabled;
@@ -413,7 +442,7 @@ namespace Crow
 
                #region public properties
                /// <summary>Random value placeholder</summary>
-               [XmlAttributeAttribute]
+               [DesignCategory ("Divers")]
                public object Tag {
                        get { return tag; }
                        set {
@@ -427,7 +456,7 @@ namespace Crow
                /// If enabled, resulting bitmap of graphic object is cached
                /// speeding up rendering of complex object. Default is enabled.
                /// </summary>
-               [XmlAttributeAttribute][DefaultValue(true)]
+               [DesignCategory ("Behavior")][DefaultValue(true)]
                public virtual bool CacheEnabled {
                        get { return cacheEnabled; }
                        set {
@@ -440,7 +469,7 @@ namespace Crow
                /// <summary>
                /// If true, rendering of GraphicObject is clipped inside client rectangle
                /// </summary>
-               [XmlAttributeAttribute][DefaultValue(true)]
+               [DesignCategory ("Appearance")][DefaultValue(true)]
                public virtual bool ClipToClientRect {
                        get { return clipToClientRect; }
                        set {
@@ -461,7 +490,7 @@ namespace Crow
                /// and by template controls to find special element in their template implementation such
                /// as a container or a group to put children in.
                /// </summary>
-               [XmlAttributeAttribute][DefaultValue(null)]
+               [DesignCategory ("Divers")][DefaultValue(null)]
                public virtual string Name {
                        get {
                                #if DEBUG
@@ -481,7 +510,7 @@ namespace Crow
                /// Vertical alignment inside parent, disabled if height is stretched
                /// or top coordinate is not null
                /// </summary>
-               [XmlAttributeAttribute  ()][DefaultValue(VerticalAlignment.Center)]
+               [DesignCategory ("Layout")][DefaultValue(VerticalAlignment.Center)]
                public virtual VerticalAlignment VerticalAlignment {
                        get { return verticalAlignment; }
                        set {
@@ -497,7 +526,7 @@ namespace Crow
                /// Horizontal alignment inside parent, disabled if width is stretched
                /// or left coordinate is not null
                /// </summary>
-               [XmlAttributeAttribute()][DefaultValue(HorizontalAlignment.Center)]
+               [DesignCategory ("Layout")][DefaultValue(HorizontalAlignment.Center)]
                public virtual HorizontalAlignment HorizontalAlignment {
                        get { return horizontalAlignment; }
                        set {
@@ -511,7 +540,7 @@ namespace Crow
                /// <summary>
                /// x position inside parent
                /// </summary>
-               [XmlAttributeAttribute()][DefaultValue(0)]
+               [DesignCategory ("Layout")][DefaultValue(0)]
                public virtual int Left {
                        get { return left; }
                        set {
@@ -525,7 +554,7 @@ namespace Crow
                /// <summary>
                /// y position inside parent
                /// </summary>
-               [XmlAttributeAttribute()][DefaultValue(0)]
+               [DesignCategory ("Layout")][DefaultValue(0)]
                public virtual int Top {
                        get { return top; }
                        set {
@@ -539,7 +568,7 @@ namespace Crow
                /// <summary>
                /// Helper property used to set width and height to fit in one call
                /// </summary>
-               [XmlAttributeAttribute()][DefaultValue(false)]
+               [DesignCategory ("Layout")][DefaultValue(false)]
                public virtual bool Fit {
                        get { return Width == Measure.Fit && Height == Measure.Fit ? true : false; }
                        set {
@@ -553,7 +582,7 @@ namespace Crow
                /// Width of this control, by default inherited from parent. May have special values
                /// such as Stretched or Fit. It may be proportionnal or absolute.
                /// </summary>
-               [XmlAttributeAttribute()][DefaultValue("Inherit")]
+               [DesignCategory ("Layout")][DefaultValue("Inherit")]
                public virtual Measure Width {
                        get {
                                return width.Units == Unit.Inherit ?
@@ -593,7 +622,7 @@ namespace Crow
                /// Height of this control, by default inherited from parent. May have special values
                /// such as Stretched or Fit. It may be proportionnal or absolute.
                /// </summary>
-               [XmlAttributeAttribute()][DefaultValue("Inherit")]
+               [DesignCategory ("Layout")][DefaultValue("Inherit")]
                public virtual Measure Height {
                        get {
                                return height.Units == Unit.Inherit ?
@@ -641,7 +670,7 @@ namespace Crow
                /// Indicate that this object may received focus or not, if not focusable all the descendants are 
                /// affected.
                /// </summary>
-               [XmlAttributeAttribute()][DefaultValue(false)]
+               [DesignCategory ("Behaviour")][DefaultValue(false)]
                public virtual bool Focusable {
                        get { return focusable; }
                        set {
@@ -683,9 +712,28 @@ namespace Crow
                        }
                }
                /// <summary>
+               /// true if this control has the pointer hover
+               /// </summary>
+               [XmlIgnore]public virtual bool IsHover {
+                       get { return isHover; }
+                       set {
+                               if (value == isHover)
+                                       return;
+
+                               isHover = value;
+
+                               if (isHover)
+                                       onHover (this, null);
+                               else
+                                       onUnHover (this, null);
+
+                               NotifyValueChanged ("IsHover", isHover);
+                       }
+               }
+               /// <summary>
                /// true if holding mouse button down should trigger multiple click events
                /// </summary>
-               [XmlAttributeAttribute()][DefaultValue(false)]
+               [DesignCategory ("Behaviour")][DefaultValue(false)]
                public virtual bool MouseRepeat {
                        get { return mouseRepeat; }
                        set {
@@ -699,7 +747,7 @@ namespace Crow
                /// <summary>
                /// background fill of the control, maybe solid color, gradient, image, or svg
                /// </summary>
-               [XmlAttributeAttribute()][DefaultValue("Transparent")]
+               [DesignCategory ("Appearance")][DefaultValue("Transparent")]
                public virtual Fill Background {
                        get { return background; }
                        set {
@@ -720,7 +768,7 @@ namespace Crow
                /// <summary>
                /// Foreground fill of the control, usage may be different among derived controls
                /// </summary>
-               [XmlAttributeAttribute()][DefaultValue("White")]
+               [DesignCategory ("Appearance")][DefaultValue("White")]
                public virtual Fill Foreground {
                        get { return foreground; }
                        set {
@@ -734,7 +782,7 @@ namespace Crow
                /// <summary>
                /// Font being used in many controls, it is defined in the base GraphicObject class.
                /// </summary>
-               [XmlAttributeAttribute()][DefaultValue("sans,10")]
+               [DesignCategory ("Appearance")][DefaultValue("sans,10")]
                public virtual Font Font {
                        get { return font; }
                        set {
@@ -748,7 +796,7 @@ namespace Crow
                /// <summary>
                /// to get rounded corners
                /// </summary>
-               [XmlAttributeAttribute()][DefaultValue(0.0)]
+               [DesignCategory ("Appearance")][DefaultValue(0.0)]
                public virtual double CornerRadius {
                        get { return cornerRadius; }
                        set {
@@ -763,7 +811,7 @@ namespace Crow
                /// This is a single integer for the 4 direction, a gap between the control and it's container,
                /// by default it is filled with the background.
                /// </summary>
-               [XmlAttributeAttribute()][DefaultValue(0)]
+               [DesignCategory ("Layout")][DefaultValue(0)]
                public virtual int Margin {
                        get { return margin; }
                        set {
@@ -777,7 +825,7 @@ namespace Crow
                /// <summary>
                /// set the visible state of the control, invisible controls does reserve space in the layouting system.
                /// </summary>
-               [XmlAttributeAttribute][DefaultValue(true)]
+               [DesignCategory ("Appearance")][DefaultValue(true)]
                public virtual bool Visible {
                        get { return isVisible; }
                        set {
@@ -798,7 +846,7 @@ namespace Crow
                /// get or set the enabled state, disabling a control will affect focuability and
                /// also it's rendering which will be grayed
                /// </summary>
-               [XmlAttributeAttribute][DefaultValue(true)]
+               [DesignCategory ("Behaviour")][DefaultValue(true)]
                public virtual bool IsEnabled {
                        get { return isEnabled; }
                        set {
@@ -819,7 +867,7 @@ namespace Crow
                /// <summary>
                /// Minimal width and  height for this control
                /// </summary>
-               [XmlAttributeAttribute()][DefaultValue("1,1")]
+               [DesignCategory ("Layout")][DefaultValue("1,1")]
                public virtual Size MinimumSize {
                        get { return minimumSize; }
                        set {
@@ -835,7 +883,7 @@ namespace Crow
                /// <summary>
                /// Maximum width and  height for this control, unlimited if null.
                /// </summary>
-               [XmlAttributeAttribute()][DefaultValue("0,0")]
+               [DesignCategory ("Layout")][DefaultValue("0,0")]
                public virtual Size MaximumSize {
                        get { return maximumSize; }
                        set {
@@ -852,7 +900,7 @@ namespace Crow
                /// 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]
+               [DesignCategory ("Data")]
                public virtual object DataSource {
                        set {
                                if (DataSource == value)
@@ -893,7 +941,7 @@ namespace Crow
                /// <summary>
                /// Style key to use for this control
                /// </summary>
-               [XmlAttributeAttribute]
+               [DesignCategory ("Appearance")]
                public virtual string Style {
                        get { return style; }
                        set {
@@ -905,7 +953,7 @@ namespace Crow
                                NotifyValueChanged ("Style", style);
                        }
                }
-               [XmlAttributeAttribute]
+               [DesignCategory ("Divers")]
                public virtual string Tooltip {
                        get { return tooltip; }
                        set {
@@ -915,7 +963,7 @@ namespace Crow
                                NotifyValueChanged("Tooltip", tooltip);
                        }
                }
-               [XmlAttributeAttribute]
+               [DesignCategory ("Divers")]
                public IList<Command> ContextCommands {
                        get { return contextCommands; }
                        set {
@@ -1040,7 +1088,9 @@ namespace Crow
                                                name = pi.Name;
                                        else
                                                name = xaa.AttributeName;
-                               }
+                               }else
+                                       name = pi.Name;
+                               
                                int styleIndex = -1;
                                if (styling.Count > 0){
                                        for (int i = 0; i < styling.Count; i++) {
@@ -1057,13 +1107,21 @@ namespace Crow
                                                defaultValue = styling[styleIndex] [name];
 
                                        #if DESIGN_MODE
-                                       FileLocation fl = styling[styleIndex].Locations[name];
-                                       il.Emit (OpCodes.Ldloc_0);
-                                       il.Emit (OpCodes.Ldstr, name);
-                                       il.Emit (OpCodes.Ldstr, fl.FilePath);
-                                       il.Emit (OpCodes.Ldc_I4, fl.Line);
-                                       il.Emit (OpCodes.Ldc_I4, fl.Column);
-                                       il.Emit (OpCodes.Call, miDesignAddDefLoc);
+                                       if (defaultValue != null){
+                                               FileLocation fl = styling[styleIndex].Locations[name];
+                                               il.Emit (OpCodes.Ldloc_0);
+                                               il.Emit (OpCodes.Ldstr, name);
+                                               il.Emit (OpCodes.Ldstr, fl.FilePath);
+                                               il.Emit (OpCodes.Ldc_I4, fl.Line);
+                                               il.Emit (OpCodes.Ldc_I4, fl.Column);
+                                               il.Emit (OpCodes.Call, miDesignAddDefLoc);
+
+                                               il.Emit (OpCodes.Ldloc_0);
+                                               il.Emit (OpCodes.Ldfld, typeof(GraphicObject).GetField("design_style_values"));
+                                               il.Emit (OpCodes.Ldstr, name);
+                                               il.Emit (OpCodes.Ldstr, defaultValue.ToString());
+                                               il.Emit (OpCodes.Call, CompilerServices.miDicStrStrAdd);
+                                       }
                                        #endif
 
                                }else {
@@ -1122,7 +1180,7 @@ namespace Crow
                }
 
                #region Drag&Drop
-               [XmlAttributeAttribute][DefaultValue(false)]
+               [DesignCategory ("DragAndDrop")][DefaultValue(false)]
                public virtual bool AllowDrag {
                        get { return allowDrag; }
                        set {
@@ -1132,7 +1190,7 @@ namespace Crow
                                NotifyValueChanged ("AllowDrag", allowDrag);
                        }
                }
-               [XmlAttributeAttribute][DefaultValue(false)]
+               [DesignCategory ("DragAndDrop")][DefaultValue(false)]
                public virtual bool AllowDrop {
                        get { return allowDrop; }
                        set {
@@ -1193,8 +1251,12 @@ namespace Crow
                protected virtual void onDrop (object sender, DragDropEventArgs e){                     
                        IsDragged = false;
                        Drop.Raise (this, e);
+                       //e.DropTarget.onDragLeave (this, e);//raise drag leave in target
                        Debug.WriteLine(this.ToString() + " : DROP => " + e.ToString());
                }
+               public bool IsDropTarget {
+                       get { return IFace.DragAndDropOperation?.DropTarget == this; }
+               }
 
                #endregion
 
@@ -1314,8 +1376,8 @@ namespace Crow
                public virtual void OnLayoutChanges(LayoutingType  layoutType)
                {
                        #if DEBUG_LAYOUTING
-                       CurrentInterface.currentLQI.Slot = LastSlots;
-                       CurrentInterface.currentLQI.NewSlot = Slot;
+                       IFace.currentLQI.Slot = LastSlots;
+                       IFace.currentLQI.NewSlot = Slot;
                        Debug.WriteLine ("\t\t{0} => {1}",LastSlots,Slot);
                        #endif
 
@@ -1717,26 +1779,38 @@ namespace Crow
                        #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);
+               }
+               public virtual void onHover(object sender, EventArgs e)
+               {
+                       #if DEBUG_FOCUS
+                       Debug.WriteLine("MouseHover => " + this.ToString());
+                       #endif
                        if (IFace.DragAndDropOperation != null) {
                                if (this.AllowDrop) {
                                        if (IFace.DragAndDropOperation.DragSource != this && IFace.DragAndDropOperation.DropTarget != this)
                                                onDragEnter (this, IFace.DragAndDropOperation);                                 
                                }
                        }
-
-                       MouseEnter.Raise (this, e);
+                       Hover.Raise (this, e);
                }
-               public virtual void onMouseLeave(object sender, MouseMoveEventArgs e)
+               public virtual void onUnHover(object sender, EventArgs e)
                {
                        #if DEBUG_FOCUS
-                       Debug.WriteLine("MouseLeave => " + this.ToString());
+                       Debug.WriteLine("MouseUnHover => " + this.ToString());
                        #endif
                        if (IFace.DragAndDropOperation != null) {
                                if (IFace.DragAndDropOperation.DropTarget == this)
                                        onDragLeave (this, IFace.DragAndDropOperation);
                        }
-                       MouseLeave.Raise (this, e);
+                       UnHover.Raise (this, e);
                }
                #endregion
 
index 0eb1ece239d6215158b38cc6ef9ea5979b7ae7e1..11bf16fba09057e59a7be57d8a4f0f5c78acc1c2 100644 (file)
@@ -114,6 +114,8 @@ namespace Crow
                        childrenRWLock.EnterWriteLock ();
 
                        Children.Remove(child);
+                       child.Parent = null;
+                       //child.ResetSlots ();
 
                        childrenRWLock.ExitWriteLock ();
 
@@ -142,6 +144,9 @@ namespace Crow
                        g.LayoutChanged += OnChildLayoutChanges;
                        g.RegisterForLayouting (LayoutingType.Sizing | LayoutingType.ArrangeChildren);
                }
+               public virtual void RemoveChild (int idx) {
+                       RemoveChild (children[idx]);
+               }
                public virtual void DeleteChild (int idx) {
                        DeleteChild (children[idx]);
                }
@@ -263,7 +268,7 @@ namespace Crow
                        switch (layoutType) {
                        case LayoutingType.Width:
                                foreach (GraphicObject c in Children) {
-                                       if (c.Width.Units == Unit.Percent)
+                                       if (c.Width.IsRelativeToParent)
                                                c.RegisterForLayouting (LayoutingType.Width);
                                        else
                                                c.RegisterForLayouting (LayoutingType.X);
@@ -271,7 +276,7 @@ namespace Crow
                                break;
                        case LayoutingType.Height:
                                foreach (GraphicObject c in Children) {
-                                       if (c.Height.Units == Unit.Percent)
+                                       if (c.Height.IsRelativeToParent)
                                                c.RegisterForLayouting (LayoutingType.Height);
                                        else
                                                c.RegisterForLayouting (LayoutingType.Y);
@@ -294,9 +299,9 @@ namespace Crow
 
                        childrenRWLock.EnterReadLock ();
 
-                               foreach (GraphicObject g in Children) {
-                                       g.Paint (ref gr);
-                               }
+                       foreach (GraphicObject g in Children) {
+                               g.Paint (ref gr);
+                       }
 
                        childrenRWLock.ExitReadLock ();
                        gr.Restore ();
index 81017a7e6bb440558af61a5610e75f3711daa40f..b0719ef088e903fdb7ea6c75fc383df097a75a8c 100644 (file)
@@ -108,11 +108,11 @@ namespace Crow
                                //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)
+                                       if (Width == Measure.Fit && child.Width.IsRelativeToParent)
                                                child.Width = Measure.Fit;
                                        break;
                                case LayoutingType.Height:
-                                       if (Height == Measure.Fit && child.Height.Units == Unit.Percent)
+                                       if (Height == Measure.Fit && child.Height.IsRelativeToParent)
                                                child.Height = Measure.Fit;
                                        break;
                                }
@@ -129,14 +129,14 @@ namespace Crow
                        LayoutingType ltChild = LayoutingType.None;
 
                        if (layoutType == LayoutingType.Width) {
-                               if (child.Width.Units == Unit.Percent) {
+                               if (child.Width.IsRelativeToParent) {
                                        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) {
+                               if (child.Height.IsRelativeToParent) {
                                        ltChild |= LayoutingType.Height;
                                        if (child.Height.Value < 100 && child.Top == 0)
                                                ltChild |= LayoutingType.Y;
index 42ffa51cd27ed804b622dd4f28a849ba0d5d4b69..f7c937638bb2c2e4ea6259625d6d41e6c0bdaa98 100644 (file)
@@ -457,8 +457,9 @@ namespace Crow
                        }
 
                        if (iTemp.Expand != null && g is Expandable) {
-                               (g as Expandable).Expand += iTemp.Expand;
-                               (g as Expandable).GetIsExpandable = iTemp.HasSubItems;
+                               Expandable e = g as Expandable;
+                               e.Expand += iTemp.Expand;
+                               e.GetIsExpandable = iTemp.HasSubItems;
                        }
 
                        g.DataSource = o;
index 3f5dfdf0ce2c93be57088ff81f841a5f9735add0..a7f5f73b8965d50d46285605c37206ddb6c65beb 100644 (file)
@@ -104,7 +104,7 @@ namespace Crow
                                this.RegisterForLayouting (LayoutingType.Width);
                                break;
                        case LayoutingType.Height:
-                               if (Orientation == Orientation.Vertical && go.Height.Units == Unit.Percent) {
+                               if (Orientation == Orientation.Vertical && go.Height.IsRelativeToParent) {
                                        go.Height = Measure.Fit;
                                        return;
                                }
@@ -137,7 +137,7 @@ namespace Crow
                                        foreach (GraphicObject c in Children) {
                                                if (!c.Visible)
                                                        continue;
-                                               if (c.Height.Units == Unit.Percent &&
+                                               if (c.Height.IsRelativeToParent &&
                                                    c.RegisteredLayoutings.HasFlag (LayoutingType.Height)) {
                                                        childrenRWLock.ExitReadLock();
                                                        return -1;
@@ -172,7 +172,7 @@ namespace Crow
                                foreach (GraphicObject c in Children) {
                                        if (!c.Visible)
                                                continue;
-                                       if (c.Width.Units == Unit.Percent &&
+                                       if (c.Width.IsRelativeToParent &&
                                            c.RegisteredLayoutings.HasFlag (LayoutingType.Width)) {
                                                childrenRWLock.ExitReadLock();
                                                return -1;
@@ -217,13 +217,13 @@ namespace Crow
                public override void OnLayoutChanges (LayoutingType layoutType)
                {
                        #if DEBUG_LAYOUTING
-                       CurrentInterface.currentLQI.Slot = LastSlots;
-                       CurrentInterface.currentLQI.Slot = Slot;
+                       IFace.currentLQI.Slot = LastSlots;
+                       IFace.currentLQI.Slot = Slot;
                        #endif
                        switch (layoutType) {
                        case LayoutingType.Width:
                                foreach (GraphicObject c in Children) {
-                                       if (c.Width.Units == Unit.Percent)
+                                       if (c.Width.IsRelativeToParent)
                                                c.RegisterForLayouting (LayoutingType.Width);
                                }
                                if (Height == Measure.Fit)
@@ -232,7 +232,7 @@ namespace Crow
                                break;
                        case LayoutingType.Height:
                                foreach (GraphicObject c in Children) {
-                                       if (c.Height.Units == Unit.Percent)
+                                       if (c.Height.IsRelativeToParent)
                                                c.RegisterForLayouting (LayoutingType.Height);
                                }
                                if (Width == Measure.Fit)
diff --git a/src/IMLAttributes.cs b/src/IMLAttributes.cs
new file mode 100644 (file)
index 0000000..40ba5f9
--- /dev/null
@@ -0,0 +1,40 @@
+//
+// IMLAttributes.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 DesignCategory : Attribute
+       {
+               public string Name { get; set; }
+
+               public DesignCategory (string name)
+               {
+                       Name = name;
+               }
+       }
+}
+
index 5c6711f5f0e1bff56958f772701ebe88e3d3b8ce..49d4f5334c37beb2b8f0d1910484abf4b2575d6e 100644 (file)
@@ -388,6 +388,21 @@ namespace Crow.IML
                                }
                        }
                }
+
+               #if DESIGN_MODE
+               void emitSetDesignAttribute (IMLContext ctx, string name, string value){
+                       //store member value in iml
+                       ctx.il.Emit (OpCodes.Ldloc_0);
+                       ctx.il.Emit (OpCodes.Ldfld, typeof(GraphicObject).GetField("design_iml_values"));
+                       ctx.il.Emit (OpCodes.Ldstr, name);
+                       if (string.IsNullOrEmpty (value))
+                               ctx.il.Emit (OpCodes.Ldnull);
+                       else
+                               ctx.il.Emit (OpCodes.Ldstr, value);
+                       ctx.il.Emit (OpCodes.Call, CompilerServices.miDicStrStrAdd);
+               }
+               #endif
+
                /// <summary>
                /// process styling, attributes and children loading.
                /// </summary>
@@ -419,8 +434,12 @@ namespace Crow.IML
                                //first check for Style attribute then trigger default value loading
                                if (reader.HasAttributes) {
                                        string style = reader.GetAttribute ("Style");
-                                       if (!string.IsNullOrEmpty (style))
+                                       if (!string.IsNullOrEmpty (style)){
                                                CompilerServices.EmitSetValue (ctx.il, CompilerServices.piStyle, style);
+                                               #if DESIGN_MODE
+                                               emitSetDesignAttribute (ctx, "Style", style);
+                                               #endif
+                                       }
                                }
                                ctx.il.Emit (OpCodes.Ldloc_0);
                                ctx.il.Emit (OpCodes.Callvirt, CompilerServices.miLoadDefaultVals);
@@ -434,19 +453,9 @@ namespace Crow.IML
                                                        continue;
 
                                                #if DESIGN_MODE
-                                               //store member value in iml
-                                               ctx.il.Emit (OpCodes.Ldloc_0);
-                                               ctx.il.Emit (OpCodes.Ldfld, typeof(GraphicObject).GetField("design_members"));
-                                               ctx.il.Emit (OpCodes.Ldstr, reader.Name);
-                                               if (string.IsNullOrEmpty (reader.Value))
-                                                       ctx.il.Emit (OpCodes.Ldnull);
-                                               else
-                                                       ctx.il.Emit (OpCodes.Ldstr, reader.Value);
-                                               ctx.il.Emit (OpCodes.Call, 
-                                                       typeof(Dictionary<string, string>).GetMethod ("set_Item", new Type[] { typeof(string), typeof(string) }));
+                                               emitSetDesignAttribute (ctx, reader.Name, reader.Value);
                                                #endif
 
-
                                                MemberInfo mi = ctx.CurrentNodeType.GetMember (reader.Name).FirstOrDefault ();
                                                if (mi == null)
                                                        throw new Exception ("Member '" + reader.Name + "' not found in " + ctx.CurrentNodeType.Name);
index cdfd24d7a1034a48d2bbf93d51b1efc791662df6..4b7807319c0d1ef1b43f856a927a123d0ec7160c 100644 (file)
@@ -459,13 +459,22 @@ namespace Crow
                        set {
                                if (_hoverWidget == value)
                                        return;
+
+                               if (_hoverWidget != null)
+                                       _hoverWidget.IsHover = false;
+
                                _hoverWidget = value;
-                               #if DEBUG_FOCUS
+
                                if (_hoverWidget != null)
-                               Debug.WriteLine("Hover => " + _hoverWidget.ToString());
-                               else
-                               Debug.WriteLine("Hover => null");
-                               #endif
+                               {
+                                       _hoverWidget.IsHover = true;
+                                       #if DEBUG_FOCUS
+                                       Debug.WriteLine("Hover => " + _activeWidget.ToString());
+                                       }else
+                                       Debug.WriteLine("Hover => null");
+                                       #else
+                               }
+                                       #endif
                        }
                }
                /// <summary>Widget has the keyboard or mouse focus</summary>
index c88038c6f33e6a2b81928dfeba6aa494c24c2f4e..0374f5d9d6ebb3c05f86339b45d0a5c6c9543df8 100644 (file)
@@ -69,6 +69,7 @@ namespace Crow
                /// </summary>
                public bool IsFixed { get { return Units == Unit.Pixel; }}
                public bool IsFit { get { return Value == -1 && Units == Unit.Percent; }}
+               public bool IsRelativeToParent { get { return Value >= 0 && Units == Unit.Percent; }}
                #region Operators
                public static implicit operator int(Measure m){
                        return m.Value;
index c597abb9cb459185b5f1d4693e5999ab0d31c77d..e8a3ca136398088c628cfde6dfebdf69e7c1242e 100644 (file)
@@ -162,7 +162,7 @@ namespace Crow
                                                #if DESIGN_MODE
                                                styling [tc].Locations[currentProperty] = new FileLocation(resId, line,column);
                                                #endif
-                                               System.Diagnostics.Debug.WriteLine ("Style: {3} : {0}.{1} = {2}", tc, currentProperty, token, resId);
+                                               //System.Diagnostics.Debug.WriteLine ("Style: {3} : {0}.{1} = {2}", tc, currentProperty, token, resId);
                                        }
                                        token = "";
                                        curState = States.members;