]> O.S.I.I.S - jp/crow.git/commitdiff
in design iml values pos, custom config create directory, wip
authorJean-Philippe Bruyère <jp_bruyere@hotmail.com>
Thu, 24 Jul 2025 07:23:13 +0000 (09:23 +0200)
committerJean-Philippe Bruyère <jp_bruyere@hotmail.com>
Thu, 24 Jul 2025 07:23:13 +0000 (09:23 +0200)
14 files changed:
Crow/Crow.csproj
Crow/Default.style
Crow/src/Command/ActionCommand.cs
Crow/src/Command/CommandGroup.cs
Crow/src/Configuration.cs
Crow/src/IML/CompilerServices.cs
Crow/src/IML/Instantiator.cs
Crow/src/Widgets/Widget.cs
Drawing2D/src/ExtensionsMethods.cs
Samples/ShowCase/ShowCase.cs
Samples/common/src/SampleBase.cs
Samples/common/ui/Interfaces/Divers/bindings.crow [new file with mode: 0644]
Samples/common/ui/Interfaces/Experimental/icobut.crow
Samples/common/ui/Interfaces/Experimental/randomProgress.crow

index 9fdc56e04bdb1d53c55827c4d9c2929dc4a5e3dc..316345cf6ac3f16528e9ad1523df8314ac0b9780 100644 (file)
@@ -22,7 +22,7 @@
                <GeneratePackageOnBuild>True</GeneratePackageOnBuild>
                <GenerateDocumentationFile>true</GenerateDocumentationFile>
                <NoWarn>$(NoWarn);1591;1587;1570;1572;1573;1574</NoWarn>
-               <DefineConstants>MEASURE_TIME;_DEBUG_HIGHLIGHT_FOCUS</DefineConstants>
+               <DefineConstants>_MEASURE_TIME;_DEBUG_HIGHLIGHT_FOCUS</DefineConstants>
                <EnableDefaultItems>false</EnableDefaultItems>
                <EnableDefaultCompileItems>false</EnableDefaultCompileItems>
                <!--<AllowUnsafeBlocks>true</AllowUnsafeBlocks>-->
index df1c75d111d5e7d6e4b2b4578865821a265d19b0..21a13e75a10a84bc1acbde5f51c1fc9e439dac72 100644 (file)
@@ -6,10 +6,12 @@ ControlBorderWidth = "1";
 ControlCaptionHoverColor = "White";
 ControlCornerRadius = "0";
 ControlInsideMargin = "1";
+ControlIdle = "DimGrey";
 
 ButtonCaptionMargin = "6";
 
 IconSize = "11";
+WindowIconSize = "14";
 IconMargin = "1";
 ToggleIconSize = "16";
 
@@ -207,8 +209,8 @@ WindowIconBorder {
        BorderWidth="1";
        Margin="1";
        Foreground="Transparent";
-       Height="12";
-       Width="12";
+       Height="${WindowIconSize}";
+       Width="${WindowIconSize}";
        MouseEnter="{Foreground=Grey}";
        MouseLeave="{Foreground=Transparent}";
        MouseDown="{Background=${ControlHighlight}}";
index f484e0eda2a38f788e9c91fbf6dd0478561c97df..e2cff01ea1afb190c2b1eff92f5d42ef985ef975 100644 (file)
@@ -39,15 +39,27 @@ namespace Crow {
                {
                        execute = executeAction;
                }
+               public ActionCommand (ICommandHost _host, string caption, Action executeAction, string icon, KeyBinding _keyBinding,
+                                               Binding<bool> _canExecuteBinding)
+                       : base (_host, caption, icon, _keyBinding, _canExecuteBinding)
+               {
+                       execute = executeAction;
+               }
                public ActionCommand (ICommandHost _host, string caption, Action executeAction, string icon = null, KeyBinding _keyBinding = null,
-                                               Binding<bool> _canExecuteBinding = null)
+                                               bool _canExecute = true)
+                       : base (_host, caption, icon, _keyBinding, _canExecute)
+               {
+                       execute = executeAction;
+               }
+               public ActionCommand (ICommandHost _host, string caption, Action<object> executeAction, string icon, KeyBinding _keyBinding,
+                                               Binding<bool> _canExecuteBinding)
                        : base (_host, caption, icon, _keyBinding, _canExecuteBinding)
                {
                        execute = executeAction;
                }
                public ActionCommand (ICommandHost _host, string caption, Action<object> executeAction, string icon = null, KeyBinding _keyBinding = null,
-                                               Binding<bool> _canExecuteBinding = null)
-                       : base (_host, caption, icon, _keyBinding, _canExecuteBinding)
+                                               bool _canExecute = true)
+                       : base (_host, caption, icon, _keyBinding, _canExecute)
                {
                        execute = executeAction;
                }
