From: Jean-Philippe Bruyère Date: Thu, 15 Feb 2018 13:58:36 +0000 (+0100) Subject: CrowIDE WIP, context commands, tooltips, PointIsIn(ref point), configuration no longe... X-Git-Tag: 0.7.0~19 X-Git-Url: https://git.osiis.dedyn.io/?a=commitdiff_plain;h=60719330e1ce6dc4516ae502b055be33e0293950;p=jp%2Fcrow.git CrowIDE WIP, context commands, tooltips, PointIsIn(ref point), configuration no longer static. also: - remove default null value for datasource - dschange sender changed in group and privateContainer - try closing menuItem, should debug - Contains search also template in TemplatedContainer - change in nodeAddress: expresion starting with '/' means current node - MouseEventArgs CTOR with one source button - RemoveWidget trigger check HoverWidget - Orientation binding in Menu template --- diff --git a/Crow.csproj b/Crow.csproj index 4de640dd..a061ae54 100644 --- a/Crow.csproj +++ b/Crow.csproj @@ -30,7 +30,7 @@ true full true - DEBUG_UPDATE0;DEBUG_FOCUS0;DEBUG_LAYOUTING0;TRACE0;DEBUG;MEASURE_TIME;DEBUG_LOAD0;DEBUG_BINDING;DEBUG_CLIP_RECTANGLE0 + DEBUG_UPDATE0;DEBUG_FOCUS0;DEBUG_LAYOUTING0;TRACE0;DEBUG;MEASURE_TIME;DEBUG_LOAD0;DEBUG_BINDING0;DEBUG_CLIP_RECTANGLE0 false $(SolutionDir)build\Debug @@ -371,10 +371,18 @@ Crow.Tooltip.template + + Crow.ContextMenu.template + + + + PreserveNewest + + diff --git a/CrowIDE/CrowIDE.csproj b/CrowIDE/CrowIDE.csproj index 8caa22a3..69e8bf42 100644 --- a/CrowIDE/CrowIDE.csproj +++ b/CrowIDE/CrowIDE.csproj @@ -107,6 +107,7 @@ + diff --git a/CrowIDE/src/CrowIDE.cs b/CrowIDE/src/CrowIDE.cs index fda596b3..2ad1fa75 100644 --- a/CrowIDE/src/CrowIDE.cs +++ b/CrowIDE/src/CrowIDE.cs @@ -86,7 +86,6 @@ namespace CrowIDE { } ImlVisualEditor imlVE; - SourceEditor srcEditor; Instantiator instFileDlg; @@ -97,7 +96,7 @@ namespace CrowIDE base.OnLoad (e); instFileDlg = Instantiator.CreateFromImlFragment - (""); + (""); initCommands (); @@ -126,9 +125,9 @@ namespace CrowIDE } public string CurrentDirectory { - get { return Crow.Configuration.Get("CurrentDirectory");} + get { return Crow.Configuration.Global.Get("CurrentDirectory");} set { - Crow.Configuration.Set ("CurrentDirectory", value); + Crow.Configuration.Global.Set ("CurrentDirectory", value); } } public Solution CurrentSolution { @@ -142,20 +141,20 @@ namespace CrowIDE } public string LastOpenSolution { - get { return Crow.Configuration.Get("LastOpenSolution");} + get { return Crow.Configuration.Global.Get("LastOpenSolution");} set { if (LastOpenSolution == value) return; - Crow.Configuration.Set ("LastOpenSolution", value); + Crow.Configuration.Global.Set ("LastOpenSolution", value); NotifyValueChanged ("LastOpenSolution", value); } } public bool ReopenLastSolution { - get { return Crow.Configuration.Get("ReopenLastSolution");} + get { return Crow.Configuration.Global.Get("ReopenLastSolution");} set { if (ReopenLastSolution == value) return; - Crow.Configuration.Set ("ReopenLastSolution", value); + Crow.Configuration.Global.Set ("ReopenLastSolution", value); NotifyValueChanged ("ReopenLastSolution", value); } } @@ -184,15 +183,16 @@ namespace CrowIDE if (e.Key == OpenTK.Input.Key.Escape) { Quit (null, null); return; - } else if (e.Key == OpenTK.Input.Key.F4) { - loadWindow ("#CrowIDE.ui.MemberView.crow"); - } else if (e.Key == OpenTK.Input.Key.F5) { - loadWindow ("#CrowIDE.ui.GTreeExplorer.crow"); - } else if (e.Key == OpenTK.Input.Key.F6) { - loadWindow ("#CrowIDE.ui.LQIsExplorer.crow"); - } else if (e.Key == OpenTK.Input.Key.F7) { - loadWindow ("#CrowIDE.ui.CSProjExplorer.crow"); } +// else if (e.Key == OpenTK.Input.Key.F4) { +// loadWindow ("#CrowIDE.ui.MemberView.crow"); +// } else if (e.Key == OpenTK.Input.Key.F5) { +// loadWindow ("#CrowIDE.ui.GTreeExplorer.crow"); +// } else if (e.Key == OpenTK.Input.Key.F6) { +// loadWindow ("#CrowIDE.ui.LQIsExplorer.crow"); +// } else if (e.Key == OpenTK.Input.Key.F7) { +// loadWindow ("#CrowIDE.ui.CSProjExplorer.crow"); +// } } void loadWindow(string path, object dataSource = null){ try { diff --git a/CrowIDE/src/DesignInterface.cs b/CrowIDE/src/DesignInterface.cs index ae104feb..10ceffc5 100644 --- a/CrowIDE/src/DesignInterface.cs +++ b/CrowIDE/src/DesignInterface.cs @@ -54,6 +54,11 @@ namespace CrowIDE CultureInfo.DefaultThreadCurrentCulture = System.Globalization.CultureInfo.InvariantCulture; } + protected override void loadStyling () + { + base.loadStyling (); + } + public override bool ProcessMouseMove (int x, int y) { int deltaX = x - Mouse.X; diff --git a/CrowIDE/src/Project.cs b/CrowIDE/src/Project.cs index ac675713..e2690b7c 100644 --- a/CrowIDE/src/Project.cs +++ b/CrowIDE/src/Project.cs @@ -30,24 +30,58 @@ using System.Collections.Generic; using System.Linq; using Microsoft.CSharp; using System.CodeDom.Compiler; +using Crow; namespace CrowIDE { - public class Project { - string path; + public class Project: IValueChange + { + #region IValueChange implementation + public event EventHandler ValueChanged; + public virtual void NotifyValueChanged(string MemberName, object _value) + { + ValueChanged.Raise(this, new ValueChangeEventArgs(MemberName, _value)); + } + #endregion + + bool isLoaded = false; XmlDocument xmlDoc; XmlNode nodeProject; XmlNode nodeProps; XmlNodeList nodesItems; public Solution solution; + public List Commands; + public CompilerResults CompilationResults; + public List dependantProjects = new List(); + public Project ParentProject = null; public string Name { - get { return solution.projects.FirstOrDefault(p=>p.ProjectGuid == ProjectGuid).ProjectName; } + get { return solutionProject.ProjectName; } + } + public bool IsLoaded { + get { return isLoaded; } + set { + if (isLoaded == value) + return; + isLoaded = value; + NotifyValueChanged ("IsLoaded", isLoaded); + } } + public bool IsStartupProject { + get { + bool result = solution.StartupProject == this; + System.Diagnostics.Debug.WriteLine ("is startup project tested for {0} => {1}", this.ProjectGuid, result); + return result; + } + } + public string Path { + get { return System.IO.Path.Combine (solution.SolutionFolder, solutionProject.RelativePath.Replace('\\','/')); } + } + #region Project properties public string RootDir { - get { return Path.GetDirectoryName (path); } + get { return System.IO.Path.GetDirectoryName (Path); } } public string ToolsVersion { get { return nodeProject?.Attributes ["ToolsVersion"]?.Value; } @@ -56,7 +90,7 @@ namespace CrowIDE get { return nodeProject?.Attributes ["DefaultTargets"]?.Value; } } public string ProjectGuid { - get { return nodeProps["ProjectGuid"]?.InnerText; } + get { return solutionProject.ProjectGuid; } } public string AssemblyName { get { return nodeProps["AssemblyName"]?.InnerText; } @@ -68,13 +102,16 @@ namespace CrowIDE get { return nodeProps["RootNamespace"]?.InnerText; } } public bool AllowUnsafeBlocks { - get { return bool.Parse (nodeProps["AllowUnsafeBlocks"]?.InnerText); } + get {return nodeProps["AllowUnsafeBlocks"] == null ? false : + bool.Parse (nodeProps["AllowUnsafeBlocks"]?.InnerText); } } public bool NoStdLib { - get { return bool.Parse (nodeProps["NoStdLib"]?.InnerText); } + get { return nodeProps["NoStdLib"] == null ? false : + bool.Parse (nodeProps["NoStdLib"]?.InnerText); } } public bool TreatWarningsAsErrors { - get { return bool.Parse (nodeProps["TreatWarningsAsErrors"]?.InnerText); } + get { return nodeProps["TreatWarningsAsErrors"] == null ? false: + bool.Parse (nodeProps["TreatWarningsAsErrors"]?.InnerText); } } public bool SignAssembly { get { return bool.Parse (nodeProps["SignAssembly"]?.InnerText); } @@ -117,7 +154,10 @@ namespace CrowIDE switch (pn.Type) { case ItemType.Reference: refs.ChildNodes.Add (pn); - break; + break; + case ItemType.ProjectReference: + refs.ChildNodes.Add (new ProjectReference(pn)); + break; case ItemType.Compile: case ItemType.None: case ItemType.EmbeddedResource: @@ -131,7 +171,17 @@ namespace CrowIDE } curNode = nextNode; } - curNode.ChildNodes.Add (pn); + switch (pn.Extension) { + case ".crow": + case ".template": + curNode.ChildNodes.Add (new ImlProjectItem(pn)); + break; + default: + curNode.ChildNodes.Add (pn); + break; + } + + break; } } @@ -141,13 +191,25 @@ namespace CrowIDE } } - public Project () {} + SolutionProject solutionProject; + + public Project (Solution sol, SolutionProject sp) { + solutionProject = sp; + + solution = sol; + + Commands = new List (new Crow.Command[] { + new Crow.Command(new Action(() => Compile())) { Caption = "Compile"}, + new Crow.Command(new Action(() => setAsStartupProject())) { Caption = "Set as Startup Project"}, + }); + + Load (); + } - public Project (string _path, Solution _solution){ - solution = _solution; - path = _path; + public void Load () { + xmlDoc = new XmlDocument(); - using (Stream ins = new FileStream (_path, FileMode.Open)) { + using (Stream ins = new FileStream (this.Path, FileMode.Open)) { xmlDoc.Load (new XmlTextReader(ins) { Namespaces = false }); } @@ -160,25 +222,78 @@ namespace CrowIDE } nodesItems = xmlDoc.SelectNodes ("/Project/ItemGroup"); + if (ProjectGuid != solutionProject.ProjectGuid) + throw new Exception ("Project GUID not matching with solution"); + + IsLoaded = true; + } + + void setAsStartupProject () { + solution.StartupProject = this; } - public void Compile () { - CSharpCodeProvider cp = new CSharpCodeProvider(); + if (ParentProject != null) + ParentProject.Compile (); + CSharpCodeProvider cp = new CSharpCodeProvider(); CompilerParameters parameters = new CompilerParameters(); + foreach (ProjectItem pi in Items.Where (pp=>pp.Type == ItemType.ProjectReference)) { + ProjectReference pr = new ProjectReference (pi); + Project p = solution.Projects.FirstOrDefault (pp => pp.ProjectGuid == pr.ProjectGUID); + if (p == null) + throw new Exception ("referenced project not found"); + p.Compile (); + parameters.ReferencedAssemblies.Add (pr.DisplayName); + } + foreach (ProjectItem pi in Items.Where (p=>p.Type == ItemType.Reference)) { parameters.ReferencedAssemblies.Add (pi.Path); } + parameters.ReferencedAssemblies.Add ("System.Core"); parameters.GenerateInMemory = true; + + if (!Directory.Exists("testbuild")) + Directory.CreateDirectory ("testbuild"); + parameters.OutputAssembly = "testbuild/" + this.AssemblyName; + // True - exe file generation, false - dll file generation - parameters.GenerateExecutable = true; + if (this.OutputType == "Library") { + parameters.GenerateExecutable = false; + parameters.CompilerOptions += " /target:library"; + parameters.OutputAssembly += ".dll"; + } else { + parameters.GenerateExecutable = true; + parameters.CompilerOptions += " /target:exe"; + parameters.OutputAssembly += ".exe"; + } + + parameters.IncludeDebugInformation = true; + parameters.TreatWarningsAsErrors = this.TreatWarningsAsErrors; + parameters.WarningLevel = 4; + parameters.CompilerOptions += " /noconfig"; + if (this.AllowUnsafeBlocks) + parameters.CompilerOptions += " /unsafe"; + parameters.CompilerOptions += " /delaysign+"; + + foreach (ProjectFile pi in Items.OfType().Where (p => p.Type == ItemType.EmbeddedResource)) { + + string absPath = pi.AbsolutePath; + string logicName = pi.LogicalName; + if (string.IsNullOrEmpty (logicName)) + parameters.CompilerOptions += string.Format (" /resource:{0}", absPath); + else + parameters.CompilerOptions += string.Format (" /resource:{0},{1}", absPath, logicName); + } + string[] files = Items.Where (p => p.Type == ItemType.Compile).Select (p => p.AbsolutePath).ToArray(); - CompilerResults results = cp.CompileAssemblyFromFile(parameters, files); + CompilationResults = cp.CompileAssemblyFromFile(parameters, files); + + solution.UpdateErrorList (); } } } diff --git a/CrowIDE/src/ProjectNodes.cs b/CrowIDE/src/ProjectNodes.cs index 5be419ab..5d13af05 100644 --- a/CrowIDE/src/ProjectNodes.cs +++ b/CrowIDE/src/ProjectNodes.cs @@ -83,8 +83,7 @@ namespace CrowIDE foreach (ProjectNode pn in childNodes) pn.SortChilds (); childNodes = childNodes.OrderBy(c=>c.Type).ThenBy(cn=>cn.DisplayName).ToList(); - } - + } } public class ProjectItem : ProjectNode { #region CTOR @@ -94,9 +93,6 @@ namespace CrowIDE #endregion public XmlNode node; - object selectedItem; - - public string Extension { get { return System.IO.Path.GetExtension (Path); } @@ -123,6 +119,32 @@ namespace CrowIDE Path.Split ('/').LastOrDefault(); } } + + } + public class ProjectReference : ProjectItem { + public ProjectReference (ProjectItem pi) : base (pi.Project, pi.node){ + } + public string ProjectGUID { + get { + return node.SelectSingleNode ("Project")?.InnerText; + } + } + public override string DisplayName { + get { + return node.SelectSingleNode ("Name").InnerText; + } + } + } + public class ProjectFile : ProjectItem { + public ProjectFile (ProjectItem pi) : base (pi.Project, pi.node){ + } + + object selectedItem; + public string LogicalName { + get { + return node.SelectSingleNode ("LogicalName")?.InnerText; + } + } public string Source { get { using (StreamReader sr = new StreamReader (AbsolutePath)) { @@ -145,11 +167,10 @@ namespace CrowIDE Project.solution.CloseItem (this); } } - public class ImlProjectItem : ProjectItem + public class ImlProjectItem : ProjectFile { #region CTOR - public ImlProjectItem (Project project, XmlNode _node) : base (project, _node){ - node = _node; + public ImlProjectItem (ProjectItem pi) : base (pi){ } #endregion diff --git a/CrowIDE/src/Solution.cs b/CrowIDE/src/Solution.cs index aba707e4..d8a7c4e7 100644 --- a/CrowIDE/src/Solution.cs +++ b/CrowIDE/src/Solution.cs @@ -41,7 +41,10 @@ namespace CrowIDE{ } #endregion + ProjectItem selectedItem = null; + object selectedItemElement = null; ObservableList openedItems = new ObservableList(); + public ObservableList OpenedItems { get { return openedItems; } set { @@ -51,9 +54,6 @@ namespace CrowIDE{ NotifyValueChanged ("OpenedItems", openedItems); } } - ProjectItem selectedItem = null; - object selectedItemElement = null; - public ProjectItem SelectedItem { get { return selectedItem; } set { @@ -72,6 +72,47 @@ namespace CrowIDE{ NotifyValueChanged ("SelectedItemElement", selectedItemElement); } } + public string DisplayName { + get { return name; } + } + /// + /// Gets solution path + /// + public String SolutionFolder + { + get { return Path.GetDirectoryName (path); } + } + +// public System.CodeDom.Compiler.CompilerErrorCollection CompilationErrors { +// get { +// System.CodeDom.Compiler.CompilerErrorCollection tmp = Projects.SelectMany +// (p => p.CompilationResults.Errors); +// return tmp; +// } +// } + public List CompilerErrors { + get { + int errCount = 0; + for (int i = 0; i < Projects.Count; i++) { + if (Projects [i].CompilationResults != null) + errCount += Projects [i].CompilationResults.Errors.Count; + } + System.CodeDom.Compiler.CompilerError[] tmp = new System.CodeDom.Compiler.CompilerError[errCount]; + + int ptr = 0; + for (int i = 0; i < Projects.Count; i++) { + if (Projects [i].CompilationResults == null) + continue; + Projects [i].CompilationResults.Errors.CopyTo (tmp,ptr); + ptr += Projects [i].CompilationResults.Errors.Count; + } + return new List(tmp); + } + } + + public void UpdateErrorList () { + NotifyValueChanged ("CompilerErrors", CompilerErrors); + } void onSelectedItemChanged (object sender, SelectionChangeEventArgs e){ ProjectItem pi = e.NewValue as ProjectItem; @@ -92,17 +133,12 @@ namespace CrowIDE{ /// /// Solution name /// - public String name; - - public string DisplayName { - get { return name; } - } - - /// - /// File path from where solution was loaded. - /// - [XmlIgnore] - public String path; + String name; + /// + /// File path from where solution was loaded. + /// + [XmlIgnore] + String path; /// /// Solution name for debugger. @@ -112,27 +148,7 @@ namespace CrowIDE{ { return "Solution: " + name; } - - /// - /// Gets solution path - /// - /// - public String SolutionFolder - { - get { return Path.GetDirectoryName (path); } - } - - public IList Projects { - get { - List tmp = new List (); - foreach (SolutionProject p in projects) { - string pp = Path.Combine (SolutionFolder, p.RelativePath.Replace('\\','/')); - tmp.Add (new Project (pp, this)); - } - return tmp; - } - } - + #region Solution properties double slnVer; // 11.00 - vs2010, 12.00 - vs2015 @@ -154,7 +170,7 @@ namespace CrowIDE{ /// /// List of project included into solution. /// - public List projects = new List(); + public List Projects = new List(); /// /// List of configuration list, in form "{Configuration}|{Platform}", for example "Release|Win32". @@ -179,6 +195,23 @@ namespace CrowIDE{ } #endregion + public Configuration UserConfig; + + public Project StartupProject { + get { return Projects?.FirstOrDefault (p => p.ProjectGuid == UserConfig.Get ("StartupProject")); } + set { + if (value == StartupProject) + return; + if (value == null) + UserConfig.Set ("StartupProject", ""); + else { + UserConfig.Set ("StartupProject", value.ProjectGuid); + value.NotifyValueChanged("IsStartupProject", true); + } + NotifyValueChanged ("StartupProject", StartupProject); + + } + } #region CTOR /// @@ -227,7 +260,7 @@ namespace CrowIDE{ reProjects.Replace(slnTxt, new MatchEvaluator(m => { - SolutionProject p = new SolutionProject(); + SolutionProject p = new SolutionProject (); foreach (String g in reProjects.GetGroupNames()) { @@ -263,7 +296,7 @@ namespace CrowIDE{ // var ProjectDependencies = new Regex("\\s*?({[A-F0-9-]+}) = ({[A-F0-9-]+})[\r\n]+", RegexOptions.Multiline).Matches(depsv).Cast().Select(x => x.Groups[1].Value).ToList(); } //foreach - s.projects.Add(p); + s.Projects.Add(new Project (s, p)); return ""; } ) @@ -285,7 +318,7 @@ namespace CrowIDE{ String action = m3.Groups[3].Value; String projectConfig = m3.Groups[4].Value; - SolutionProject p = s.projects.Where(x => x.ProjectGuid == guid).FirstOrDefault(); + Project p = s.Projects.Where(x => x.ProjectGuid == guid).FirstOrDefault(); if (p == null) continue; @@ -336,16 +369,18 @@ namespace CrowIDE{ new Regex("\\s*?({[A-F0-9-]+}) = ({[A-F0-9-]+})[\r\n]+", RegexOptions.Multiline).Replace(v, new MatchEvaluator(m5 => { String[] args = m5.Groups.Cast().Skip(1).Select(x => x.Value).ToArray(); - SolutionProject child = s.projects.Where(x => args[0] == x.ProjectGuid).FirstOrDefault(); - SolutionProject parent = s.projects.Where(x => args[1] == x.ProjectGuid).FirstOrDefault(); -// parent.nodes.Add(child); -// child.parent = parent; + Project child = s.Projects.Where(x => args[0] == x.ProjectGuid).FirstOrDefault(); + Project parent = s.Projects.Where(x => args[1] == x.ProjectGuid).FirstOrDefault(); + parent.dependantProjects.Add(child); + child.ParentProject = parent; return ""; })); return ""; } )); + s.UserConfig = new Configuration (s.path + ".user"); + return s; } //LoadSolution #endregion diff --git a/CrowIDE/src/SolutionControler.cs b/CrowIDE/src/SolutionControler.cs new file mode 100644 index 00000000..dec1a8d2 --- /dev/null +++ b/CrowIDE/src/SolutionControler.cs @@ -0,0 +1,37 @@ +// +// SolutionControler.cs +// +// Author: +// Jean-Philippe Bruyère +// +// 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 CrowIDE +{ + public class SolutionControler + { + public SolutionControler () + { + } + } +} + diff --git a/CrowIDE/ui/CrowIDE.crow b/CrowIDE/ui/CrowIDE.crow index d778d9e5..18ffc0c3 100644 --- a/CrowIDE/ui/CrowIDE.crow +++ b/CrowIDE/ui/CrowIDE.crow @@ -31,19 +31,34 @@ - - - + + + + + + + + + + - - - - + + + + + + + + + diff --git a/CrowIDE/ui/EditPaneItems.template b/CrowIDE/ui/EditPaneItems.template index fca1821a..08875ce2 100644 --- a/CrowIDE/ui/EditPaneItems.template +++ b/CrowIDE/ui/EditPaneItems.template @@ -2,6 +2,35 @@ + + + + + + + + + + + + + + + diff --git a/CrowIDE/ui/MembersView.template b/CrowIDE/ui/MembersView.template index 362380e8..d541fe01 100755 --- a/CrowIDE/ui/MembersView.template +++ b/CrowIDE/ui/MembersView.template @@ -1,13 +1,11 @@ - - - - - - - - - + + + + + + + diff --git a/CrowIDE/ui/ProjectTree.template b/CrowIDE/ui/ProjectTree.template index 8ca36b5c..2ec8419a 100644 --- a/CrowIDE/ui/ProjectTree.template +++ b/CrowIDE/ui/ProjectTree.template @@ -3,7 +3,29 @@ - + + + + + + + + + + + + \ No newline at end of file diff --git a/Icons/compiler_error.svg b/Icons/compiler_error.svg new file mode 100644 index 00000000..1b505681 --- /dev/null +++ b/Icons/compiler_error.svg @@ -0,0 +1,13 @@ + + + + Layer 1 + + X + + + Layer 2 + + ! + + \ No newline at end of file diff --git a/Icons/compiler_warning.svg b/Icons/compiler_warning.svg new file mode 100644 index 00000000..9dac3772 --- /dev/null +++ b/Icons/compiler_warning.svg @@ -0,0 +1,53 @@ + + + + + + + + + + + + + + + + + + + + + + + + + image/svg+xml + + 3D effect warning triangle + 18/9/07 + + + Tim O'Ryan + + + + + + + + + + + + + + + + + + + + + + \ No newline at end of file diff --git a/Icons/compiler_warning_orange.svg b/Icons/compiler_warning_orange.svg new file mode 100644 index 00000000..233437ff --- /dev/null +++ b/Icons/compiler_warning_orange.svg @@ -0,0 +1,54 @@ + + + + + + + + + + + + + + + + + + + + + + + + + + image/svg+xml + + 3D effect warning triangle + 18/9/07 + + + Tim O'Ryan + + + + + + + + + + + + + + + + + + + + + + \ No newline at end of file diff --git a/Icons/project.svg b/Icons/project.svg new file mode 100644 index 00000000..1f9a1f1b --- /dev/null +++ b/Icons/project.svg @@ -0,0 +1,9 @@ + + + + + + diff --git a/Icons/projectRef.svg b/Icons/projectRef.svg new file mode 100644 index 00000000..3ebd7b5f --- /dev/null +++ b/Icons/projectRef.svg @@ -0,0 +1,21 @@ + + + + + + + + diff --git a/Icons/warning_construction.svg b/Icons/warning_construction.svg new file mode 100644 index 00000000..4c101ec0 --- /dev/null +++ b/Icons/warning_construction.svg @@ -0,0 +1,60 @@ + + + + + + + + + + + + + + + + + + + + + image/svg+xml + + 3D effect warning triangle + 18/9/07 + + + Tim O'Ryan + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + \ No newline at end of file diff --git a/Templates/ContextMenu.template b/Templates/ContextMenu.template new file mode 100644 index 00000000..3fb29552 --- /dev/null +++ b/Templates/ContextMenu.template @@ -0,0 +1,43 @@ + + + + + + + + + + diff --git a/Templates/Menu.template b/Templates/Menu.template index c560043c..99ae5545 100644 --- a/Templates/Menu.template +++ b/Templates/Menu.template @@ -1,2 +1,2 @@  - + diff --git a/Templates/MenuItem.template b/Templates/MenuItem.template index 0f93b20c..511c5265 100644 --- a/Templates/MenuItem.template +++ b/Templates/MenuItem.template @@ -13,7 +13,7 @@ Background="{./Background}"> diff --git a/Tests/BasicTests.cs b/Tests/BasicTests.cs index a33470b0..9327a112 100644 --- a/Tests/BasicTests.cs +++ b/Tests/BasicTests.cs @@ -47,6 +47,7 @@ namespace Tests string[] testFiles; #region Test values for Binding + public List Commands; public int intValue = 500; DirectoryInfo curDir = new DirectoryInfo (Path.GetDirectoryName(Assembly.GetEntryAssembly().Location)); //DirectoryInfo curDir = new DirectoryInfo (@"/mnt/data/Images"); @@ -135,17 +136,40 @@ namespace Tests void OnLoadList (object sender, MouseButtonEventArgs e) => TestList = Color.ColorDic.Values.ToList(); + void command1(){ + Console.WriteLine("command1 triggered"); + } + void command2(){ + Console.WriteLine("command2 triggered"); + } + void command3(){ + Console.WriteLine("command3 triggered"); + } + void command4(){ + Console.WriteLine("command4 triggered"); + } + protected override void OnLoad (EventArgs e) { base.OnLoad (e); + Commands = new List (new Crow.Command[] { + new Crow.Command(new Action(() => command1())) { Caption = "command1"}, + new Crow.Command(new Action(() => command2())) { Caption = "command2"}, + new Crow.Command(new Action(() => command3())) { Caption = "command3"}, + new Crow.Command(new Action(() => command4())) { Caption = "command4"}, + }); + this.KeyDown += KeyboardKeyDown1; //testFiles = new string [] { @"Interfaces/Unsorted/testFileDialog.crow" }; //testFiles = new string [] { @"Interfaces/Divers/colorPicker.crow" }; //testFiles = new string [] { @"Interfaces/Divers/welcome.crow" }; //testFiles = new string [] { @"Interfaces/TemplatedContainer/testTabView.crow" }; - testFiles = new string [] { @"Interfaces/TemplatedControl/testSpinner.crow" }; + //testFiles = new string [] { @"Interfaces/TemplatedControl/testSpinner.crow" }; + //testFiles = new string [] { @"Interfaces/GraphicObject/testCtxMenu.crow" }; + testFiles = new string [] { @"Interfaces/TemplatedControl/testItemTemplateTag.crow" }; + testFiles = testFiles.Concat (Directory.GetFiles (@"Interfaces/Divers", "*.crow")).ToArray (); testFiles = testFiles.Concat (Directory.GetFiles (@"Interfaces/GraphicObject", "*.crow")).ToArray (); testFiles = testFiles.Concat (Directory.GetFiles (@"Interfaces/Container", "*.crow")).ToArray (); testFiles = testFiles.Concat (Directory.GetFiles (@"Interfaces/Group", "*.crow")).ToArray (); @@ -155,7 +179,6 @@ namespace Tests testFiles = testFiles.Concat (Directory.GetFiles (@"Interfaces/TemplatedGroup", "*.crow")).ToArray (); testFiles = testFiles.Concat (Directory.GetFiles (@"Interfaces/Splitter", "*.crow")).ToArray (); testFiles = testFiles.Concat (Directory.GetFiles (@"Interfaces/Wrapper", "*.crow")).ToArray (); - testFiles = testFiles.Concat (Directory.GetFiles (@"Interfaces/Divers", "*.crow")).ToArray (); testFiles = testFiles.Concat (Directory.GetFiles (@"Interfaces/Unsorted", "*.crow")).ToArray (); Load(testFiles[idx]).DataSource = this; diff --git a/Tests/Interfaces/GraphicObject/testCtxMenu.crow b/Tests/Interfaces/GraphicObject/testCtxMenu.crow new file mode 100755 index 00000000..86ebcf2f --- /dev/null +++ b/Tests/Interfaces/GraphicObject/testCtxMenu.crow @@ -0,0 +1,4 @@ + + \ No newline at end of file diff --git a/Tests/Tests.csproj b/Tests/Tests.csproj index 5016b0ee..fb384de9 100644 --- a/Tests/Tests.csproj +++ b/Tests/Tests.csproj @@ -362,6 +362,9 @@ PreserveNewest + + PreserveNewest + diff --git a/src/Configuration.cs b/src/Configuration.cs index 39c3c9cb..a6b0f0b0 100644 --- a/src/Configuration.cs +++ b/src/Configuration.cs @@ -71,9 +71,9 @@ namespace Crow /// /// ```csharp\n /// //storing\n - /// Configuration.Set ("Option1", 42);\n + /// Configuration.Global.Set ("Option1", 42);\n /// //loading\n - /// int op1 = Configuration.Get ("Option1");\n + /// int op1 = Configuration.Global.Get ("Option1");\n /// ```\n /// /// @@ -82,15 +82,28 @@ namespace Crow /// /// When running the application for the first time, some default options may be necessary. Their can be defined /// in a special embedded resource text file with the key '**appname.default.config**' - public static class Configuration + public class Configuration { - volatile static bool isDirty = false; - static string configPath, configFileName = "app.config"; - static Dictionary items; + volatile bool isDirty = false; + string configPath; + Dictionary items = new Dictionary (); + static Configuration globalConfig; + public static Configuration Global { get { return globalConfig; } } + + public Configuration (string path, Stream defaultConf = null) { + configPath = path; + if (File.Exists (configPath)) { + using (Stream s = new FileStream (configPath, FileMode.Open)) + load (s); + + } else if (defaultConf != null) { + load (defaultConf); + } + startSavingThread (); + } static Configuration () { - items = new Dictionary (); string configRoot = Path.Combine( Environment.GetFolderPath(Environment.SpecialFolder.UserProfile), @@ -98,39 +111,29 @@ namespace Crow Assembly a = Assembly.GetEntryAssembly (); string appName = a.GetName().Name; + string globalConfigPath = Path.Combine (configRoot, appName); - configPath = Path.Combine (configRoot, appName); + if (!Directory.Exists (globalConfigPath)) + Directory.CreateDirectory (globalConfigPath); - if (!Directory.Exists(configPath)) - Directory.CreateDirectory (configPath); + globalConfigPath = Path.Combine (globalConfigPath, "global.config"); - string path = Path.Combine(configPath, configFileName); - - if (File.Exists (path)) { - using (Stream s = new FileStream (path, FileMode.Open)) - load (s); - } else { - string defaultConfigResID = appName + ".default.config"; - bool found = false; - foreach (string resIds in a.GetManifestResourceNames()) { - if (string.Equals (defaultConfigResID, resIds, StringComparison.OrdinalIgnoreCase)) { - using (Stream s = a.GetManifestResourceStream (defaultConfigResID)) - load (s); - found = true; - break; - } + string defaultConfigResID = appName + ".default.config"; + foreach (string resIds in a.GetManifestResourceNames()) { + if (string.Equals (defaultConfigResID, resIds, StringComparison.OrdinalIgnoreCase)) { + using (Stream s = a.GetManifestResourceStream (defaultConfigResID)) + globalConfig = new Configuration (globalConfigPath, s); + return; } - if (!found) - Console.WriteLine ("No Default Config found. ({0})", defaultConfigResID); } - startSavingThread (); + globalConfig = new Configuration (globalConfigPath); } - static void startSavingThread(){ + void startSavingThread(){ Thread t = new Thread (savingThread); t.IsBackground = true; t.Start (); } - static void savingThread(){ + void savingThread(){ while(true){ if (isDirty) { save (); @@ -143,7 +146,7 @@ namespace Crow /// retrive the value of the configuration key given in parameter /// /// option name - public static T Get(string key) + public T Get(string key) { return !items.ContainsKey (key) ? default(T) : items [key].GetValue (); } @@ -152,7 +155,7 @@ namespace Crow /// /// option name /// value for that option - public static void Set(string key, T value) + public void Set(string key, T value) { if (!items.ContainsKey (key)) { lock(items) @@ -161,8 +164,8 @@ namespace Crow items[key].Set (value); isDirty = true; } - static void save(){ - using (Stream s = new FileStream(Path.Combine(configPath, configFileName),FileMode.Create)){ + void save(){ + using (Stream s = new FileStream(configPath,FileMode.Create)){ using (StreamWriter sw = new StreamWriter (s)) { lock (items) { foreach (string key in items.Keys) { @@ -172,7 +175,7 @@ namespace Crow } } } - static void load(Stream s){ + void load(Stream s){ using (StreamReader sr = new StreamReader (s)) { while (!sr.EndOfStream) { string l = sr.ReadLine(); diff --git a/src/GraphicObjects/GraphicObject.cs b/src/GraphicObjects/GraphicObject.cs index ad02a544..ad9392b0 100644 --- a/src/GraphicObjects/GraphicObject.cs +++ b/src/GraphicObjects/GraphicObject.cs @@ -190,7 +190,8 @@ namespace Crow bool isDragged; bool allowDrag; bool allowDrop; - + string tooltip; + IList contextCommands; #endregion #region public fields @@ -764,7 +765,7 @@ namespace Crow /// Seek first logical tree upward if logicalParent is set, or seek graphic tree for /// a not null dataSource that will be active for all descendants having dataSource=null /// - [XmlAttributeAttribute][DefaultValue(null)] + [XmlAttributeAttribute]//[DefaultValue(null)] public virtual object DataSource { set { if (DataSource == value) @@ -774,6 +775,10 @@ namespace Crow dataSource = value; dse.NewDataSource = DataSource; + //prevent setting null causing stack overflow in specific case + if (dse.NewDataSource == dse.OldDataSource) + return; + OnDataSourceChanged (this, dse); NotifyValueChanged ("DataSource", DataSource); @@ -813,7 +818,6 @@ namespace Crow NotifyValueChanged ("Style", style); } } - string tooltip; [XmlAttributeAttribute] public virtual string Tooltip { get { return tooltip; } @@ -824,6 +828,16 @@ namespace Crow NotifyValueChanged("Tooltip", tooltip); } } + [XmlAttributeAttribute] + public IList ContextCommands { + get { return contextCommands; } + set { + if (contextCommands == value) + return; + contextCommands = value; + NotifyValueChanged("ContextCommands", contextCommands); + } + } #endregion #region Default and Style Values loading @@ -1499,24 +1513,45 @@ namespace Crow #endregion #region Mouse handling + public virtual bool PointIsIn(ref Point m) + { + if (!(Visible & isEnabled)||IsDragged) + return false; + ILayoutable tmp = Parent; + //while (tmp != null){ + if (!parent.PointIsIn(ref m)) + return false; + m -= (parent.getSlot().Position + parent.ClientRectangle.Position) ; + + return Slot.ContainsOrIsEqual (m); + } public virtual bool MouseIsIn(Point m) { - try { - if (!(Visible & isEnabled)||IsDragged) - return false; - if (ScreenCoordinates (Slot).ContainsOrIsEqual (m)) { - Scroller scr = Parent as Scroller; - if (scr == null) { - if (Parent is GraphicObject) - return (Parent as GraphicObject).MouseIsIn (m); - else return true; - } - return scr.MouseIsIn (scr.savedMousePos); - } - } catch (Exception ex) { - return false; - } - return false; + Point p = m; + return PointIsIn (ref m); +// try { +// if (!(Visible & isEnabled)||IsDragged) +// return false; +// ILayoutable tmp = Parent; +// //while (tmp != null){ +// if (!parent.MouseIsIn(m)) +// return false; +// m -= (parent.getSlot().Position + parent.ClientRectangle.Position) ; +// +// return slot.ContainsOrIsEqual (m); +//// Scroller scr = tmp as Scroller; +//// if (scr != null) { +//// m.Y += scr.ScrollY; +//// m.X += scr.ScrollX; +//// } +//// tmp = tmp.Parent; +// //} +// +// //} +// } catch (Exception ex) { +// return false; +// } + //return false; } public virtual void checkHoverWidget(MouseMoveEventArgs e) { @@ -1525,7 +1560,7 @@ namespace Crow onMouseEnter (this, e); } - this.onMouseMove (this, e);//without this, window border doesn't work, should be removed + //this.onMouseMove (this, e);//without this, window border doesn't work, should be removed } public virtual void onMouseMove(object sender, MouseMoveEventArgs e) { @@ -1553,6 +1588,8 @@ namespace Crow if (be.Focused == null) { be.Focused = this; CurrentInterface.FocusedWidget = this; + if (e.Button == MouseButton.Right && this.ContextCommands != null) + CurrentInterface.ShowContextMenu (this); } } //bubble event to the top diff --git a/src/GraphicObjects/Group.cs b/src/GraphicObjects/Group.cs index c944eba2..3802a4d9 100644 --- a/src/GraphicObjects/Group.cs +++ b/src/GraphicObjects/Group.cs @@ -147,7 +147,7 @@ namespace Crow lock (children) { foreach (GraphicObject g in children) if (g.localDataSourceIsNull & g.localLogicalParentIsNull) - g.OnDataSourceChanged (sender, e); + g.OnDataSourceChanged (g, e); } } public override GraphicObject FindByName (string nameToFind) diff --git a/src/GraphicObjects/ILayoutable.cs b/src/GraphicObjects/ILayoutable.cs index c0c1cf5c..c8aa38fb 100644 --- a/src/GraphicObjects/ILayoutable.cs +++ b/src/GraphicObjects/ILayoutable.cs @@ -45,7 +45,7 @@ namespace Crow void RegisterForLayouting(LayoutingType layoutType); void RegisterClip(Rectangle clip); bool UpdateLayout(LayoutingType layoutType); - + bool PointIsIn(ref Point m); Rectangle ContextCoordinates(Rectangle r); Rectangle ScreenCoordinates (Rectangle r); diff --git a/src/GraphicObjects/MenuItem.cs b/src/GraphicObjects/MenuItem.cs index ae27b013..5c9665fb 100644 --- a/src/GraphicObjects/MenuItem.cs +++ b/src/GraphicObjects/MenuItem.cs @@ -40,7 +40,6 @@ namespace Crow public event EventHandler Open; public event EventHandler Close; - string caption; Command command; Picture icon; bool isOpened; @@ -58,7 +57,8 @@ namespace Crow if (isOpened) { onOpen (this, null); - (LogicalParent as Menu).AutomaticOpenning = true; + if (LogicalParent is Menu) + (LogicalParent as Menu).AutomaticOpenning = true; }else onClose (this, null); } @@ -143,8 +143,10 @@ namespace Crow } void onMI_Click (object sender, MouseButtonEventArgs e) { - if (command != null) + if (command != null) { command.Execute (); + closeMenu (); + } if(!IsOpened) (LogicalParent as Menu).AutomaticOpenning = false; } @@ -152,6 +154,7 @@ namespace Crow Open.Raise (this, null); } protected virtual void onClose (object sender, EventArgs e){ + System.Diagnostics.Debug.WriteLine ("close: " + this.ToString()); Close.Raise (this, null); } public override bool MouseIsIn (Point m) @@ -170,6 +173,14 @@ namespace Crow IsOpened = false; base.onMouseLeave (this, e); } + + void closeMenu () { + MenuItem tmp = LogicalParent as MenuItem; + while (tmp != null) { + tmp.IsOpened = false; + tmp = tmp.LogicalParent as MenuItem; + } + } } } diff --git a/src/GraphicObjects/Popper.cs b/src/GraphicObjects/Popper.cs index 41210dc5..be4a19b8 100644 --- a/src/GraphicObjects/Popper.cs +++ b/src/GraphicObjects/Popper.cs @@ -192,6 +192,12 @@ namespace Crow base.onMouseLeave (this, e); IsPopped = false; } +// public override bool PointIsIn (ref Point m) +// { +// if (!base.PointIsIn (ref m)) +// return false; +// +// } public override bool MouseIsIn (Point m) { bool isInContent = false; diff --git a/src/GraphicObjects/PrivateContainer.cs b/src/GraphicObjects/PrivateContainer.cs index e76b57a8..8383a274 100644 --- a/src/GraphicObjects/PrivateContainer.cs +++ b/src/GraphicObjects/PrivateContainer.cs @@ -92,7 +92,7 @@ namespace Crow base.OnDataSourceChanged (this, e); if (child != null) if (child.localDataSourceIsNull & child.localLogicalParentIsNull) - child.OnDataSourceChanged (sender, e); + child.OnDataSourceChanged (child, e); } public override bool UpdateLayout (LayoutingType layoutType) { diff --git a/src/GraphicObjects/Scroller.cs b/src/GraphicObjects/Scroller.cs index ec3bc47d..a4e1b816 100644 --- a/src/GraphicObjects/Scroller.cs +++ b/src/GraphicObjects/Scroller.cs @@ -219,17 +219,39 @@ namespace Crow } #region Mouse handling - internal Point savedMousePos; - public override bool MouseIsIn (Point m) - { - return Visible ? base.ScreenCoordinates(Slot).ContainsOrIsEqual (m) : false; - } - public override void checkHoverWidget (MouseMoveEventArgs e) + //internal Point savedMousePos; + + public override bool PointIsIn (ref Point m) { - savedMousePos = e.Position; - Point m = e.Position - new Point (ScrollX, ScrollY); - base.checkHoverWidget (new MouseMoveEventArgs(m.X,m.Y,e.XDelta,e.YDelta)); +// if (!(Visible & IsEnabled)||IsDragged) +// return false; +// ILayoutable tmp = Parent; +// //while (tmp != null){ +// if (!Parent.PointIsIn(ref m)) +// return false; +// m -= (Parent.getSlot().Position + Parent.ClientRectangle.Position); +// if (!Slot.ContainsOrIsEqual (m) || child==null) +// return false; +// m += new Point (ScrollX, ScrollY); +// return true; + if (!base.PointIsIn(ref m)) + return false; + //m -= (Parent.getSlot().Position + Parent.ClientRectangle.Position); + if (!Slot.ContainsOrIsEqual (m) || child==null) + return false; + m += new Point (ScrollX, ScrollY); + return true; } +// public override bool MouseIsIn (Point m) +// { +// return Visible ? base.ScreenCoordinates(Slot).ContainsOrIsEqual (m) : false; +// } +// public override void checkHoverWidget (MouseMoveEventArgs e) +// { +// savedMousePos = e.Position; +// Point m = e.Position - new Point (ScrollX, ScrollY); +// base.checkHoverWidget (new MouseMoveEventArgs(m.X,m.Y,e.XDelta,e.YDelta)); +// } public override void onMouseWheel (object sender, MouseWheelEventArgs e) { if (Child == null) @@ -240,12 +262,12 @@ namespace Crow if (HorizontalScrolling ) ScrollX -= e.Delta * ScrollSpeed; } - public override void onMouseMove (object sender, MouseMoveEventArgs e) - { - savedMousePos.X += e.XDelta; - savedMousePos.Y += e.YDelta; - base.onMouseMove (sender, new MouseMoveEventArgs(savedMousePos.X,savedMousePos.Y,e.XDelta,e.YDelta)); - } +// public override void onMouseMove (object sender, MouseMoveEventArgs e) +// { +// savedMousePos.X += e.XDelta; +// savedMousePos.Y += e.YDelta; +// base.onMouseMove (sender, new MouseMoveEventArgs(savedMousePos.X,savedMousePos.Y,e.XDelta,e.YDelta)); +// } public override void RegisterClip (Rectangle clip) { base.RegisterClip (clip - new Point(ScrollX,ScrollY)); diff --git a/src/GraphicObjects/TemplatedContainer.cs b/src/GraphicObjects/TemplatedContainer.cs index 31bbc436..3e0dd801 100644 --- a/src/GraphicObjects/TemplatedContainer.cs +++ b/src/GraphicObjects/TemplatedContainer.cs @@ -77,12 +77,11 @@ namespace Crow } public override bool Contains (GraphicObject goToFind) { - if (Content == null) - return base.Contains (goToFind); - if (Content == goToFind) return true; - return Content.Contains (goToFind); + if (Content?.Contains (goToFind) == true) + return true; + return base.Contains (goToFind); } #endregion } diff --git a/src/GraphicObjects/TemplatedGroup.cs b/src/GraphicObjects/TemplatedGroup.cs index 069303dd..ef099f93 100644 --- a/src/GraphicObjects/TemplatedGroup.cs +++ b/src/GraphicObjects/TemplatedGroup.cs @@ -344,7 +344,9 @@ namespace Crow #endif Group page; - if (typeof(TabView).IsAssignableFrom (items.GetType ())||typeof(Wrapper).IsAssignableFrom (items.GetType ())) { + if (typeof(TabView).IsAssignableFrom (items.GetType ())|| + typeof(Menu).IsAssignableFrom (this.GetType())|| + typeof(Wrapper).IsAssignableFrom (items.GetType ())) { page = items; itemPerPage = int.MaxValue; } else if (typeof(GenericStack).IsAssignableFrom (items.GetType ())) { @@ -425,7 +427,8 @@ namespace Crow lock (CurrentInterface.LayoutMutex) { g = iTemp.CreateInstance(CurrentInterface); page.AddChild (g); - //g.LogicalParent = this; +// if (isPaged) +// g.LogicalParent = this; registerItemClick (g); } diff --git a/src/IML/NodeAddress.cs b/src/IML/NodeAddress.cs index b9f8b902..450a9d2d 100644 --- a/src/IML/NodeAddress.cs +++ b/src/IML/NodeAddress.cs @@ -54,18 +54,21 @@ namespace Crow.IML if (splitedExp.Length < 2)//dataSource binding return null; - if (string.IsNullOrEmpty (splitedExp [0]) || splitedExp [0] == ".") {//search template root - ptr--; - while (ptr >= 0) { - if (typeof(TemplatedControl).IsAssignableFrom (this [ptr].CrowType)) - break; + if (!string.IsNullOrEmpty (splitedExp [0])) {//else bind on current node + //return new NodeAddress (this.Take(ptr+1).ToArray()); + if (splitedExp [0] == ".") {//search template root ptr--; + while (ptr >= 0) { + if (typeof(TemplatedControl).IsAssignableFrom (this [ptr].CrowType)) + break; + ptr--; + } + } else if (splitedExp [0] == "..") { //search starting at current node + int levelUp = splitedExp.Length - 1; + if (levelUp > ptr + 1) + throw new Exception ("Binding error: try to bind outside IML source"); + ptr -= levelUp; } - } else if (splitedExp [0] == "..") { //search starting at current node - int levelUp = splitedExp.Length - 1; - if (levelUp > ptr + 1) - throw new Exception ("Binding error: try to bind outside IML source"); - ptr -= levelUp; } expression = splitedExp [splitedExp.Length - 1]; //TODO:change Template special address identified with Nodecount = 0 to something not using array count to 0, diff --git a/src/Input/MouseEventArgs.cs b/src/Input/MouseEventArgs.cs index e1f7ae2a..cf883f13 100644 --- a/src/Input/MouseEventArgs.cs +++ b/src/Input/MouseEventArgs.cs @@ -257,6 +257,12 @@ namespace Crow this.IsPressed = pressed; } + public MouseButtonEventArgs(MouseButton button) + : base() + { + this.button = button; + } + /// /// Constructs a new instance. /// diff --git a/src/Interface.cs b/src/Interface.cs index 03ea9308..0393fbc8 100644 --- a/src/Interface.cs +++ b/src/Interface.cs @@ -75,6 +75,15 @@ namespace Crow if (!Directory.Exists (CrowConfigRoot)) Directory.CreateDirectory (CrowConfigRoot); + //ensure all assemblies are loaded, because IML could contains classes not instanciated in source +// foreach (string af in Directory.GetFiles (AppDomain.CurrentDomain.BaseDirectory, "*.dll")){ +// try { +// Assembly.LoadFrom (af); +// } catch (Exception ex) { +// Console.WriteLine ("{0} not loaded as assembly.", af); +// } +// } + loadCursors (); findAvailableTemplates (); @@ -89,6 +98,7 @@ namespace Crow CultureInfo.DefaultThreadCurrentCulture = System.Globalization.CultureInfo.InvariantCulture; loadStyling (); initTooltip (); + initContextMenus (); } #endregion @@ -676,6 +686,12 @@ namespace Crow /// Set visible state of widget to false and remove if from the graphic tree public void RemoveWidget(GraphicObject g) { + if (g.Contains(HoverWidget)) { + while (HoverWidget != g.LogicalParent) { + HoverWidget.onMouseLeave (HoverWidget, null); + HoverWidget = HoverWidget.LogicalParent as GraphicObject; + } + } lock (UpdateMutex) { RegisterClip (g.ScreenCoordinates (g.LastPaintedSlot)); GraphicTree.Remove (g); @@ -861,7 +877,7 @@ namespace Crow public bool ProcessMouseButtonUp(int button) { Mouse.DisableBit (button); - MouseButtonEventArgs e = new MouseButtonEventArgs () { Mouse = Mouse }; + MouseButtonEventArgs e = new MouseButtonEventArgs ((Crow.MouseButton)button) { Mouse = Mouse }; if (_activeWidget == null) return false; @@ -888,7 +904,7 @@ namespace Crow public bool ProcessMouseButtonDown(int button) { Mouse.EnableBit (button); - MouseButtonEventArgs e = new MouseButtonEventArgs () { Mouse = Mouse }; + MouseButtonEventArgs e = new MouseButtonEventArgs ((Crow.MouseButton)button) { Mouse = Mouse }; if (HoverWidget == null) return false; @@ -1016,6 +1032,31 @@ namespace Crow } #endregion + #region Contextual menu + MenuItem ctxMenuContainer; + void initContextMenus (){ + ctxMenuContainer = Load ("#Crow.ContextMenu.template") as MenuItem; + } + + public void ShowContextMenu (GraphicObject go) { + + if (ctxMenuContainer.Parent == null) + this.AddWidget (ctxMenuContainer); + else + ctxMenuContainer.IsOpened = true; + + ctxMenuContainer.LogicalParent = go; + ctxMenuContainer.DataSource = go; + + PutOnTop (ctxMenuContainer, true); + ctxMenuContainer.Left = Mouse.X - 5; + ctxMenuContainer.Top = Mouse.Y - 5; + + HoverWidget = ctxMenuContainer; + ctxMenuContainer.onMouseEnter (ctxMenuContainer, new MouseMoveEventArgs (Mouse.X, Mouse.Y, 0, 0)); + } + #endregion + #region Device Repeat Events volatile bool mouseRepeatOn, keyboardRepeatOn; volatile int mouseRepeatCount, keyboardRepeatCount; @@ -1044,6 +1085,10 @@ namespace Crow #endregion #region ILayoutable implementation + public virtual bool PointIsIn(ref Point m) + { + return true; + } public void RegisterClip(Rectangle r){ clipping.UnionRectangle (r); }