<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" />
<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" />
//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'/>");
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 ();
--- /dev/null
+//
+// 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;
+ }
+ }
+}
+
--- /dev/null
+//
+// 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 ();
+// }
+
+ }
+}
--- /dev/null
+//
+// 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);
+ }
+ }
+}
+
+++ /dev/null
-//
-// 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 ();
-// }
-
- }
-}
#endregion
bool isLoaded = false;
+ bool isExpanded;
XmlDocument xmlDoc;
XmlNode nodeProject;
XmlNode nodeProps;
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; }
}
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:
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;
}
f = new ProjectFile (pn);
break;
}
- curNode.ChildNodes.Add (f);
+ curNode.AddChild (f);
flattenNodes.Add (f);
break;
}
Commands = new List<Crow.Command> ();
}
+ ProjectNode parent;
+ bool isExpanded;
ItemType type;
string name;
List<ProjectNode> childNodes = new List<ProjectNode>();
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; }
}
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;
+++ /dev/null
-//
-// 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;
- }
-
-
- }
-}
-
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;
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;
s.UserConfig = new Configuration (s.path + ".user");
s.ReloadStyling ();
s.ReloadDefaultTemplates ();
- s.reopenItemsSavedInUserConfig ();
return s;
} //LoadSolution
#endregion
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();
/// </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){
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;
}
}
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;
}
return i;
}
- int CurrentTabulatedColumn {
+ public int CurrentTabulatedColumn {
get {
return lines [_currentLine].Content.Substring (0, _currentCol).
Replace ("\t", new String (' ', Interface.TabSize)).Length;
set {
if (value == _currentCol)
return;
+
+ editMutex.EnterReadLock ();
+
if (value < 0)
_currentCol = 0;
else if (value > lines [_currentLine].Length)
_currentCol = value;
requestedColumn = CurrentTabulatedColumn;
- //requestedColumn = _currentCol;
+
+ editMutex.ExitReadLock ();
PositionChanged.Raise (this, null);
}
set {
if (value == _currentLine)
return;
+
+ editMutex.EnterReadLock ();
+
if (value >= lines.Count)
_currentLine = lines.Count-1;
else if (value < 0)
//_currentCol = requestedColumn;
_currentCol = tabulatedRequestedCol;
//Debug.WriteLine ("buff cur line: " + _currentLine);
+
+ editMutex.ExitReadLock();
+
PositionChanged.Raise (this, null);
}
}
/// </summary>
public class SourceEditor : ScrollingObject
{
+ public ReaderWriterLockSlim seMutex = new ReaderWriterLockSlim(LockRecursionPolicy.SupportsRecursion);
+
#region CTOR
public SourceEditor (): base()
{
loadSource ();
isDirty = false;
oldSource = projFile.Source;
+ CurrentLine = requestedLine;
+ CurrentColumn = requestedCol;
projFile.RegisteredEditors [this] = true;
}
buffer.editMutex.EnterWriteLock ();
}
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>
}
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);
}
void updatePrintedLines () {
buffer.editMutex.EnterReadLock ();
+ seMutex.EnterWriteLock ();
+
PrintedLines = new List<CodeLine> ();
int curL = 0;
int i = 0;
curL++;
i++;
}
+
buffer.editMutex.ExitReadLock ();
+ seMutex.ExitWriteLock ();
}
void toogleFolding (int line) {
if (parser == null || !foldingEnabled)
#region Buffer events handlers
void Buffer_BufferCleared (object sender, EventArgs e)
{
+ seMutex.EnterWriteLock ();
+
buffer.longestLineCharCount = 0;
buffer.longestLineIdx = 0;
measureLeftMargin ();
RegisterForGraphicUpdate ();
notifyPositionChanged ();
isDirty = true;
+
+ seMutex.ExitWriteLock ();
}
void Buffer_LineAdditionEvent (object sender, CodeBufferEventArgs e)
{
}
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 ();
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 ());
}
}
}
#endregion
+ seMutex.EnterReadLock ();
+
if (PrintedLines != null) {
for (int i = 0; i < visibleLines; i++) {
if (i + ScrollY >= buffer.UnfoldedLines)//TODO:need optimize
drawLine (gr, cb, i);
}
}
+
+ seMutex.ExitReadLock ();
+
buffer.editMutex.ExitReadLock ();
}
<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}"/>
<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"
</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"/>
</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"/>
<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>
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";
}
Splitter {
Focusable = "true";
- Background = "DimGray";
+ Margin = "1";
+ Background = "White";
}
Spinner {
Foreground = "DimGray";
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";
}
<?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>-->
<?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
--- /dev/null
+<?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
<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\" />
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");
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);
--- /dev/null
+//
+// 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'/>");
+ }
+
+ }
+}
+
}
#endregion
+ int undockThreshold = 10;
bool isDocked = false;
Alignment docking = Alignment.Center;
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 {
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))
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;
}
// }
// }
//
-// 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);
}
-
}
}
}
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 {
}
}
- 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 ();
childrenRWLock.EnterReadLock ();
foreach (GraphicObject g in Children) {
- if (IFace.DragAndDropOperation?.DragSource == g)
- continue;
+// if (IFace.DragAndDropOperation?.DragSource == g)
+// continue;
g.Paint (ref gr);
}
if (showDockingTarget) {
Rectangle r;
- if (mainStack == null)
+ if (stack == null)
r = ClientRectangle;
else
- r = mainStack.ClientRectangle;
+ r = stack.ClientRectangle;
switch (dockingDirection) {
case Alignment.Top:
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);
- }
+ }*/
}
}
NotifyValueChanged ("Image", image);
}
}
- [XmlAttributeAttribute][DefaultValue(false)]
+ [DefaultValue(false)]
public bool IsExpanded
{
get { return _isExpanded; }
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;
} 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);
} 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);
}
#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);
+ }
}
}
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){
getIML (doc, (XmlNode)doc);
doc.WriteTo (xtw);
}
- this.HasChanged = false;
+ this.design_HasChanged = false;
return sw.ToString ();
}
}
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);
bool focusable = false;
bool hasFocus = false;
bool isActive = false;
+ bool isHover = false;
bool mouseRepeat;
protected bool isVisible = true;
bool isEnabled = true;
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
}
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>
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;
#region public properties
/// <summary>Random value placeholder</summary>
- [XmlAttributeAttribute]
+ [DesignCategory ("Divers")]
public object Tag {
get { return tag; }
set {
/// 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 {
/// <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 {
/// 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
/// 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 {
/// 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 {
/// <summary>
/// x position inside parent
/// </summary>
- [XmlAttributeAttribute()][DefaultValue(0)]
+ [DesignCategory ("Layout")][DefaultValue(0)]
public virtual int Left {
get { return left; }
set {
/// <summary>
/// y position inside parent
/// </summary>
- [XmlAttributeAttribute()][DefaultValue(0)]
+ [DesignCategory ("Layout")][DefaultValue(0)]
public virtual int Top {
get { return top; }
set {
/// <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 {
/// 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 ?
/// 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 ?
/// 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 {
}
}
/// <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 {
/// <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 {
/// <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 {
/// <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 {
/// <summary>
/// to get rounded corners
/// </summary>
- [XmlAttributeAttribute()][DefaultValue(0.0)]
+ [DesignCategory ("Appearance")][DefaultValue(0.0)]
public virtual double CornerRadius {
get { return cornerRadius; }
set {
/// 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 {
/// <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 {
/// 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 {
/// <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 {
/// <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 {
/// 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)
/// <summary>
/// Style key to use for this control
/// </summary>
- [XmlAttributeAttribute]
+ [DesignCategory ("Appearance")]
public virtual string Style {
get { return style; }
set {
NotifyValueChanged ("Style", style);
}
}
- [XmlAttributeAttribute]
+ [DesignCategory ("Divers")]
public virtual string Tooltip {
get { return tooltip; }
set {
NotifyValueChanged("Tooltip", tooltip);
}
}
- [XmlAttributeAttribute]
+ [DesignCategory ("Divers")]
public IList<Command> ContextCommands {
get { return contextCommands; }
set {
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++) {
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 {
}
#region Drag&Drop
- [XmlAttributeAttribute][DefaultValue(false)]
+ [DesignCategory ("DragAndDrop")][DefaultValue(false)]
public virtual bool AllowDrag {
get { return allowDrag; }
set {
NotifyValueChanged ("AllowDrag", allowDrag);
}
}
- [XmlAttributeAttribute][DefaultValue(false)]
+ [DesignCategory ("DragAndDrop")][DefaultValue(false)]
public virtual bool AllowDrop {
get { return allowDrop; }
set {
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
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
#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
childrenRWLock.EnterWriteLock ();
Children.Remove(child);
+ child.Parent = null;
+ //child.ResetSlots ();
childrenRWLock.ExitWriteLock ();
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]);
}
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);
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);
childrenRWLock.EnterReadLock ();
- foreach (GraphicObject g in Children) {
- g.Paint (ref gr);
- }
+ foreach (GraphicObject g in Children) {
+ g.Paint (ref gr);
+ }
childrenRWLock.ExitReadLock ();
gr.Restore ();
//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;
}
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;
}
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;
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;
}
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;
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;
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)
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)
--- /dev/null
+//
+// 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;
+ }
+ }
+}
+
}
}
}
+
+ #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>
//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);
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);
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>
/// </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;
#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;