diff options
| author | Jean-Philippe Bruyère <jp_bruyere@hotmail.com> | 2025-07-24 09:23:13 +0200 |
|---|---|---|
| committer | Jean-Philippe Bruyère <jp_bruyere@hotmail.com> | 2025-07-24 09:23:13 +0200 |
| commit | 60e0e7d19c884fc8204be45c244a065e9085f98a (patch) | |
| tree | 62a39fe7fd033d9b252d7b2dc14f52fa0ffc7258 | |
| parent | afc11903ff9018a57aa54ab5339151f0a1a47ead (diff) | |
in design iml values pos, custom config create directory, wip
| -rw-r--r-- | Crow/Crow.csproj | 2 | ||||
| -rw-r--r-- | Crow/Default.style | 6 | ||||
| -rw-r--r-- | Crow/src/Command/ActionCommand.cs | 18 | ||||
| -rw-r--r-- | Crow/src/Command/CommandGroup.cs | 4 | ||||
| -rw-r--r-- | Crow/src/Configuration.cs | 14 | ||||
| -rw-r--r-- | Crow/src/IML/CompilerServices.cs | 2 | ||||
| -rw-r--r-- | Crow/src/IML/Instantiator.cs | 24 | ||||
| -rw-r--r-- | Crow/src/Widgets/Widget.cs | 21 | ||||
| -rw-r--r-- | Drawing2D/src/ExtensionsMethods.cs | 11 | ||||
| -rw-r--r-- | Samples/ShowCase/ShowCase.cs | 7 | ||||
| -rw-r--r-- | Samples/common/src/SampleBase.cs | 22 | ||||
| -rw-r--r-- | Samples/common/ui/Interfaces/Divers/bindings.crow | 9 | ||||
| -rw-r--r-- | Samples/common/ui/Interfaces/Experimental/icobut.crow | 13 | ||||
| -rw-r--r-- | Samples/common/ui/Interfaces/Experimental/randomProgress.crow | 4 |
14 files changed, 116 insertions, 41 deletions
diff --git a/Crow/Crow.csproj b/Crow/Crow.csproj index 9fdc56e0..316345cf 100644 --- a/Crow/Crow.csproj +++ b/Crow/Crow.csproj @@ -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>--> diff --git a/Crow/Default.style b/Crow/Default.style index df1c75d1..21a13e75 100644 --- a/Crow/Default.style +++ b/Crow/Default.style @@ -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}}"; diff --git a/Crow/src/Command/ActionCommand.cs b/Crow/src/Command/ActionCommand.cs index f484e0ed..e2cff01e 100644 --- a/Crow/src/Command/ActionCommand.cs +++ b/Crow/src/Command/ActionCommand.cs @@ -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; } diff --git a/Crow/src/Command/CommandGroup.cs b/Crow/src/Command/CommandGroup.cs index 6c5a76ba..2dc6e85a 100644 --- a/Crow/src/Command/CommandGroup.cs +++ b/Crow/src/Command/CommandGroup.cs @@ -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; diff --git a/Crow/src/Configuration.cs b/Crow/src/Configuration.cs index 28a5293a..055a2668 100644 --- a/Crow/src/Configuration.cs +++ b/Crow/src/Configuration.cs @@ -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> diff --git a/Crow/src/IML/CompilerServices.cs b/Crow/src/IML/CompilerServices.cs index da5c1f86..2cea823d 100644 --- a/Crow/src/IML/CompilerServices.cs +++ b/Crow/src/IML/CompilerServices.cs @@ -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 diff --git a/Crow/src/IML/Instantiator.cs b/Crow/src/IML/Instantiator.cs index be46d20a..dc3e77da 100644 --- a/Crow/src/IML/Instantiator.cs +++ b/Crow/src/IML/Instantiator.cs @@ -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(); diff --git a/Crow/src/Widgets/Widget.cs b/Crow/src/Widgets/Widget.cs index 3fac43e2..6f20a54b 100644 --- a/Crow/src/Widgets/Widget.cs +++ b/Crow/src/Widgets/Widget.cs @@ -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; diff --git a/Drawing2D/src/ExtensionsMethods.cs b/Drawing2D/src/ExtensionsMethods.cs index dba42420..f58bc199 100644 --- a/Drawing2D/src/ExtensionsMethods.cs +++ b/Drawing2D/src/ExtensionsMethods.cs @@ -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: diff --git a/Samples/ShowCase/ShowCase.cs b/Samples/ShowCase/ShowCase.cs index 536fad90..89e72224 100644 --- a/Samples/ShowCase/ShowCase.cs +++ b/Samples/ShowCase/ShowCase.cs @@ -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 (); diff --git a/Samples/common/src/SampleBase.cs b/Samples/common/src/SampleBase.cs index 0aac7873..2a14b5fa 100644 --- a/Samples/common/src/SampleBase.cs +++ b/Samples/common/src/SampleBase.cs @@ -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; @@ -229,17 +230,26 @@ 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 index 00000000..daf49b77 --- /dev/null +++ b/Samples/common/ui/Interfaces/Divers/bindings.crow @@ -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 diff --git a/Samples/common/ui/Interfaces/Experimental/icobut.crow b/Samples/common/ui/Interfaces/Experimental/icobut.crow index 68730dcf..801507c6 100644 --- a/Samples/common/ui/Interfaces/Experimental/icobut.crow +++ b/Samples/common/ui/Interfaces/Experimental/icobut.crow @@ -12,7 +12,18 @@ </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" diff --git a/Samples/common/ui/Interfaces/Experimental/randomProgress.crow b/Samples/common/ui/Interfaces/Experimental/randomProgress.crow index ae78a76a..7227298f 100644 --- a/Samples/common/ui/Interfaces/Experimental/randomProgress.crow +++ b/Samples/common/ui/Interfaces/Experimental/randomProgress.crow @@ -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}"> |