]> O.S.I.I.S - jp/crow.git/commitdiff
save commit, BubbleEvents, iface.search type and ext meth for loadCtx wise searches...
authorJean-Philippe Bruyère <jp_bruyere@hotmail.com>
Sat, 18 Sep 2021 09:22:04 +0000 (09:22 +0000)
committerJean-Philippe Bruyère <jp_bruyere@hotmail.com>
Sat, 18 Sep 2021 09:22:04 +0000 (09:22 +0000)
39 files changed:
Crow/Default.style
Crow/Templates/Button.template
Crow/Templates/CheckBox2.template
Crow/Templates/ContextMenu.template
Crow/Templates/FileDialog.template
Crow/Templates/MenuButton.template
Crow/Templates/MenuItem.itmp
Crow/Templates/MenuItem.template
Crow/Templates/Popper.template
Crow/src/Colors.cs
Crow/src/DebugUtils/DbgEvent.cs
Crow/src/DebugUtils/DbgEvtType.cs
Crow/src/DebugUtils/DbgWidgetEvent.cs
Crow/src/DebugUtils/DebugLogger.cs
Crow/src/IML/CompilerServices.cs
Crow/src/IML/Instantiator.cs
Crow/src/Input/KeyPressEventArgs.cs
Crow/src/Interface.cs
Crow/src/ItemTemplate.cs
Crow/src/Text/SpanCharReader.cs
Crow/src/Widgets/Expandable.cs
Crow/src/Widgets/FileDialog.cs
Crow/src/Widgets/MenuItem.cs
Crow/src/Widgets/TemplatedGroup.cs
Crow/src/Widgets/Widget.cs
Crow/src/styling/StyleReader.cs
Directory.Build.props
README.md
Samples/HelloWorld/main.cs
Samples/HelloWorld/ui/helloworld.crow
Samples/ShowCase/ShowCase.cs
Samples/ShowCase/ui/Button.template
Samples/ShowCase/ui/showcase.crow
Samples/common/src/Editor.cs
Samples/common/src/SampleBase.cs
Samples/common/src/SampleBaseForEditor.cs
Samples/common/ui/Interfaces/Experimental/buttonSizing.crow [new file with mode: 0644]
Samples/common/ui/Interfaces/Experimental/enumSelector2.crow [new file with mode: 0644]
Samples/common/ui/Interfaces/Experimental/fileDialog.crow [new file with mode: 0644]

index c2b17b4b78bbbad2cecb86f55fac40674fc4dabe..181ed47b242ac54acad67a51ab012e2ff10b9350 100644 (file)
@@ -100,8 +100,9 @@ Wrapper {
 }
 Button {
        Template = "#Crow.Button.template";
+       //Focusable     = "true";
        Caption         = "Button";
-       MinimumSize = "50,22";
+       MinimumSize = "60,22";
        Height          = "Fit";
        Width           = "Fit";
 }
@@ -163,6 +164,7 @@ ListItem {
        //Selected = "{Background=${ControlHighlight}}";
        //Unselected = "{Background=Transparent}";
        //Margin="1";
+       Focusable = "true";
 }
 MessageBox {
        Background = "0.1,0.1,0.2,0.85";
@@ -362,13 +364,13 @@ TableHeaderLabel {
 
 Button, CheckBox, RadioButton, ComboBox, Expandable,
 MessageBox, Popper, Slider, Spinner, TextBox, NumericControl {
-       //Focusable = "true";
+       Focusable = "true";
        Foreground="${ControlForeground}";
        Height = "Fit";
        Background = "${ControlBackground}";
        CornerRadius = "${ControlCornerRadius}";
        Margin="0";
-       BubbleMouseEvent="MouseWheel|Keyboard";
+       BubbleEvents="MouseWheel|Keyboard";
 }
 TemplatedControl, GenericStack {
        CacheEnabled="true";
index 9ad621d968077558e297b9045b0e850ee922dc6f..6627021e1deefe73c12267dd5a692994a06e1dae 100644 (file)
@@ -1,4 +1,4 @@
 <?xml version="1.0"?>
-<Border Style="ButtonBorder" Background="{./Background}" Name="Content" CornerRadius="{../CornerRadius}" >
+<Border Style="ButtonBorder" Background="{./Background}" Name="Content" CornerRadius="{../CornerRadius}" Width="Stretched" Height="Stretched" >
        <Label Font="{./Font}" Name="caption" Margin="${ButtonCaptionMargin}" Foreground="{./Foreground}" Text="{./Caption}"/>
 </Border>
index 0fa0ffefb8011dc114559361ca576d4245188871..68afd0bfa5d83db273bd75a04e27e819f526548e 100644 (file)
@@ -1,7 +1,5 @@
-<Border Foreground="Transparent" MouseEnter="{Foreground=Grey}" MouseLeave="{Foreground=Transparent}">
-       <Label Font="{./Font}" Text="{./Caption}"
-               Margin="1"
-               Background="{./Background}"
-               Foreground="{./Foreground}"
-               TextAlignment="Center"/>
-</Border>
\ No newline at end of file
+<Label Font="{./Font}" Text="{./Caption}" CornerRadius="{./CornerRadius}" Width="Stretched"
+       Margin="3"
+       Background="{./Background}"
+       Foreground="{./Foreground}"
+       TextAlignment="Center"/>
\ No newline at end of file
index 2d41ffbf11e2fd73a3111ad1835b58005f0be519..54df383c308097bf8a95ead9db59d90e040fe7d6 100644 (file)
@@ -3,8 +3,8 @@
                Orientation="Vertical"
                IsOpened ="true" IsVisible="{/IsOpened}"
                ItemTemplate="#Crow.MenuItem.itmp">
-       <Template>              
-               <GenericStack Orientation="{./Orientation}" Name="ItemsContainer" Margin="0" Background="${MenuBackground}"/>           
+       <Template>
+               <GenericStack Orientation="{./Orientation}" Name="ItemsContainer" Margin="0" Background="${MenuBackground}"/>
        </Template>
 </MenuItem>
 
index a349905a3293e8ee6f28026a4bd71eb594947997..71ed5c2b6619ca66b05524ab57e5c411e879c846 100644 (file)
@@ -33,7 +33,7 @@
                                                                                        Name="ItemsContainer" Margin="0" Spacing="1"/>
                                                                        </Scroller>
                                                                        <ScrollBar Name="scrollbar1" Orientation="Vertical"
-                                                                               Value="{²../scroller1.ScrollY}"        Maximum="{../scroller1.MaxScrollY}" 
+                                                                               Value="{²../scroller1.ScrollY}"        Maximum="{../scroller1.MaxScrollY}"
                                                                                CursorRatio="{../scroller1.ChildHeightRatio}"
                                                                                LargeIncrement="{../scroller1.PageHeight}" SmallIncrement="30"
                                                                                Width="14" />
@@ -51,8 +51,8 @@
                                        <CheckBox Style="CheckBoxAlt" Name="cbShowHidden" Caption="Show Hidden" IsChecked="{²./ShowHidden}"/>
                                </HorizontalStack>
                                <HorizontalStack Fit="true" HorizontalAlignment="Right" Margin="3" Spacing="3">
-                                       <Button Caption="Ok" MouseClick="./onFileSelect"/>
-                                       <Button Caption="Cancel" MouseClick="./onCancel"/>
+                                       <Button Caption="Ok" Command="{./CMDOk}"/>
+                                       <Button Caption="Cancel" Command="{./CMDCancel}"/>
                                </HorizontalStack>
                        </VerticalStack>
                </Container>
index abc3ff2c9f3994b00ef7161b6a21b67f3664852e..8025954b3879b6480fd6bf051104951b18b24637 100644 (file)
@@ -1,5 +1,5 @@
 <?xml version="1.0"?>
-<Button Command="{}" Width="Stretched">
+<Button Command="{}" Width="Stretched" BubbleEvents="All">
        <Template>
                <Label Text="{./Caption}" Width="Stretched" Height="Stretched" Margin="3"
                                                MouseEnter="{Background=${ControlHighlight}}"
index 7bbf27657bcd753691abba793fd8eb8c12b41e0d..b1d062ab2ad5c75f3953bdffeea89d97d9926da7 100644 (file)
@@ -2,6 +2,7 @@
 <ItemTemplate DataType="Crow.Command" Path="#Crow.MenuButton.template"/>
 <ItemTemplate DataType="Crow.CommandGroup" Data="Commands">
        <Popper PopDirection="Right" Caption="{Caption}" IsEnabled="{CanExecute}" Width="Stretched"
+                       BubbleEvents="All"
                        MouseEnter="{Background=${ControlHighlight}}"
                        MouseLeave="{Background=Transparent}">
                <Template>
@@ -9,7 +10,7 @@
                                <Label Text="{./Caption}"   Width="Fit" Height="Stretched"/>
                                <Label Text="..."/>
                        </HorizontalStack>
-               </Template>             
+               </Template>
                <VerticalStack Margin="0" Name="ItemsContainer" Fit="true" Background="${MenuBackground}"/>
        </Popper>
 </ItemTemplate>
index 4945b009f4c3e80893dcde5575734316a11f3d6c..4075be945b3caf9b08c9b00782aa5ba1483b6594 100644 (file)
@@ -1,7 +1,7 @@
 <?xml version="1.0"?>
 <ListItem>
        <Popper Font="{./Font}" Caption="{./Caption}"  Background="{./Background}" PopDirection="{./PopDirection}"
-               Foreground = "{./Foreground}" BubbleMouseEvent="All"
+               Foreground = "{./Foreground}" BubbleEvents="All"
                IsPopped="{²./IsOpened}" PopWidth="{./PopWidth}" PopHeight="{./PopHeight}">
                <Template>
                        
index 2a0a0de5ceca796030f219e0d7dcc4692e5761ff..6f3b84402750b296cda3ee35dc24899670c4983e 100644 (file)
@@ -1,8 +1,8 @@
 <?xml version="1.0"?>
 <Border Style="ControlBorder" Background="{./Background}" CornerRadius="{./CornerRadius}">
        <HorizontalStack Spacing="1">
-               <Image Style="Icon" 
-                       MouseEnter="{Background=White}" MouseLeave="{Background=Transparent}"                                   
+               <Image Style="Icon"
+                       MouseEnter="{Background=White}" MouseLeave="{Background=Transparent}"
                        Path="#Crow.Icons.expandable.svg" SvgSub="{./IsPopped}"/>
                <Label Style="ControlCaption" Text="{./Caption}" Foreground="{./Foreground}"/>
        </HorizontalStack>
index 323cba2e3ec5c6e0fd561405bf416eff857e67d8..d24f5e94246052164649042faeb046c9e991c617 100644 (file)
@@ -327,18 +327,18 @@ namespace Crow
                        => value == (UInt32)other;*/
 
                public bool Equals (Color other)
-                       => value == other.value;                
+                       => value == other.value;
                public override int GetHashCode ()
                        => value.GetHashCode ();
 
                public override string ToString()
                        => EnumsNET.Enums.IsValid<Colors> ((Colors)value) ? EnumsNET.Enums.GetName((Colors)value) : HtmlCode;
-                       
+
                public static Color FromIml (string iml)
                {
                        Span<double> components = stackalloc double[4];
                        components[3] = 1;//init alpha to 1 so that it can be ommitted
-                       ReadOnlySpan<char> c = iml.AsSpan ();                   
+                       ReadOnlySpan<char> c = iml.AsSpan ();
                        int i = 0;
                        int ioc = c.IndexOf (',');
 
@@ -347,7 +347,7 @@ namespace Crow
                                c = c.Slice (ioc + 1);
                                ioc = c.IndexOf (',');
                        }
-                       components[i++] = double.Parse (c);                     
+                       components[i++] = double.Parse (c);
                        return new Color (components);
                }
 
index 1b6144f2626f02dfc166b4942fee9bb0ed3465a8..e3144d9011ab018f92b9cd4f461a867329c81e43 100644 (file)
@@ -50,7 +50,7 @@ namespace Crow.DebugLogger
                                return null;
                        string [] tmp = str.Trim ().Split (';', StringSplitOptions.None);
 
-                       DbgEvtType evtType = (DbgEvtType)Enum.Parse (typeof (DbgEvtType), tmp [3]);                     
+                       DbgEvtType evtType = (DbgEvtType)Enum.Parse (typeof (DbgEvtType), tmp [3]);
 
                        if (evtType.HasFlag (DbgEvtType.Widget)) {
                                if (evtType.HasFlag (DbgEvtType.Layouting))
@@ -109,13 +109,13 @@ namespace Crow.DebugLogger
                                case DbgEvtType.Update:
                                        return Colors.Grey;
                                case DbgEvtType.IFaceLoad:
-                                       return Colors.Teal;                             
+                                       return Colors.Teal;
                                default:
                                        if (type.HasFlag(DbgEvtType.Mouse))
                                                return Colors.DeepPink;
                                        return Colors.White;
                                }
                        }
-               }               
+               }
        }
 }