index 6c5a76ba6866b106d53776e33231253a26940b10..2dc6e85aa4b24c7f81cb0d9d1d307bc44e772e31 100644 (file)
@@ -26,9 +26,9 @@ namespace Crow {
                public CommandGroup (params CommandBase[] commands) {
                        Commands = new ObservableList<CommandBase>(commands);
                }
-               public CommandGroup (ICommandHost host) {
+               /*public CommandGroup (ICommandHost host) {
 
-               }
+               }*/
 
 
                public int Count => Commands.Count;
index 28a5293af8f0392e97f6d879ae3e021f42842b72..055a26680d2edda5789f567a9f68fb07ac2ea240 100644 (file)
@@ -8,6 +8,7 @@ using System.IO;
 using System.Collections.Generic;
 using System.Threading;
 using System.Linq;
+using System.Runtime.CompilerServices;
 
 namespace Crow
 {
@@ -94,6 +95,9 @@ namespace Crow
                /// <param name="defaultConf">an optional text stream with default values.</param>
                public Configuration (string path, Stream defaultConf = null) {
                        configPath = path;
+                       string folder = Path.GetDirectoryName(configPath);
+                       if (!Directory.Exists(folder))
+                               Directory.CreateDirectory(folder);
                        if (File.Exists (configPath)) {
                                using (Stream s = new FileStream (configPath, FileMode.Open))
                                        load (s);
@@ -216,6 +220,16 @@ namespace Crow
                                items[key].Set (value);
                        isDirty = true;
                }
+               /*public void Set<T>(T value, [CallerMemberName] string key = null)
+               {
+                       if (!items.ContainsKey (key)) {
+                               lock(items)
+                                       items[key] = new ConfigItem (value);
+                       }else
+                               items[key].Set (value);
+                       isDirty = true;
+               }*/
+               
                /// <summary>
                /// Save this configuration store with the path provided on creation. This is done automaticaly normaly.
                /// </summary>
index da5c1f866ee823cad82c8e4a6e923f3df0220a55..2cea823d01741da4d7fbc91c2dc451d112e4d2b8 100644 (file)
@@ -99,7 +99,7 @@ namespace Crow.IML
                internal static FieldInfo fiWidget_design_column = typeof(Widget).GetField("design_column");
                internal static FieldInfo fiWidget_design_imlPath = typeof(Widget).GetField("design_imlPath");
                internal static FieldInfo fiWidget_design_iml_values = typeof(Widget).GetField("design_iml_values");
-
+               internal static MethodInfo miDesignAddValLoc = typeof(Widget).GetMethod("design_add_iml_location", BindingFlags.Instance | BindingFlags.NonPublic);
                #endif
 
                #region tree handling methods
index be46d20a1de32462d477e6d5b9256e6fcd820ca0..dc3e77da57a341fd3fd3f37e12bd7a8bd8a5d76b 100644 (file)
@@ -385,7 +385,7 @@ namespace Crow.IML {
                        }
                }
                #if DESIGN_MODE
-               void emitSetDesignAttribute (IMLContext ctx, string name, string value){
+               void emitSetDesignAttribute (IMLContext ctx, string name, string value, IXmlLineInfo li){
                        //store member value in iml
                        ctx.il.Emit (OpCodes.Ldloc_0);
                        ctx.il.Emit (OpCodes.Ldfld, CompilerServices.fiWidget_design_iml_values);
@@ -395,6 +395,18 @@ namespace Crow.IML {
                        else
                                ctx.il.Emit (OpCodes.Ldstr, value);
                        ctx.il.Emit (OpCodes.Call, CompilerServices.miDicStrStrAdd);
+
+                       ctx.il.Emit (OpCodes.Ldloc_0);
+                       ctx.il.Emit (OpCodes.Ldstr, name);
+                       if (string.IsNullOrEmpty(sourcePath))
+                               ctx.il.Emit (OpCodes.Ldnull);
+                       else
+                               ctx.il.Emit (OpCodes.Ldstr, sourcePath);
+                       //Debug.WriteLine($"{name}={value} l:{ctx.curLine}+{li.LineNumber} c:{li.LinePosition}");
+                       ctx.il.Emit (OpCodes.Ldc_I4, ctx.curLine + li.LineNumber - 1);
+                       ctx.il.Emit (OpCodes.Ldc_I4, li.LinePosition - 1);
+                       ctx.il.Emit (OpCodes.Call, CompilerServices.miDesignAddValLoc);
+               
                }
                #endif
 
@@ -408,15 +420,15 @@ namespace Crow.IML {
                                reader.Read ();
 
 #if DESIGN_MODE
-                               IXmlLineInfo li = (IXmlLineInfo)reader;
+                               IXmlLineInfo li = reader;
                                ctx.il.Emit (OpCodes.Ldloc_0);
                                ctx.il.Emit (OpCodes.Ldstr, this.NextDesignID);
                                ctx.il.Emit (OpCodes.Stfld, CompilerServices.fiWidget_design_id);
                                ctx.il.Emit (OpCodes.Ldloc_0);
-                               ctx.il.Emit (OpCodes.Ldc_I4, ctx.curLine + li.LineNumber);
+                               ctx.il.Emit (OpCodes.Ldc_I4, ctx.curLine + li.LineNumber - 1);
                                ctx.il.Emit (OpCodes.Stfld, CompilerServices.fiWidget_design_line);
                                ctx.il.Emit (OpCodes.Ldloc_0);
-                               ctx.il.Emit (OpCodes.Ldc_I4, li.LinePosition);
+                               ctx.il.Emit (OpCodes.Ldc_I4, li.LinePosition - 1);
                                ctx.il.Emit (OpCodes.Stfld, CompilerServices.fiWidget_design_column);
                                if (!string.IsNullOrEmpty (sourcePath)) {
                                        ctx.il.Emit (OpCodes.Ldloc_0);
@@ -431,7 +443,7 @@ namespace Crow.IML {
                                        if (!string.IsNullOrEmpty (style)) {
                                                CompilerServices.EmitSetValue (ctx.il, CompilerServices.piStyle, style);
 #if DESIGN_MODE
-                                               emitSetDesignAttribute (ctx, NT_style, style);
+                                               emitSetDesignAttribute (ctx, NT_style, style, reader);
 #endif
                                        }
                                        //check for dataSourceType, if set, datasource bindings will use direct setter/getter
@@ -457,7 +469,7 @@ namespace Crow.IML {
                                                        continue;
 
 #if DESIGN_MODE
-                                               emitSetDesignAttribute (ctx, reader.Name, reader.Value);
+                                               emitSetDesignAttribute (ctx, reader.Name, reader.Value, reader);
 #endif
                                                string imlValue = reader.Value;
                                                StringBuilder styledValue = new StringBuilder();
index 3fac43e268f10251562de75281683708555703b6..6f20a54bde5b95521c96579014098fcccbb99eba 100644 (file)
@@ -47,8 +47,6 @@ namespace Crow
 #if DESIGN_MODE
                static MethodInfo miDesignAddDefLoc = typeof(Widget).GetMethod("design_add_style_location",
                        BindingFlags.Instance | BindingFlags.NonPublic);
-               static MethodInfo miDesignAddValLoc = typeof(Widget).GetMethod("design_add_iml_location",
-                       BindingFlags.Instance | BindingFlags.NonPublic);
 
                public volatile bool design_HasChanged = false;
                public string design_id;
@@ -58,23 +56,24 @@ namespace Crow
                public bool design_isTGItem = false;//true if this is a templated item's root
                public Dictionary<string,string> design_iml_values = new Dictionary<string, string>();
                public Dictionary<string,string> design_style_values = new Dictionary<string, string>();
-               //public Dictionary<string,FileLocation> design_iml_locations = new Dictionary<string, FileLocation>();
+               public Dictionary<string,FileLocation> design_iml_locations = new Dictionary<string, FileLocation>();
                public Dictionary<string,FileLocation> design_style_locations = new Dictionary<string, FileLocation>();
 
                internal void design_add_style_location (string memberName, string path, int line, int col) {
                        if (design_style_locations.ContainsKey(memberName)){
-                               System.Diagnostics.Debug.WriteLine ("default value localtion already set for {0}{1}.{2}", this.GetType().Name, this.design_id, memberName);
+                               Debug.WriteLine ("default value location already set for {0}{1}.{2}", this.GetType().Name, this.design_id, memberName);
                                return;
                        }
                        design_style_locations.Add(memberName, new FileLocation(path,line,col));
                }
-//             internal void design_add_iml_location (string memberName, string path, int line, int col) {
-//                     if (design_iml_locations.ContainsKey(memberName)){
-//                             System.Diagnostics.Debug.WriteLine ("IML value localtion already set for {0}{1}.{2}", this.GetType().Name, this.design_id, memberName);
-//                             return;
-//                     }
-//                     design_iml_locations.Add(memberName, new FileLocation(path,line,col));
-//             }
+               internal void design_add_iml_location (string memberName, string path, int line, int col) {
+                       if (design_iml_locations.ContainsKey(memberName)){
+                               Debug.WriteLine ("IML value location already set for {0}{1}.{2}", this.GetType().Name, this.design_id, memberName);
+                               return;
+                       }
+                       //Debug.WriteLine ("IML value location added for {3}: {0}{1}.{2}", this.GetType().Name, this.design_id, memberName, path);
+                       design_iml_locations.Add(memberName, new FileLocation(path,line,col));
+               }
 
                public virtual bool FindByDesignID(string designID, out Widget go){
                        go = null;
index dba42420aeea51a1e275de0e3c52d0b4a34dd801..f58bc199d162fddd5596b177607c427b8b9e72a1 100644 (file)
@@ -29,6 +29,10 @@ namespace Crow
                        System.Buffer.BlockCopy(str.ToCharArray(), 0, bytes, 0, bytes.Length);
                        return bytes;
                }
+               public static bool IsWhiteSpace (this char c)
+               {
+                       return c == '\t' || char.IsWhiteSpace (c);
+               }               
                public static bool IsWhiteSpaceOrNewLine (this char c)
                {
                        return c == '\t' || c.IsAnyLineBreakCharacter() || char.IsWhiteSpace (c);
@@ -62,7 +66,12 @@ namespace Crow
                                return "".AsSpan ();
                        return str.AsSpan ().Slice (start, ls.LengthIncludingLineBreak);
                }
-
+               public static int CountLeadingWhiteSpaces (this ReadOnlySpan<char> str) {
+                       int i = 0;
+                       while (i < str.Length && str[i].IsWhiteSpace())
+                               i++;
+                       return i;
+               }
                public static ReadOnlySpan<char> ToCharSpan (this LineBreakKind lineBreak) {
                        switch (lineBreak) {
                        case LineBreakKind.Unix:
index 536fad90aff0ac307c611185ccef00d677e9257d..89e72224fea9660fc3518f0440b588f07c8b7151 100644 (file)
@@ -111,14 +111,11 @@ namespace ShowCase
                        }
                }
                public string TemplateContainerSource {
-                       get => Configuration.Global.Get<string> ("TemplateContainerSource", "<Button>");
+                       get => Configuration.Global.Get<string> ("TemplateContainerSource", "<Button/>");
                        set {
                                if (TemplateContainerSource == value)
                                        return;
-                               if (value != null && value.EndsWith ("/>"))
-                                       Configuration.Global.Set ("TemplateContainerSource", value.Remove (value.Length -2) + ">");
-                               else
-                                       Configuration.Global.Set ("TemplateContainerSource", value);
+                               Configuration.Global.Set ("TemplateContainerSource", value);
                                NotifyValueChanged (TemplateContainerSource);
                                if (!reloadChrono.IsRunning)
                                        reloadChrono.Restart ();
index 0aac787306950c5044d7dd1e85302a5ffe2f722b..2a14b5fab8afeaac893d65edbaaffa3c55d61f17 100644 (file)
@@ -204,6 +204,7 @@ namespace Samples
                        public void NotifyValueChanged(object _value, [CallerMemberName] string caller = null)
                                => ValueChanged.Raise(this, new ValueChangeEventArgs(caller, _value));
                        string prop1, prop2;
+                       bool boolProp;
                        public string Prop1
                        {
                                get => prop1;
@@ -228,18 +229,27 @@ namespace Samples
 
 
 
+                       }
+                       public bool BoolProp {
+                               get => boolProp;
+                               set {
+                                       if (boolProp == value)
+                                               return;
+                                       boolProp = value;
+                                       NotifyValueChanged(boolProp);
+                               }
                        }
 
                        public override string ToString()
                                        => $"{Prop1}, {Prop2}";
 
                }
-               TestClass tcInstance = new TestClass() { Prop1 = "instance 0 prop1 value", Prop2 = "instance 0 prop2 value" };
-               TestClassVC tcVCInstance;// = new TestClassVC () { Prop1 = "instance 0 prop1 value", Prop2 = "instance 0 prop2 value" };
-               TestClass tcInstance1 = new TestClass() { Prop1 = "instance 1 prop1 value", Prop2 = "instance 1 prop2 value" };
-               TestClassVC tcVCInstance1 = new TestClassVC() { Prop1 = "instance 1 prop1 value", Prop2 = "instance 1 prop2 value" };
-               TestClass tcInstance2 = new TestClass() { Prop1 = "instance 2 prop1 value", Prop2 = "instance 2 prop2 value" };
-               TestClassVC tcVCInstance2 = new TestClassVC() { Prop1 = "instance 2 prop1 value", Prop2 = "instance 2 prop2 value" };
+               public TestClass tcInstance = new TestClass() { Prop1 = "instance 0 prop1 value", Prop2 = "instance 0 prop2 value" };
+               public TestClassVC tcVCInstance = new TestClassVC () { Prop1 = "instance 0 prop1 value", Prop2 = "instance 0 prop2 value" };
+               public TestClass tcInstance1 = new TestClass() { Prop1 = "instance 1 prop1 value", Prop2 = "instance 1 prop2 value" };
+               public TestClassVC tcVCInstance1 = new TestClassVC() { Prop1 = "instance 1 prop1 value", Prop2 = "instance 1 prop2 value" };
+               public TestClass tcInstance2 = new TestClass() { Prop1 = "instance 2 prop1 value", Prop2 = "instance 2 prop2 value" };
+               public TestClassVC tcVCInstance2 = new TestClassVC() { Prop1 = "instance 2 prop1 value", Prop2 = "instance 2 prop2 value" };
 
                public TestClass TcInstance
                {
diff --git a/Samples/common/ui/Interfaces/Divers/bindings.crow b/Samples/common/ui/Interfaces/Divers/bindings.crow
new file mode 100644 (file)
index 0000000..daf49b7
--- /dev/null
@@ -0,0 +1,9 @@
+<Container Name="test" Background="Onyx" RootDataLevel="true">
+<VerticalStack   Fit="true"  >
+       <CheckBox DataSource="{TcVCInstance}" Style="CheckBox2" IsChecked="{²BoolProp}"/>
+       <CheckBox DataSource="{TcVCInstance}" IsChecked="{²BoolProp}"/>
+       <CheckBox DataSource="{TcVCInstance}" IsChecked="{²BoolProp}"/>
+       <TextBox DataSource="{TcVCInstance}" Text="{²Prop1}"/> 
+       <TextBox DataSource="{TcVCInstance}" Text="{²Prop1}"/>
+</VerticalStack>
+</Container>
\ No newline at end of file
index 68730dcfd1fec09566be5ef1e98366ff89fdee90..801507c612875fd1dafc699a3f0a1c475ede8edb 100644 (file)
                        </Border>
                </Template>
        </Button>
-
+       <Button Command="{SingleCommand}" Background="DimGrey" CornerRadius="8">
+               <Template>
+                       <Border Background="{./Background}" Name="Content" Margin="5" Tooltip="{./Caption}"
+                                                                               Foreground="Transparent" CornerRadius="{../CornerRadius}" BorderWidth="1"
+                                                                               MouseEnter="{Foreground=vgradient|0:White|0.2:Grey|0.9:Grey|1:Black}"
+                                                                               MouseLeave="{Foreground=Transparent}"
+                                                                               MouseDown="{Foreground=vgradient|0:Black|0.05:Grey|0.85:Grey|1:White};{Background=${ControlHighlight}}"
+                                                                               MouseUp="{Foreground=vgradient|0:White|0.2:Grey|0.9:Grey|1:Black};{Background=DimGrey}">
+                                       <Image Name="caption" Width="20" Height="20" Path="{./Icon}" />
+                       </Border>
+               </Template>
+       </Button>
        <Button Command="{SingleCommand}">
                <Template>
                        <Border Background="{./Background}" MinimumSize="50,20" Name="Content"
index ae78a76a0284bc36af0bf12d1ad469b5febf5faf..7227298fba6d3e9620fbfc89f5377dc95489bd3e 100644 (file)
@@ -2,8 +2,8 @@
        <VerticalStack Width="Fit" Background="DarkSlateGrey" Margin="10" Height="Fit">
                <HorizontalStack Height="Fit" Spacing="10">
                        <Label Text="Value:"/>
-                       <Spinner Name="slider" Width="100" Background="DarkGrey" LargeIncrement="20" SmallIncrement="5"
-                               Minimum="10" Maximum="1000" Value="{²RandomProgressItemCount}"/>
+                       <Spinner Name="slider" Width="100" Background="DarkGrey" LargeIncrement="500" SmallIncrement="5"
+                               Minimum="10" Maximum="10000" Value="{²RandomProgressItemCount}"/>
                </HorizontalStack>
        </VerticalStack>
        <ListBox UseLoadingThread="false" Data="{RandomProgressList}">