\ No newline at end of file
index 4acd1d27be6a4c8efd17feca6c1baf5d504ea27f..dff68490c25545da549af31a41c60c070f88d65c 100644 (file)
@@ -9,25 +9,25 @@ namespace Crow
        [Flags]
        public enum DbgEvtType : Int32 {
                None                                                    = 0,
-               IFace                                                   = 0x40000000,
-               Widget                                                  = 0x20000000,
+               IFace                                                   = 0x00000100,
+               Widget                                                  = 0x00000200,
 
-               Warning                                                 = 0x10000000,
-               Error                                                   = 0x08000000,
+               Warning                                                 = 0x00000400,
+               Error                                                   = 0x00000800,
 
-               Binding                                                 = 0x800000,
-               Lock                                                    = 0x400000,
-               Layouting                                               = 0x200000,
-               Clipping                                                = 0x100000,
-               Drawing                                                 = 0x080000,
+               Binding                                                 = 0x00001000,
+               Lock                                                    = 0x00002000,
+               Layouting                                               = 0x00004000,
+               Clipping                                                = 0x00008000,
+               Drawing                                                 = 0x00010000,
 
-               Focus                                                   = 0x040000,
-               Override                                                = 0x020000,
-               TemplatedGroup                                  = 0x010000,
-               Dispose                                                 = 0x008000,
-               Mouse                                                   = 0x004000,
+               Focus                                                   = 0x00020000,
+               Override                                                = 0x00040000,
+               TemplatedGroup                                  = 0x00080000,
+               Dispose                                                 = 0x00100000,
+               Mouse                                                   = 0x00200000,
 
-               Update                                                  = IFace | 0x004000,
+               Update                                                  = IFace | 0x00100000,
                ProcessLayouting                                = IFace | Update | Lock | Layouting,
                ClippingRegistration                    = IFace | Update | Lock | Clipping,
                ProcessDrawing                                  = IFace | Update | Lock | Drawing,
@@ -90,9 +90,14 @@ namespace Crow
                MouseDown                                               = IFace | Mouse | 0x01,
                MouseUp                                                 = IFace | Mouse | 0x02,
                MouseMove                                               = IFace | Mouse | 0x03,
-               GOMouseDown                                             = Widget | Mouse | 0x01,
-               GOMouseUp                                               = Widget | Mouse | 0x02,
-               GOMouseMove                                             = Widget | Mouse | 0x03,
+               MouseEnter                                              = Widget | Mouse | 0x01,
+               MouseLeave                                              = Widget | Mouse | 0x02,
+               WidgetMouseMove                                 = Widget | Mouse | 0x03,
+               WidgetMouseDown                                 = Widget | Mouse | 0x04,
+               WidgetMouseUp                                   = Widget | Mouse | 0x05,
+               WidgetMouseWheel                                = Widget | Mouse | 0x06,
+               WidgetMouseClick                                = Widget | Mouse | 0x07,
+               WidgetMouseDblClick                             = Widget | Mouse | 0x08,
 
                All = 0x7FFFFF00
        }
index d147ba252548d920d4d4ad4752a3a1edd2416140..cf61a79beb15e2c6829d496e9c95ebd938757037 100644 (file)
@@ -6,7 +6,7 @@ using System.Collections.Generic;
 using System.Threading;
 
 namespace Crow.DebugLogger
-{      
+{
        public class DbgWidgetEvent : DbgEvent
        {
                public int InstanceIndex;
@@ -17,7 +17,7 @@ namespace Crow.DebugLogger
                        InstanceIndex = widgetInstanceIndex;
                }
                //public override string Print() => $"{base.Print()}:{InstanceIndex}"
-               
+
         public override string ToString ()
                        => $"{base.ToString ()};{InstanceIndex}";
                public override Color Color {
@@ -76,6 +76,6 @@ namespace Crow.DebugLogger
                                        return Colors.White;
                                }
                        }
-               }                       
-       }       
+               }
+       }
 }
\ No newline at end of file
index b84077a64b632b0a256b48da5be6bd2f7c72b262..d549e19d31962c8d7c8897c65215b146a0df488a 100644 (file)
@@ -1,8 +1,7 @@
-using System.Text;
-// Copyright (c) 2013-2021  Jean-Philippe Bruyère <jp_bruyere@hotmail.com>
+// Copyright (c) 2013-2021  Jean-Philippe Bruyère <jp_bruyere@hotmail.com>
 //
 // This code is licensed under the MIT license (MIT) (http://opensource.org/licenses/MIT)
-
+using System.Text;
 using System;
 using System.Collections.Generic;
 using System.Diagnostics;
@@ -16,18 +15,21 @@ namespace Crow
 {
        public static class DbgLogger
        {
-               public static DbgEvtType IncludeEvents = DbgEvtType.All;
-               public static DbgEvtType DiscardEvents = DbgEvtType.Focus;
+               /*public static DbgEvtType IncludeEvents = DbgEvtType.All;
+               public static DbgEvtType DiscardEvents = DbgEvtType.Focus;*/
+
+               public static List<DbgEvtType> IncludedEvents = new List<DbgEvtType> ();
                public static bool ConsoleOutput = true;
 
 
 #if DEBUG_LOG
-               static bool logevt (DbgEvtType evtType)
-                       //=> IncludeEvents != DbgEvtType.None && (evtType & DiscardEvents) == 0 && (evtType & IncludeEvents) == IncludeEvents;
-                       //=> IncludeEvents != DbgEvtType.None && (evtType & DiscardEvents) == 0 && (evtType & IncludeEvents) == IncludeEvents;
-                       => IncludeEvents == DbgEvtType.All || (IncludeEvents != DbgEvtType.None && (evtType & IncludeEvents) != 0);
-
-
+               static bool logevt (DbgEvtType evtType) {
+                       foreach (DbgEvtType et in IncludedEvents) {
+                               if ((et & evtType) == et)
+                                       return true;
+                       }
+                       return false;
+               }
 
                static object logMutex = new object ();
                static Stopwatch chrono = Stopwatch.StartNew ();
index 69c74e42e620373f3d82ac18541676a61d157555..3888ceafc60a1e5c5c3b67de0175be71f5597732 100644 (file)
@@ -386,29 +386,34 @@ namespace Crow.IML
                }
                internal static MethodInfo SearchExtMethod (Type t, string methodName)
                {
-                       string key = t.Name + "." + methodName;
-                       lock (knownExtMethods) {
-                               if (knownExtMethods.ContainsKey (key))
-                                       return knownExtMethods [key];
-
-                               //System.Diagnostics.Console.WriteLine ($"*** search extension method: {t};{methodName} => key={key}");
-
-                               MethodInfo mi = null;
-                               if (!TryGetExtensionMethods (Assembly.GetEntryAssembly (), t, methodName, out mi)) {
-                                       if (!TryGetExtensionMethods (t.Module.Assembly, t, methodName, out mi)) {
-                                               foreach (Assembly a in Interface.crowAssemblies) {
-                                                       if (TryGetExtensionMethods (a, t, methodName, out mi))
-                                                               break;
+                       try {
+                               string key = t.Name + "." + methodName;
+                               lock (knownExtMethods) {
+                                       if (knownExtMethods.ContainsKey (key))
+                                               return knownExtMethods [key];
+
+                                       //System.Diagnostics.Console.WriteLine ($"*** search extension method: {t};{methodName} => key={key}");
+
+                                       MethodInfo mi = null;
+                                       if (!TryGetExtensionMethods (Assembly.GetEntryAssembly (), t, methodName, out mi)) {
+                                               if (!TryGetExtensionMethods (t.Module.Assembly, t, methodName, out mi)) {
+                                                       foreach (Assembly a in Interface.crowAssemblies) {
+                                                               if (TryGetExtensionMethods (a, t, methodName, out mi))
+                                                                       break;
+                                                       }
+                                                       if (mi == null)
+                                                               TryGetExtensionMethods (Assembly.GetExecutingAssembly (), t, methodName, out mi);//crow Assembly
                                                }
-                                               if (mi == null)
-                                                       TryGetExtensionMethods (Assembly.GetExecutingAssembly (), t, methodName, out mi);//crow Assembly
                                        }
-                               }
 
-                               //add key even if mi is null to prevent searching again and again for propertyless bindings
-                               knownExtMethods.Add (key, mi);
-                               return mi;
+                                       //add key even if mi is null to prevent searching again and again for propertyless bindings
+                                       knownExtMethods.Add (key, mi);
+                                       return mi;
+                               }
+                       } catch (Exception e) {//added this catch for CrowEdit, ext method should be search with appropriate LoadContext.
+                               Debug.WriteLine ($"[CompilerServices.SearchExtMethod]{e}");
                        }
+                       return null;
                }
 
                public static bool TryGetExtensionMethods (Assembly assembly, Type extendedType, string methodName, out MethodInfo foundMI)
index 07ebfd3cd5860089c0e2f5ac52715a57b747472d..2acace294a15a6c56e18b23a808dffd642ec3797 100644 (file)
@@ -214,7 +214,7 @@ namespace Crow.IML {
                        while (reader.NodeType != XmlNodeType.Element)
                                reader.Read ();
                        root = reader.Name;
-                       Type t = GetWidgetTypeFromName (root);
+                       Type t = iface.GetWidgetTypeFromName (root);
                        if (t == null)
                                throw new Exception ("IML parsing error: undefined root type (" + root + ")");
                        return t;
@@ -323,7 +323,8 @@ namespace Crow.IML {
                                }
                                if (itemTemplateIds.Count == 0) {
                                        //try to load ItemTemplate(s) from ItemTemplate property of TemplatedGroup
-                                       if (!string.IsNullOrEmpty (itemTemplatePath)) {
+                                       //but don't if it's an binding expression
+                                       if (!string.IsNullOrEmpty (itemTemplatePath) && !itemTemplatePath.StartsWith('{')) {
                                                //check if it is already loaded in cache as a single itemTemplate instantiator
                                                if (iface.ItemTemplates.ContainsKey (itemTemplatePath))
                                                        itemTemplateIds.Add (new string [] { "default", itemTemplatePath, "" });
@@ -357,23 +358,30 @@ namespace Crow.IML {
                                }
                        }
                }
+               //TODO(09/2021):output an ItemTemplateDecl object instead of an array of string
                public static IEnumerable<string[]> loadItemTemplatesFromTemplatedGroupProperty (Interface iface, string itemTemplatePath) {
                        using (Stream stream = iface.GetStreamFromPath (itemTemplatePath)) {
-                               //itemtemplate files may have multiple root nodes
-                               XmlReaderSettings itrSettings = new XmlReaderSettings { ConformanceLevel = ConformanceLevel.Fragment };
-                               using (XmlReader itr = XmlReader.Create (stream, itrSettings)) {
-                                       while (itr.Read ()) {
-                                               if (!itr.IsStartElement ())
-                                                       continue;
-                                               if (itr.NodeType == XmlNodeType.Element) {
-                                                       if (itr.Name != NT_iTemp) {
-                                                               //the file contains a single template to use as default
-                                                               iface.ItemTemplates [itemTemplatePath] = new ItemTemplate (iface, itr);
-                                                               yield return new string [] { "default", itemTemplatePath, "", "TypeOf" };
-                                                               break;//we should be at the end of the file
-                                                       }
-                                                       yield return parseItemTemplateTag (iface, itr, itemTemplatePath);
+                               foreach (string[] item in loadItemTemplatesFromTemplatedGroupProperty (iface, stream, itemTemplatePath))
+                                       yield return item;
+                       }
+               }
+               public static IEnumerable<string[]> loadItemTemplatesFromTemplatedGroupProperty (Interface iface, Stream stream, string itemTemplatePath = null) {
+                       if (string.IsNullOrEmpty (itemTemplatePath))
+                               itemTemplatePath = Guid.NewGuid().ToString();
+                       //itemtemplate files may have multiple root nodes
+                       XmlReaderSettings itrSettings = new XmlReaderSettings { ConformanceLevel = ConformanceLevel.Fragment };
+                       using (XmlReader itr = XmlReader.Create (stream, itrSettings)) {
+                               while (itr.Read ()) {
+                                       if (!itr.IsStartElement ())
+                                               continue;
+                                       if (itr.NodeType == XmlNodeType.Element) {
+                                               if (itr.Name != NT_iTemp) {
+                                                       //the file contains a single template to use as default
+                                                       iface.ItemTemplates [itemTemplatePath] = new ItemTemplate (iface, itr);
+                                                       yield return new string [] { "default", itemTemplatePath, "", "TypeOf" };
+                                                       break;//we should be at the end of the file
                                                }
+                                               yield return parseItemTemplateTag (iface, itr, itemTemplatePath);
                                        }
                                }
                        }
@@ -543,7 +551,7 @@ namespace Crow.IML {
                                        ctx.il.Emit (OpCodes.Ldloc_0);
                                        ctx.il.Emit (OpCodes.Ldloc_0);
 
-                                       Type t = GetWidgetTypeFromName (reader.Name);
+                                       Type t = iface.GetWidgetTypeFromName (reader.Name);
                                        if (t == null)
                                                throw new Exception (reader.Name + " type not found");
                                        ConstructorInfo ci = t.GetConstructor (
index cb4e534ce36d8af97e953123baa10468794cf26d..17d1fee2859c1f0a88fe4b07d184133b8cde6513 100644 (file)
@@ -13,7 +13,7 @@ namespace Crow
     public class KeyPressEventArgs : CrowEventArgs
     {
         char key_char;
-        
+
         /// <summary>
         /// Constructs a new instance.
         /// </summary>
index ede2927e9ca2d3fa078f8cd7a4dce5f7f8d8df3d..46645deea8366f5ebeba91b0bc66ae431c5f7eb6 100644 (file)
@@ -360,8 +360,46 @@ namespace Crow
                        }
                }
 
-               internal Dictionary<string, MethodInfo> knownExtMethods = new Dictionary<string, MethodInfo> ();
-               internal MethodInfo SearchExtMethod (Type t, string methodName) {
+               protected Dictionary<string, MethodInfo> knownExtMethods;
+               protected Dictionary<string, Type> knownCrowWidgetTypes;
+
+               /// <summary>
+               /// search for graphic object type in crow assembly, if not found,
+               /// search for type independently of namespace in all the loaded assemblies
+               /// </summary>
+               /// <remarks>
+               /// </remarks>
+               /// <returns>the corresponding type object</returns>
+               /// <param name="typeName">graphic object type name without its namespace</param>
+               public virtual Type GetWidgetTypeFromName (string typeName){
+                       if (knownCrowWidgetTypes.ContainsKey (typeName))
+                               return knownCrowWidgetTypes [typeName];
+                       Type t = Type.GetType ("Crow." + typeName);
+                       if (t != null) {
+                               knownCrowWidgetTypes.Add (typeName, t);
+                               return t;
+                       }
+
+                       foreach (Type expT in Assembly.GetEntryAssembly ().GetExportedTypes ()) {
+                               if (expT.Name != typeName)
+                                       continue;
+                               knownCrowWidgetTypes.Add (typeName, expT);
+                               return expT;
+                       }
+
+                       foreach (Assembly a in Interface.crowAssemblies) {
+                               foreach (Type expT in a.GetExportedTypes ()) {
+                                       if (expT.Name != typeName)
+                                               continue;
+                                       knownCrowWidgetTypes.Add (typeName, expT);
+                                       return expT;
+                               }
+                       }
+                       return null;
+               }
+
+
+               public virtual MethodInfo SearchExtMethod (Type t, string methodName) {
                        string key = t.Name + "." + methodName;
                        if (knownExtMethods.ContainsKey (key))
                                return knownExtMethods [key];
@@ -790,6 +828,8 @@ namespace Crow
                        DefaultValuesLoader = new Dictionary<string, LoaderInvoker> (initCapacity);
                        Instantiators = new Dictionary<string, Instantiator> (initCapacity);
                        ItemTemplates = new Dictionary<string, ItemTemplate> (initCapacity);
+                       knownCrowWidgetTypes = new Dictionary<string, Type> (initCapacity);
+                       knownExtMethods = new Dictionary<string, MethodInfo> (initCapacity);
                }
                void loadThemeFiles () {
                        if (string.IsNullOrEmpty (Theme))
@@ -1033,6 +1073,9 @@ namespace Crow
                                }
 
                                _hoverWidget = value;
+                               if (_hoverWidget.ToString() == "HelloWorld.Program.vs2.Border12")
+                                       Debugger.Break();
+
 
                                NotifyValueChanged ("HoverWidget", _hoverWidget);
                                DbgLogger.AddEvent (DbgEvtType.HoverWidget, _hoverWidget);
@@ -1840,10 +1883,12 @@ namespace Crow
                                        return true;
                                }
 
-                               if (doubleClickTriggered)
-                                       _activeWidget.onMouseDoubleClick (_activeWidget, new MouseButtonEventArgs (MousePosition.X, MousePosition.Y, button, InputAction.Press));
-                               else
-                                       _activeWidget.onMouseClick (_activeWidget, new MouseButtonEventArgs (MousePosition.X, MousePosition.Y, button, InputAction.Press));
+                               if (_focusedWidget != null &&_focusedWidget.MouseIsIn(MousePosition)) {
+                                       if (doubleClickTriggered)
+                                               _activeWidget.onMouseDoubleClick (_activeWidget, new MouseButtonEventArgs (MousePosition.X, MousePosition.Y, button, InputAction.Press));
+                                       else
+                                               _activeWidget.onMouseClick (_activeWidget, new MouseButtonEventArgs (MousePosition.X, MousePosition.Y, button, InputAction.Press));
+                               }
 
                                ActiveWidget = null;
                                //                      if (!lastActive.MouseIsIn (Mouse.Position)) {
@@ -2057,7 +2102,7 @@ namespace Crow
                                else
                                        ctxMenuContainer.IsOpened = true;
 
-                               ctxMenuContainer.BubbleMouseEvent = DeviceEventType.None;
+                               ctxMenuContainer.BubbleEvents = DeviceEventType.None;
                                ctxMenuContainer.LogicalParent = go;
                                ctxMenuContainer.DataSource = go;
 
index 9fcbd7fbc21d2ffef14b6a69d4cf6d40cee3fa6c..c263b65622a5292f344a35ad51c97f1af4762a91 100644 (file)
@@ -14,7 +14,10 @@ using System.Diagnostics;
 using System.Linq;
 using Crow.IML;
 using System.Collections;
-
+//TODO(09/2021): itemTemplate are created  with datatest and datatype only to be able
+//to get their original iml, but itor part takes no advantage of it.
+//One advantage could be to set the DataSourceType (which speed bindings by bypassing reflection)
+//at the root level of the item template if the dataTest is 'typeOf'...
 namespace Crow
 {
        /// <summary> Test func on data, return yes if there's children </summary>
index 6c6fcde0cb56d454b36680ca476065f58102ca04..5b206575d7c86ad5cef529feb2d5d1b6d42d5bdc 100644 (file)
@@ -32,27 +32,27 @@ namespace Crow.Text
                        return true;
                }
                public bool TryRead (char c) => EndOfSpan ? false : Read() == c;
-                                       
+
                public ReadOnlySpan<char> Read (int length) => buffer.Slice (curPos += length, length);
                public void Advance (int increment = 1) => curPos += increment;
-               public bool TryAdvance (int increment = 1) {                    
+               public bool TryAdvance (int increment = 1) {
                        curPos += increment;
                        return curPos < buffer.Length;
                }
-               
+
                public bool TryReadUntil (ReadOnlySpan<char> str, StringComparison comparison = StringComparison.Ordinal) {
                        int startPos = curPos;
                        while (curPos < buffer.Length - str.Length) {
                                if (buffer[curPos] == str[0] && buffer.Slice(curPos + 1, str.Length - 1).Equals(str.Slice (1), comparison))
                                        return true;
-                               curPos++;                       
+                               curPos++;
                        }
                        return false;
                }
                public bool TryReadUntil (char c) {
                        int startPos = curPos;
                        while (curPos < buffer.Length && buffer[curPos] != c)
-                               curPos++;                       
+                               curPos++;
                        return curPos < buffer.Length;
                }
                public bool TryRead (int length, out ReadOnlySpan<char> str) {
@@ -63,7 +63,7 @@ namespace Crow.Text
                        str = default;
                        return false;
                }
-               
+
                /// <summary>
                /// Try read expected string and advance reader position in any case
                /// </summary>
@@ -81,22 +81,68 @@ namespace Crow.Text
                }
                public bool TryPeak (ReadOnlySpan<char> expectedString, StringComparison comparison = StringComparison.Ordinal) =>
                         (buffer.Length < curPos + expectedString.Length)? false :
-                                               buffer.Slice(curPos, expectedString.Length).Equals (expectedString, comparison);                        
-                       
+                                               buffer.Slice(curPos, expectedString.Length).Equals (expectedString, comparison);
+
+               /// <summary>
+               /// Retrieve a span of that buffer from provided starting position to the current reader position.
+               /// </summary>
+               /// <param name="fromPosition"></param>
+               /// <returns></returns>
         public ReadOnlySpan<char> Get (int fromPosition) => buffer.Slice (fromPosition, curPos - fromPosition);
-        public bool EndOfSpan => curPos >= buffer.Length;
+        /// <summary>
+        /// Current reader position is further the end of the buffer.
+        /// </summary>
+               public bool EndOfSpan => curPos >= buffer.Length;
                public bool TryPeak (char c) => !EndOfSpan && Peak == c;
+               /// <summary>
+               /// Try peak one char, return false if end of span, true otherwise.
+               /// </summary>
+               /// <param name="c"></param>
+               /// <returns></returns>
                public bool TryPeak (ref char c) {
                        if (EndOfSpan)
                                return false;
                        c = buffer[curPos];
                        return true;
                }
+               /// <summary>
+               /// test if next char is one of the provided one as parameter
+               /// </summary>
+               /// <param name="chars"></param>
+               /// <returns></returns>
                public bool IsNextCharIn (params char[] chars) {
                        for (int i = 0; i < chars.Length; i++)
                                if (chars[i] == buffer[curPos])
                                        return true;
                        return false;
                }
+               /// <summary>
+               /// increment reader position just before the next end of line
+               /// </summary>
+               public void AdvanceUntilEol () {
+                       while(!EndOfSpan) {
+                               switch (Peak) {
+                                       case '\x85':
+                                       case '\x2028':
+                                       case '\xA':
+                                               return;
+                                       case '\xD':
+                                               int nextPos = curPos + 1;
+                                               if (nextPos == buffer.Length || buffer[nextPos] == '\xA' || buffer[nextPos] == '\x85')
+                                                       return;
+                                               break;
+                               }
+                               Advance ();
+                       }
+               }
+               /// <summary>
+               /// Next char or pair of chars is end of line.
+               /// </summary>
+               /// <returns></returns>
+               public bool Eol () {
+                       return Peak == '\x85' || Peak == '\x2028' || Peak == '\xA' || curPos + 1 == buffer.Length ||
+                               (Peak == '\xD' && (buffer [curPos + 1]  == '\xA' || buffer [curPos + 1]  == '\x85'));
+
+               }
     }
 }
index 95e743ea8818e2e0bbece9c157be36394eece234..62b0f1c3de6df347d61703e6f6c575bbc3e506cf 100644 (file)
@@ -58,6 +58,7 @@ namespace Crow
                public void onClickForExpand (object sender, MouseButtonEventArgs e)
                {
                        IsExpanded = !IsExpanded;
+                       e.Handled = true;
                }
 
                #region Public properties
index bc6b46c037d4c5c12aa7d742463ce3999ed7dd9e..302818bfb4f0c3c8e2e6b9e9a6ed84fad818a4fa 100644 (file)
@@ -14,9 +14,17 @@ namespace Crow
        public class FileDialog: Window
        {
                #region CTOR
-               protected FileDialog() : base(){}
+               protected FileDialog() : base() {}
                public FileDialog (Interface iface) : base(iface){}
                #endregion
+               protected override void loadTemplate(Widget template = null)
+               {
+                       if (CMDOk == null) {
+                               CMDOk = new ActionCommand (this, "Ok", validate, null, new KeyBinding (Glfw.Key.Enter));
+                               CMDCancel = new ActionCommand (this, "Cancel", () => IFace.DeleteWidget (this), null, new KeyBinding (Glfw.Key.Escape));
+                       }
+                       base.loadTemplate(template);
+               }
 
                string searchPattern, curDir, _selectedFile, _selectedDir;
                bool showHidden, showFiles;
@@ -25,6 +33,9 @@ namespace Crow
                public event EventHandler OkClicked;
                #endregion
 
+               [XmlIgnore]public ActionCommand CMDOk { get; set;}
+               [XmlIgnore]public ActionCommand CMDCancel { get; set;}
+
                public string SelectedFileFullPath {
                        get { return Path.Combine (SelectedDirectory, SelectedFile); }
                }
@@ -115,20 +126,22 @@ namespace Crow
                        CurrentDirectory = SelectedDirectory;
                }
 
-               void onFileSelect (object sender, MouseButtonEventArgs e){
+               void validate () {
                        if (ShowFiles) {
                                if (string.IsNullOrEmpty (SelectedFile)) {
                                        CurrentDirectory = SelectedDirectory;
                                        return;
-                               }                                                                       
+                               }
                        }
                        OkClicked.Raise (this, null);
                        IFace.DeleteWidget (this);
                }
-               void onCancel(object sender, MouseButtonEventArgs e){
-                       IFace.DeleteWidget (this);
+               protected override void Dispose(bool disposing)
+               {
+                       CMDOk?.Dispose ();
+                       CMDCancel?.Dispose ();
+                       base.Dispose(disposing);
                }
-
        }
 }
 
index e91600954aa87f9dc49bebec63e2660227364afc..fd5a4984564ae63e63b4876c584413ad9303dd53 100644 (file)
@@ -140,7 +140,8 @@ namespace Crow
                {
                        if (IsOpened)
                                IsOpened = false;
-                       base.onMouseLeave (this, e);
+                       if (mouseIsEntered)
+                               base.onMouseLeave (this, e);
                }
                public override void onMouseClick (object sender, MouseButtonEventArgs e)
                {
index 6621c27c105e21bdf57d02144ffe874e6210dabd..e67625fec41f8e41f8905aa3b4f330f6e3b82d75 100644 (file)
@@ -6,6 +6,7 @@ using System;
 using System.Collections;
 using System.Collections.Generic;
 using System.ComponentModel;
+using System.IO;
 using System.Linq;
 using System.Threading;
 
@@ -114,13 +115,33 @@ namespace Crow {
                        ItemTemplates.Clear();
                        if (string.IsNullOrEmpty (_itemTemplate))
                                return;
-                       foreach (string[] itempIds in Instantiator.loadItemTemplatesFromTemplatedGroupProperty (IFace, _itemTemplate)) {
-                               ItemTemplate itemp = IFace.GetItemTemplate (itempIds[1]);
-                               ItemTemplates.Add (itempIds[0], itemp);
-                               if (string.IsNullOrEmpty (itempIds[2]))
-                                       continue;
-                               itemp.CreateExpandDelegate (this);
+                       if (_itemTemplate.Trim().StartsWith('<')) {//iml fragment in property
+                               using (Stream stream = new MemoryStream (System.Text.Encoding.UTF8.GetBytes (_itemTemplate))) {
+                                       foreach (string[] itempIds in Instantiator.loadItemTemplatesFromTemplatedGroupProperty (IFace, stream)) {
+                                               ItemTemplate itemp = IFace.GetItemTemplate (itempIds[1]);
+                                               ItemTemplates.Add (itempIds[0], itemp);
+                                               if (string.IsNullOrEmpty (itempIds[2]))
+                                                       continue;
+                                               itemp.CreateExpandDelegate (this);
+                                       }
+                               }
+                       } else {
+                               foreach (string[] itempIds in Instantiator.loadItemTemplatesFromTemplatedGroupProperty (IFace, _itemTemplate)) {
+                                       ItemTemplate itemp = IFace.GetItemTemplate (itempIds[1]);
+                                       ItemTemplates.Add (itempIds[0], itemp);
+                                       if (string.IsNullOrEmpty (itempIds[2]))
+                                               continue;
+                                       itemp.CreateExpandDelegate (this);
+                               }
                        }
+                       realoadDatas ();
+               }
+               void realoadDatas () {
+                       if (data == null)
+                               return;
+                       IEnumerable dataSave = data;
+                       Data = null;
+                       Data = dataSave;
                }
                protected override void loadTemplate(Widget template = null)
                {
@@ -234,8 +255,10 @@ namespace Crow {
                                lock (IFace.UpdateMutex)
                                        ClearItems ();
 
-                               if (data == null)
+                               if (data == null) {
+                                       NotifyValueChanged ("HasItems", false);
                                        return;
+                               }
 
                                if (data is ICollection c) {
                                        if (c.Count == 0) {
@@ -504,7 +527,7 @@ namespace Crow {
                                        itempKey = dataType.FullName;//fallback to full type name
                                }
                        }
-                       if (ItemTemplates.ContainsKey (itempKey))
+                       if (!string.IsNullOrEmpty (itempKey) && ItemTemplates.ContainsKey (itempKey))
                                iTemp = ItemTemplates [itempKey];
                        else {
                                if (_dataTest == "TypeOf") {//item template selection on full type name
index 0b5b4463e7a1d36b8f41b6be6838c67d6e18aa3c..1f7c1b08ad1e091c60fedd11a638d019aa25d77b 100644 (file)
@@ -27,7 +27,7 @@ namespace Crow
        /// <summary>
        /// The base class for all the graphic tree elements.
        /// </summary>
-       public class Widget : ILayoutable, IValueChange, IDisposable
+       public class Widget : ILayoutable, ICommandHost, IDisposable
        {
                internal ReaderWriterLockSlim parentRWLock = new ReaderWriterLockSlim(LockRecursionPolicy.SupportsRecursion);
 #if DEBUG_LOG
@@ -140,9 +140,7 @@ namespace Crow
                        }
                        return di;
                }
-               public string DesignName {
-                       get { return GetType ().Name + design_id; }
-               }
+               public string DesignName => LogName + design_id;
 #endif
 
                #region IDisposable implementation
@@ -558,7 +556,7 @@ namespace Crow
                public virtual string Name {
                        get {
 #if DEBUG_LOG
-                               return string.IsNullOrEmpty(name) ? this.GetType().Name + GraphicObjects.IndexOf(this).ToString () : name;
+                               return string.IsNullOrEmpty(name) ? this.LogName + GraphicObjects.IndexOf(this).ToString () : name;
 #else
                                return name;
 #endif
@@ -774,7 +772,7 @@ namespace Crow
                /// </summary>
                [DesignCategory ("Behaviour")]
                [DefaultValue (DeviceEventType.All)]
-               public virtual DeviceEventType BubbleMouseEvent {
+               public virtual DeviceEventType BubbleEvents {
                        get => bubbledEvents;
                        set {
                                if (bubbledEvents == value)
@@ -1971,7 +1969,6 @@ namespace Crow
                                ctx.Fill ();
                                ctx.Operator = Operator.Over;
                        }
-
                        ctx.SetSource (bmp, rb.X, rb.Y);
                        ctx.Paint ();
 #if VKVG
@@ -2060,19 +2057,19 @@ namespace Crow
                public virtual void onKeyDown(object sender, KeyEventArgs e){
                        if (KeyDown != null)
                                KeyDown.Invoke (this, e);
-                       else if (!e.Handled && BubbleMouseEvent.HasFlag (DeviceEventType.KeyDown))
+                       else if (!e.Handled && BubbleEvents.HasFlag (DeviceEventType.KeyDown))
                                FocusParent?.onKeyDown (sender, e);
                }
                public virtual void onKeyUp(object sender, KeyEventArgs e){
                        if (KeyUp != null)
                                KeyUp.Invoke (this, e);
-                       else if (!e.Handled && BubbleMouseEvent.HasFlag (DeviceEventType.KeyUp))
+                       else if (!e.Handled && BubbleEvents.HasFlag (DeviceEventType.KeyUp))
                                FocusParent?.onKeyUp (sender, e);
                }
                public virtual void onKeyPress(object sender, KeyPressEventArgs e){
                        if (KeyPress != null)
                                KeyPress.Invoke (this, e);
-                       else if (!e.Handled && BubbleMouseEvent.HasFlag (DeviceEventType.KeyPress))
+                       else if (!e.Handled && BubbleEvents.HasFlag (DeviceEventType.KeyPress))
                                FocusParent?.onKeyPress (sender, e);
                }
                #endregion
@@ -2123,7 +2120,7 @@ namespace Crow
 
                        if (MouseMove != null)
                                MouseMove.Invoke (this, e);
-                       else if (!e.Handled && BubbleMouseEvent.HasFlag (DeviceEventType.MouseMove))
+                       else if (!e.Handled && BubbleEvents.HasFlag (DeviceEventType.MouseMove))
                                FocusParent?.onMouseMove (sender, e);
                }
                /// <summary>
@@ -2135,7 +2132,8 @@ namespace Crow
                /// <param name="sender">Sender of the event</param>
                /// <param name="e">mouse button pressed event arguments</param>
                public virtual void onMouseDown(object sender, MouseButtonEventArgs e){
-                       if (Focusable) {
+                       DbgLogger.AddEvent (DbgEvtType.MouseDown, this);
+                       if (Focusable && !HasFocus) {
                                IFace.FocusedWidget = this;
                                e.Handled = true;
                        }
@@ -2145,9 +2143,8 @@ namespace Crow
                                e.Handled = true;
                        }
 
-                       if (MouseDown != null)
-                               MouseDown?.Invoke (this, e);
-                       else if (!e.Handled && BubbleMouseEvent.HasFlag (DeviceEventType.ButtonDown))
+                       MouseDown?.Invoke (this, e);
+                       if (!e.Handled && BubbleEvents.HasFlag (DeviceEventType.ButtonDown))
                                FocusParent?.onMouseDown (sender, e);
                }
                /// <summary>
@@ -2159,10 +2156,10 @@ namespace Crow
                /// <param name="sender">Sender of the event</param>
                /// <param name="e">mouse button release event arguments</param>
                public virtual void onMouseUp(object sender, MouseButtonEventArgs e){
-
+                       DbgLogger.AddEvent (DbgEvtType.WidgetMouseUp, this);
                        if (MouseUp != null)
                                MouseUp.Invoke (this, e);
-                       else if (!e.Handled && BubbleMouseEvent.HasFlag (DeviceEventType.ButtonUp))
+                       if (!e.Handled && BubbleEvents.HasFlag (DeviceEventType.ButtonUp))
                                FocusParent?.onMouseUp (sender, e);
                }
                /// <summary>
@@ -2171,9 +2168,10 @@ namespace Crow
                /// <param name="sender">The Sender of the event</param>
                /// <param name="e">event arguments</param>
                public virtual void onMouseClick(object sender, MouseButtonEventArgs e){
+                       DbgLogger.AddEvent (DbgEvtType.WidgetMouseClick, this);
                        if (MouseClick != null)
                                MouseClick.Invoke (this, e);
-                       else if (!e.Handled && BubbleMouseEvent.HasFlag (DeviceEventType.MouseClick))
+                       if (!e.Handled && BubbleEvents.HasFlag (DeviceEventType.MouseClick))
                                FocusParent?.onMouseClick (sender, e);
                }
                /// <summary>
@@ -2183,19 +2181,24 @@ namespace Crow
                /// <param name="sender">The Sender of the event</param>
                /// <param name="e">event arguments</param>
                public virtual void onMouseDoubleClick(object sender, MouseButtonEventArgs e){
+                       DbgLogger.AddEvent (DbgEvtType.WidgetMouseDblClick, this);
                        if (MouseDoubleClick != null)
                                MouseDoubleClick.Invoke (this, e);
-                       else if (!e.Handled && BubbleMouseEvent.HasFlag (DeviceEventType.MouseClick))
+                       if (!e.Handled && BubbleEvents.HasFlag (DeviceEventType.MouseClick))
                                FocusParent?.onMouseDoubleClick (sender, e);
                }
                public virtual void onMouseWheel(object sender, MouseWheelEventArgs e){
+                       DbgLogger.AddEvent (DbgEvtType.WidgetMouseWheel, this);
                        if (MouseWheelChanged != null)
                                MouseWheelChanged.Invoke (this, e);
-                       else if (!e.Handled && BubbleMouseEvent.HasFlag (DeviceEventType.MouseWheel))
+                       if (!e.Handled && BubbleEvents.HasFlag (DeviceEventType.MouseWheel))
                                FocusParent?.onMouseWheel (sender, e);
                }
+               protected bool mouseIsEntered;
                public virtual void onMouseEnter(object sender, MouseMoveEventArgs e)
                {
+                       DbgLogger.AddEvent (DbgEvtType.MouseEnter, this);
+                       mouseIsEntered = true;
                        IFace.MouseCursor = MouseCursor;
                        /*if (IFace.DragAndDropOperation != null) {
                                Widget g = this;
@@ -2216,6 +2219,8 @@ namespace Crow
                }
                public virtual void onMouseLeave(object sender, MouseMoveEventArgs e)
                {
+                       DbgLogger.AddEvent (DbgEvtType.MouseLeave, this);
+                       mouseIsEntered = false;
                        MouseLeave.Raise (this, e);
                }
 
@@ -2312,8 +2317,8 @@ namespace Crow
                                                w = w.FocusParent;
                                        }
                                        this.onMouseLeave (this, e);
-                                       IFace.HoverWidget = null;
-                                       IFace.OnMouseMove (IFace.MousePosition.X, IFace.MousePosition.Y);
+                                       IFace.HoverWidget = FocusParent;
+                                       //IFace.OnMouseMove (IFace.MousePosition.X, IFace.MousePosition.Y);
                                }
                        }
 
index 23e3047c71001cfa677adcee907aeb78af764cec..a056283ac7cfe63c1316f80f857e98d63f544ff5 100644 (file)
@@ -54,7 +54,7 @@ namespace Crow
                        return (Char)Peek();
                }
                void SkipWhiteSpaceAndLineBreak (){
-                       while (!EndOfStream){                           
+                       while (!EndOfStream){
                                if (!PeekChar ().IsWhiteSpaceOrNewLine ())
                                        break;
                                if (ReadChar () == '\n') {
@@ -102,108 +102,108 @@ namespace Crow
                                        }else
                                                throw new ParserException (line, column, $"Unexpected char '{PeekChar ()}'", resId);
                                        break;
-                               case ',':
-                                       ReadChar ();
-                                       if (curState != States.classNames || token.Length == 0)
-                                               throw new ParserException (line, column, "Unexpected char ','", resId);
-                                       targetsClasses.Add (token.ToString());
-                                       token.Clear();
-                                       curState = States.classNames;
-                                       break;
-                               case '{':
-                                       ReadChar ();
-                                       if (curState != States.classNames || token.Length == 0)
-                                               throw new ParserException (line, column, "Unexpected char '{'", resId);
-                                       targetsClasses.Add (token.ToString());
-                                       token.Clear();
-                                       curState = States.members;
-                                       break;
-                               case '}':
-                                       ReadChar ();
-                                       if (curState != States.members)
-                                               throw new ParserException (line, column, "Unexpected char '}'", resId);
-                                       curState = States.classNames;
-                                       targetsClasses.Clear ();
-                                       break;
-                               case '=':
-                                       ReadChar ();
-                                       if (!(curState == States.members || curState == States.classNames) || token.Length == 0)
-                                               throw new ParserException (line, column, "Unexpected char '='", resId);
-                                       currentProperty = token.ToString ();
-                                       token.Clear ();
-                                       curState = States.value;
-                                       break;
-                               case '"':
-                                       if (curState != States.value)
-                                               throw new ParserException (line, column, "Unexpected char '\"'", resId);
-                                       ReadChar ();
+                                       case ',':
+                                               ReadChar ();
+                                               if (curState != States.classNames || token.Length == 0)
+                                                       throw new ParserException (line, column, "Unexpected char ','", resId);
+                                               targetsClasses.Add (token.ToString());
+                                               token.Clear();
+                                               curState = States.classNames;
+                                               break;
+                                       case '{':
+                                               ReadChar ();
+                                               if (curState != States.classNames || token.Length == 0)
+                                                       throw new ParserException (line, column, "Unexpected char '{'", resId);
+                                               targetsClasses.Add (token.ToString());
+                                               token.Clear();
+                                               curState = States.members;
+                                               break;
+                                       case '}':
+                                               ReadChar ();
+                                               if (curState != States.members)
+                                                       throw new ParserException (line, column, "Unexpected char '}'", resId);
+                                               curState = States.classNames;
+                                               targetsClasses.Clear ();
+                                               break;
+                                       case '=':
+                                               ReadChar ();
+                                               if (!(curState == States.members || curState == States.classNames) || token.Length == 0)
+                                                       throw new ParserException (line, column, "Unexpected char '='", resId);
+                                               currentProperty = token.ToString ();
+                                               token.Clear ();
+                                               curState = States.value;
+                                               break;
+                                       case '"':
+                                               if (curState != States.value)
+                                                       throw new ParserException (line, column, "Unexpected char '\"'", resId);
+                                               ReadChar ();
 
-                                       while (!EndOfStream) {
-                                               char c = ReadChar ();
-                                               if (c == '$') {
-                                                       if (PeekChar () == '{') {
-                                                               ReadChar ();
-                                                               //constant replacement
-                                                               while (!EndOfStream) {
-                                                                       c = ReadChar ();
-                                                                       if (c == '}')
-                                                                               break;
-                                                                       constantId.Append (c);
+                                               while (!EndOfStream) {
+                                                       char c = ReadChar ();
+                                                       if (c == '$') {
+                                                               if (PeekChar () == '{') {
+                                                                       ReadChar ();
+                                                                       //constant replacement
+                                                                       while (!EndOfStream) {
+                                                                               c = ReadChar ();
+                                                                               if (c == '}')
+                                                                                       break;
+                                                                               constantId.Append (c);
+                                                                       }
+                                                                       if (constantId.Length == 0)
+                                                                               throw new ParserException (line, column, "Empty constant id in styling", resId);
+                                                                       string cst = constantId.ToString ();
+                                                                       constantId.Clear ();
+                                                                       if (!StylingConstants.ContainsKey (cst))
+                                                                               throw new ParserException (line, column, $"Constant id not found in styling ({cst})", resId);
+                                                                       token.Append (StylingConstants[cst]);
+                                                                       continue;
                                                                }
-                                                               if (constantId.Length == 0)
-                                                                       throw new ParserException (line, column, "Empty constant id in styling", resId);
-                                                               string cst = constantId.ToString ();
-                                                               constantId.Clear ();
-                                                               if (!StylingConstants.ContainsKey (cst))
-                                                                       throw new ParserException (line, column, $"Constant id not found in styling ({cst})", resId);
-                                                               token.Append (StylingConstants[cst]);
-                                                               continue;
+                                                       } else if (c == '\"') {
+                                                               curState = States.endOfStatement;
+                                                               break;
                                                        }
-                                               } else if (c == '\"') {
-                                                       curState = States.endOfStatement;
-                                                       break;
+                                                       token.Append (c);
                                                }
-                                               token.Append (c);
-                                       }
-                                       break;
-                               case ';':
-                                       if (curState != States.endOfStatement)
-                                               throw new ParserException (line, column, "Unexpected end of statement", resId);
-                                       ReadChar ();
-                                       if (targetsClasses.Count == 0) {
-                                               //only first style constants kept.
-                                               if (!StylingConstants.ContainsKey (currentProperty))
-                                                       StylingConstants[currentProperty] = token.ToString ();
-                                               curState = States.classNames;
-                                       } else {
-                                               foreach (string tc in targetsClasses) {
-                                                       if (!Styling.ContainsKey (tc))
-                                                               Styling [tc] = new Style ();
-                                                       if (!Styling[tc].ContainsKey (currentProperty)) {
-                                                               Styling[tc][currentProperty] = token.ToString ();
-#if DESIGN_MODE
-                                                               Styling [tc].Locations[currentProperty] = new FileLocation(resId, line, column - token.Length - 1, token.Length);
-#endif
+                                               break;
+                                       case ';':
+                                               if (curState != States.endOfStatement)
+                                                       throw new ParserException (line, column, "Unexpected end of statement", resId);
+                                               ReadChar ();
+                                               if (targetsClasses.Count == 0) {
+                                                       //only first style constants kept.
+                                                       if (!StylingConstants.ContainsKey (currentProperty))
+                                                               StylingConstants[currentProperty] = token.ToString ();
+                                                       curState = States.classNames;
+                                               } else {
+                                                       foreach (string tc in targetsClasses) {
+                                                               if (!Styling.ContainsKey (tc))
+                                                                       Styling [tc] = new Style ();
+                                                               if (!Styling[tc].ContainsKey (currentProperty)) {
+                                                                       Styling[tc][currentProperty] = token.ToString ();
+       #if DESIGN_MODE
+                                                                       Styling [tc].Locations[currentProperty] = new FileLocation(resId, line, column - token.Length - 1, token.Length);
+       #endif
+                                                               }
                                                        }
+                                                       curState = States.members;
                                                }
-                                               curState = States.members;
-                                       }
-                                       token.Clear ();
-                                       currentProperty = null;
-                                       break;
-                               default:
-                                       if (curState == States.value)
-                                               throw new ParserException (line, column, "expecting value enclosed in '\"'", resId);
-                                       if (curState == States.endOfStatement)
-                                               throw new ParserException (line, column, "expecting end of statement", resId);
+                                               token.Clear ();
+                                               currentProperty = null;
+                                               break;
+                                       default:
+                                               if (curState == States.value)
+                                                       throw new ParserException (line, column, "expecting value enclosed in '\"'", resId);
+                                               if (curState == States.endOfStatement)
+                                                       throw new ParserException (line, column, "expecting end of statement", resId);
 
-                                       if (nextCharIsValidCharStartName) {
-                                               token.Append (ReadChar ());
-                                               while (nextCharIsValidCharName)
+                                               if (nextCharIsValidCharStartName) {
                                                        token.Append (ReadChar ());
+                                                       while (nextCharIsValidCharName)
+                                                               token.Append (ReadChar ());
+                                               }
+                                               break;
                                        }
-                                       break;
-                               }
                        }
 
                }
index a0ea5fb5d3b83658d81f7fe41b16c1e93a79cc92..ba354726e2e1eae99a24a1c5e77d884ab8edd8ca 100644 (file)
@@ -15,7 +15,7 @@
 
                <!-- Compile with logging enabled, this will slow down apps, use this only
                         for debugging purpose-->
-               <CrowDebugLogEnabled>false</CrowDebugLogEnabled>
+               <CrowDebugLogEnabled>true</CrowDebugLogEnabled>
 
                <!-- Collect several statistics on widgets-->
                <CrowDebugStatsEnabled>false</CrowDebugStatsEnabled>
index 28d28b50b0ce032ef53822a65c806bfada6bba6d..98b4dc8a6fd41a41cfff09c74716db3af94ec6d9 100644 (file)
--- a/README.md
+++ b/README.md
@@ -3,10 +3,10 @@
   <a href="http://www.amitmerchant.com/electron-markdownify">
     <img src="https://github.com/jpbruyere/Crow/blob/master/Images/crow.png" alt="C.R.O.W." width="140">
   </a>
-  <br>  
+  <br>
     <br>
   C# Rapid Open Widgets
-  <br>  
+  <br>
 <p align="center">
   <a href="https://www.nuget.org/packages/Crow"><img src="https://buildstats.info/nuget/Crow"></a>
   <a href="https://travis-ci.org/jpbruyere/Crow">
@@ -20,7 +20,7 @@
   </a>
   <a href="https://gitter.im/CSharpRapidOpenWidgets?utm_source=badge&utm_medium=badge&utm_campaign=pr-badge&utm_content=badge">
     <img src="https://badges.gitter.im/CSharpRapidOpenWidgets.svg">
-  </a>    
+  </a>
 </p>
 </h1>
 
index e2be248e57a250a9f824148e0f10e4a4d7b2d623..dc5e2a1355ba3196fb9abafd148dae1eaff3f519 100644 (file)
@@ -5,7 +5,18 @@ using Samples;
 namespace HelloWorld
 {
        class Program : SampleBase {
+               public CommandGroup CMDTest = new CommandGroup (
+                       new ActionCommand("Action", ()=> Console.WriteLine ("Action executed"))
+               );
                static void Main (string[] args) {
+                       DbgLogger.IncludedEvents.AddRange ( new DbgEvtType[] {
+                               DbgEvtType.MouseEnter,
+                               DbgEvtType.MouseLeave,
+                               DbgEvtType.WidgetMouseDown,
+                               DbgEvtType.WidgetMouseUp,
+                               DbgEvtType.WidgetMouseClick,
+                               DbgEvtType.HoverWidget
+                       });
                        using (Interface app = new Program ()) {
                                app.Initialized += (sender, e) => (sender as Interface).Load ("#HelloWorld.helloworld.crow").DataSource = sender;
                                app.Run ();
index fe05d1e284d65a39ae634b2f9a054beac5440028..a9dad40cee05f1762af0afc239fb7b6c1dba37a0 100644 (file)
@@ -1,2 +1,40 @@
 <?xml version="1.0"?>
-<Label Text="Hello World"/>
\ No newline at end of file
+<VerticalStack Margin="50" Spacing="20">
+       <HorizontalStack Height="Fit">
+               <Label Text="Hover:" Width="50" Foreground="Grey"/>
+               <Label Text="{HoverWidget}" Font="mono, 8"/>
+       </HorizontalStack>
+       <HorizontalStack Height="Fit">
+               <Label Text="Focus:" Width="50" Foreground="Grey"/>
+               <Label Text="{FocusedWidget}" Font="mono, 8"/>
+       </HorizontalStack>
+       <HorizontalStack Height="Fit">
+               <Label Text="Active:" Width="50" Foreground="Grey"/>
+               <Label Text="{ActiveWidget}" Font="mono, 8"/>
+       </HorizontalStack>
+       <Border Height="Fit" Margin="2" Background="Blue" ContextCommands="{CMDTest}" Focusable="true"
+                       MouseEnter="{Background=Red}"
+                       MouseLeave="{Background=Blue}">
+               <Label Margin="5" Text="Hello World" />
+       </Border>
+       <Border Height="Fit" Margin="2" Background="Blue" ContextCommands="{CMDTest}" Focusable="true"
+                       MouseEnter="{Background=Red}"
+                       MouseLeave="{Background=Blue}">
+               <Label Margin="5" Text="Hello World" />
+       </Border>
+       <Border Height="Fit" Margin="2" Background="Blue" ContextCommands="{CMDTest}" Focusable="true"
+                       MouseEnter="{Background=Red}"
+                       MouseLeave="{Background=Blue}">
+               <Label Margin="5" Text="Hello World" />
+       </Border>
+       <Border Height="Fit" Margin="2" Background="Blue" ContextCommands="{CMDTest}" Focusable="true"
+                       MouseEnter="{Background=Red}"
+                       MouseLeave="{Background=Blue}">
+               <Label Margin="5" Text="Hello World" />
+       </Border>
+       <Border Height="Fit" Margin="2" Background="Blue" ContextCommands="{CMDTest}" Focusable="true"
+                       MouseEnter="{Background=Red}"
+                       MouseLeave="{Background=Blue}">
+               <Label Margin="5" Text="Hello World" />
+       </Border>
+</VerticalStack>
index cb094e4aadc4c559d0f0e9920aebff1668ef26ad..37582cfe2063d78d5516d224dd906949927638a9 100644 (file)
@@ -19,6 +19,13 @@ namespace ShowCase
 {
        class Showcase : SampleBaseForEditor
        {
+               DbgEvtType[] logEvts = {
+                       DbgEvtType.MouseEnter,
+                       DbgEvtType.MouseLeave,
+                       DbgEvtType.WidgetMouseDown,
+                       DbgEvtType.WidgetMouseUp,
+                       DbgEvtType.WidgetMouseClick,
+               };
                static void Main ()
                {
                        initDebugLog ();
@@ -116,15 +123,13 @@ namespace ShowCase
                 return true;
             case Key.F6:
                                if (DebugLogRecording) {
-                                       DbgLogger.IncludeEvents = DbgEvtType.None;
-                                       DbgLogger.DiscardEvents = DbgEvtType.All;
+                                       DbgLogger.IncludedEvents.Clear();
                                        if (DebugLogToFile && !string.IsNullOrEmpty(DebugLogFilePath))
                                DbgLogger.Save (this, DebugLogFilePath);
                                        DebugLogRecording = false;
                                } else {
                                        DbgLogger.Reset ();
-                                       DbgLogger.IncludeEvents = RecordedEvents;
-                                       DbgLogger.DiscardEvents = DiscardedEvents;
+                                       DbgLogger.IncludedEvents = new List<DbgEvtType> (logEvts);
                                        DebugLogRecording = true;
                                }
                 return true;
index c7e2fa06c08038cf084e4bed221c3d29898eedee..9ef1001d91dd0db098ab617f84614a76b8939293 100644 (file)
@@ -1,5 +1,5 @@
 <?xml version="1.0"?>
-<Border Background="{./Background}" MinimumSize="50,20" Name="Content"
+<Border Background="{./Background}" MinimumSize="50,20" Name="Content" Width="Stretched"
                                                        Foreground="Transparent" CornerRadius="{../CornerRadius}" BorderWidth="1"
                                                        MouseEnter="{Foreground=vgradient|0:White|0.2:Grey|0.9:Grey|1:Black};{caption.Foreground=White}"
                                                        MouseLeave="{Foreground=Transparent};{caption.Foreground=LightGrey}"
index c64fa74090826c50246fce16647348a4f468148d..23368cedd474b51bfd16e5260ad834d3e6bec1b3 100644 (file)
@@ -25,7 +25,7 @@
                                                                <ListItem ContextCommands="{GetCommands}"
                                                                                Selected="{/exp.Background=${ControlHighlight}}"
                                                                                Unselected="{/exp.Background=Transparent}">
-                                                                       <Expandable Name="exp" Caption="{Name}" MouseDoubleClick="/onClickForExpand" BubbleMouseEvent="MouseWheel|Keyboard|ButtonDown">
+                                                                       <Expandable Name="exp" Caption="{Name}" MouseDoubleClick="/onClickForExpand" BubbleEvents="MouseWheel|Keyboard|MouseClick|ButtonDown">
                                                                                <Template>
                                                                                        <VerticalStack>
                                                                                                <Border CornerRadius="2" Margin="0" Height="Fit" MouseDoubleClick="./onClickForExpand"
@@ -44,7 +44,7 @@
                                                                                                                <Label Text="{./Caption}"/>
                                                                                                        </HorizontalStack>
                                                                                                </Border>
-                                                                                               <Container Name="Content" Visible="false"/>
+                                                                                               <Container Name="Content" Visible="false" BubbleEvents="MouseWheel|Keyboard"/>
                                                                                        </VerticalStack>
                                                                                </Template>
                                                                                <HorizontalStack Height="Fit">
index e56914f885cdc0d700934fb20ef88cd01f8d2ea1..0c702745473aa220da128e6e2f8e21ae44cd24c6 100644 (file)
@@ -52,13 +52,13 @@ namespace Crow
 
 
                IEnumerable<MemberInfo> getAllCrowTypeMembers (string crowTypeName) {
-                       Type crowType = IML.Instantiator.GetWidgetTypeFromName (crowTypeName);
+                       Type crowType = IFace.GetWidgetTypeFromName (crowTypeName);
                        return crowType.GetMembers (BindingFlags.Public | BindingFlags.Instance).
                                Where (m=>((m is PropertyInfo pi && pi.CanWrite) || (m is EventInfo)) &&
                                                m.GetCustomAttribute<XmlIgnoreAttribute>() == null);
                }
                MemberInfo getCrowTypeMember (string crowTypeName, string memberName) {
-                       Type crowType = IML.Instantiator.GetWidgetTypeFromName (crowTypeName);
+                       Type crowType = IFace.GetWidgetTypeFromName (crowTypeName);
                        return crowType.GetMember (memberName, BindingFlags.Public | BindingFlags.Instance).FirstOrDefault ();
                }
 
index b44bb8f5f84b85581fc102f4a0e697707c729b64..3e0ef714c9872d0aa001c08556c8d8b6c5576b74 100644 (file)
@@ -94,6 +94,17 @@ namespace Samples
                                new ActionCommand("Action A", () => MessageBox.ShowModal(this, MessageBox.Type.Information, "context menu A clicked"))
                        );
                }
+               DeviceEventType deviceEventTypeEnum;
+               public DeviceEventType DeviceEventTypeEnum {
+                       get => deviceEventTypeEnum;
+                       set {
+                               if (deviceEventTypeEnum == value)
+                                       return;
+                               deviceEventTypeEnum = value;
+                               NotifyValueChanged ("DeviceEventTypeEnum", deviceEventTypeEnum);
+                       }
+
+               }
                public int intValue = 500;
                VerticalAlignment currentVAlign;
 
index e1cadc0a26d23dae4908879d611611d9c329af64..a63ba54e5f34a0728df1186634d1e2b9e77ba2ed 100644 (file)
@@ -67,7 +67,7 @@ namespace Samples
                }
                public bool DebugLoggingEnabled => DbgLogger.IsEnabled;
 
-               public DbgEvtType RecordedEvents {
+               /*public DbgEvtType RecordedEvents {
                        get => Configuration.Global.Get<DbgEvtType> (nameof (RecordedEvents));
                        set {
                                if (RecordedEvents == value)
@@ -88,7 +88,7 @@ namespace Samples
                                        DbgLogger.DiscardEvents = DiscardedEvents;
                                NotifyValueChanged(DiscardedEvents);
                        }
-               }
+               }*/
                public bool DebugLogRecording {
                        get => debugLogRecording;
                        set {
@@ -119,9 +119,6 @@ namespace Samples
                }
 
                protected static void initDebugLog () {
-                       DbgLogger.IncludeEvents = DbgEvtType.None;
-                       DbgLogger.DiscardEvents = DbgEvtType.All;
-                       //DbgLogger.DiscardEvents = DbgEvtType.All;
                        DbgLogger.ConsoleOutput = !Configuration.Global.Get<bool> (nameof (DebugLogToFile));
                }
 
diff --git a/Samples/common/ui/Interfaces/Experimental/buttonSizing.crow b/Samples/common/ui/Interfaces/Experimental/buttonSizing.crow
new file mode 100644 (file)
index 0000000..04139b1
--- /dev/null
@@ -0,0 +1,9 @@
+<VerticalStack Fit="true" Background="Onyx" Margin="0">
+       <Button Caption='Ok' Background='MediumSeaGreen' Width="Stretched" MouseClick="{Background=Red}">
+               <Template>
+                       <Border Style="ButtonBorder" Background="{./Background}" Name="Content" CornerRadius="{../CornerRadius}" Width="Stretched">
+                               <Label Font="{./Font}" Name="caption" Margin="${ButtonCaptionMargin}" Foreground="{./Foreground}" Text="{./Caption}"/>
+                       </Border>
+               </Template>
+       </Button>
+</VerticalStack>
\ No newline at end of file
diff --git a/Samples/common/ui/Interfaces/Experimental/enumSelector2.crow b/Samples/common/ui/Interfaces/Experimental/enumSelector2.crow
new file mode 100644 (file)
index 0000000..adaf087
--- /dev/null
@@ -0,0 +1,18 @@
+<VerticalStack>
+       <Label Text="{DeviceEventTypeEnum}"/>
+       <EnumSelector Caption="Device Events:" EnumValue="{²DeviceEventTypeEnum}" ItemStyle="CheckBox3" Width="Fit"  Background="Jet">
+               <Template>
+                       <Border Style="ControlBorder" Background="{./Background}" CornerRadius="{./CornerRadius}">
+                               <HorizontalStack>
+                                       <Label Text="{./Caption}"/>
+                                       <Popper Caption="{./EnumValue}" PopDirection="BottomLeft" >
+                                               <Template>
+                                                       <Label Style="ControlCaption" Text="{./Caption}" Foreground="{./Foreground}" MinimumSize="80,1" TextAlignment="Center"/>
+                                               </Template>
+                                               <VerticalStack Fit="true" Name="Content" Background="Onyx" Width="{../PopWidth}" Margin="5"/>
+                                       </Popper>
+                               </HorizontalStack>
+                       </Border>
+               </Template>
+       </EnumSelector>
+</VerticalStack>
diff --git a/Samples/common/ui/Interfaces/Experimental/fileDialog.crow b/Samples/common/ui/Interfaces/Experimental/fileDialog.crow
new file mode 100644 (file)
index 0000000..90f9c70
--- /dev/null
@@ -0,0 +1,17 @@
+<VerticalStack> 
+       <HorizontalStack Height="Fit">
+               <Label Text="Hover:" Width="50" Foreground="Grey"/>
+               <Label Text="{HoverWidget}" Font="mono, 8"/>
+       </HorizontalStack>
+       <HorizontalStack Height="Fit">
+               <Label Text="Focus:" Width="50" Foreground="Grey"/>
+               <Label Text="{FocusedWidget}" Font="mono, 8"/>
+       </HorizontalStack>
+       <HorizontalStack Height="Fit">
+               <Label Text="Active:" Width="50" Foreground="Grey"/>
+               <Label Text="{ActiveWidget}" Font="mono, 8"/>
+       </HorizontalStack>
+       <Container>
+       <FileDialog Focusable="true" Resizable="true"/>
+       </Container>
+</VerticalStack>
\ No newline at end of file