diff options
| author | Jean-Philippe Bruyère <jp_bruyere@hotmail.com> | 2021-07-12 08:45:51 +0200 |
|---|---|---|
| committer | Jean-Philippe Bruyère <jp_bruyere@hotmail.com> | 2021-07-12 08:45:51 +0200 |
| commit | 5c91d515f8e05171ff94323c49831f080a11adec (patch) | |
| tree | 524bdc58416c40c4bf007988dade3b051010771a | |
| parent | 5c30903a5f07342b1c2741240ff8dd173c1c641f (diff) | |
replace FastEnum with Enums.NET for flags handling, Bubbling event as Flag, requiredLayouting, MAXLAYOUTINGTRY=>30
78 files changed, 1296 insertions, 690 deletions
@@ -10,8 +10,6 @@ Project("{2150E333-8FDC-42A3-9474-1A3956D46DE8}") = "global", "global", "{728545 EndProject Project("{9A19103F-16F7-4668-BE54-9A1E7A4F7556}") = "Crow", "Crow\Crow.csproj", "{C2980F9B-4798-4C05-99E2-E174810F7C7B}" EndProject -Project("{9A19103F-16F7-4668-BE54-9A1E7A4F7556}") = "CrowDbgShared", "CrowDbgShared\CrowDbgShared.csproj", "{91F1CE07-EECE-4F1D-A3EE-7239B563654A}" -EndProject Project("{2150E333-8FDC-42A3-9474-1A3956D46DE8}") = "Samples", "Samples", "{B2C7855A-2878-47FD-AD32-9A83DB4AB8C6}" ProjectSection(SolutionItems) = preProject Samples\Directory.Build.props = Samples\Directory.Build.props @@ -57,8 +55,6 @@ Global {56329D48-D382-4850-93DE-59C453894E8A}.Debug|Any CPU.Build.0 = Debug|Any CPU {56329D48-D382-4850-93DE-59C453894E8A}.Release|Any CPU.ActiveCfg = Release|Any CPU {56329D48-D382-4850-93DE-59C453894E8A}.Release|Any CPU.Build.0 = Release|Any CPU - {91F1CE07-EECE-4F1D-A3EE-7239B563654A}.Debug|Any CPU.ActiveCfg = Debug|Any CPU - {91F1CE07-EECE-4F1D-A3EE-7239B563654A}.Release|Any CPU.ActiveCfg = Release|Any CPU {0CC6DFAB-2E4A-4786-976C-89053D5EA6A2}.Debug|Any CPU.ActiveCfg = Debug|Any CPU {0CC6DFAB-2E4A-4786-976C-89053D5EA6A2}.Debug|Any CPU.Build.0 = Debug|Any CPU {0CC6DFAB-2E4A-4786-976C-89053D5EA6A2}.Release|Any CPU.ActiveCfg = Release|Any CPU diff --git a/Crow/Crow.csproj b/Crow/Crow.csproj index d5d50114..972e22f1 100644 --- a/Crow/Crow.csproj +++ b/Crow/Crow.csproj @@ -39,7 +39,8 @@ <PackageReference Include="System.Reflection.Emit.Lightweight" Version="4.6.0" /> </ItemGroup> <ItemGroup> - <PackageReference Include="FastEnum" Version="1.5.3" /> + <!--<PackageReference Include="FastEnum" Version="1.5.3" />--> + <PackageReference Include="Enums.NET" Version="4.0.0" /> <PackageReference Include="glfw-sharp" Version="$(GlfwSharpVersion)" /> </ItemGroup> diff --git a/Crow/Default.style b/Crow/Default.style index 5c88c062..80131bce 100644 --- a/Crow/Default.style +++ b/Crow/Default.style @@ -134,6 +134,7 @@ MessageBox { //MinimumSize = "200,120"; AlwaysOnTop = "true"; Resizable = "false"; + AllowedStates = "Normal"; } Slider { Foreground = "Grey"; @@ -166,12 +167,15 @@ WindowIconBorder { Foreground="Transparent"; Height="12"; Width="12"; - MouseEnter="{Foreground=White}"; + MouseEnter="{Foreground=Grey}"; MouseLeave="{Foreground=Transparent}"; + MouseDown="{Background=${ControlHighlight}}"; + MouseUp="{Background=Transparent}"; } ToolWindow { Caption = "Window"; Template = "#Crow.ToolWindow.template"; + AllowedStates = "Normal"; Focusable = "true"; MinimumSize="50,50"; Width = "150"; @@ -183,7 +187,8 @@ DockStack { AllowDrop = "true"; AllowedDropTypes = "Crow.DockWindow"; } -DockWindow { +DockWindow { + AllowedStates = "Normal"; Focusable = "true"; AllowDrag = "true"; AllowDrop="true"; @@ -321,8 +326,9 @@ MessageBox, Popper, Slider, Spinner, TextBox, NumericControl { Background = "${ControlBackground}"; CornerRadius = "${ControlCornerRadius}"; Margin="0"; - BubbleMouseEvent="false"; + BubbleMouseEvent="MouseWheel|Keyboard"; } -TemplatedControl, GenericStack { - CacheEnabled="true"; -}
\ No newline at end of file + +//TemplatedControl, GenericStack { +// CacheEnabled="true"; +//}
\ No newline at end of file diff --git a/Crow/Icons/pin.svg b/Crow/Icons/pin.svg new file mode 100644 index 00000000..b36340b8 --- /dev/null +++ b/Crow/Icons/pin.svg @@ -0,0 +1,6 @@ +<?xml version="1.0" encoding="utf-8"?> +<!-- Generated by IcoMoon.io --> +<!DOCTYPE svg PUBLIC "-//W3C//DTD SVG 1.1//EN" "http://www.w3.org/Graphics/SVG/1.1/DTD/svg11.dtd"> +<svg version="1.1" xmlns="http://www.w3.org/2000/svg" xmlns:xlink="http://www.w3.org/1999/xlink" width="16" height="16" viewBox="0 0 16 16"> +<path fill="#dddddd" d="M11 6.5v-5.5h1v-1h-8v1h1v5.5c0 0-2 1.5-2 3.5 0 0.5 1.9 0.7 4 0.7v2.2c0 0.7 0.2 1.4 0.5 2.1l0.5 1 0.5-1c0.3-0.6 0.5-1.3 0.5-2.1v-2.2c2.1 0 4-0.3 4-0.7 0-2-2-3.5-2-3.5zM7 6.6c0 0-0.5 0.3-1.6 1.4-1 1-1.5 1.9-1.5 1.9s0.1-1 0.8-1.9c0.9-1.1 1.3-1.4 1.3-1.4v-5.6h1v5.6z"></path> +</svg> diff --git a/Crow/Icons/unpin.svg b/Crow/Icons/unpin.svg new file mode 100644 index 00000000..8396017f --- /dev/null +++ b/Crow/Icons/unpin.svg @@ -0,0 +1,9 @@ +<?xml version="1.0" encoding="utf-8"?> +<!-- Generated by IcoMoon.io --> +<!DOCTYPE svg PUBLIC "-//W3C//DTD SVG 1.1//EN" "http://www.w3.org/Graphics/SVG/1.1/DTD/svg11.dtd"> +<svg version="1.1" xmlns="http://www.w3.org/2000/svg" xmlns:xlink="http://www.w3.org/1999/xlink" width="16" height="16" viewBox="0 0 16 16"> + <path + fill="#dddddd" + d="M 9.8735488,10.133961 13.560108,6.0523834 14.302213,6.7226674 14.972497,5.9805624 9.0356558,0.61829343 8.3653726,1.3603984 9.1074778,2.0306824 5.420918,6.1122604 c 0,0 -2.4896355,-0.22741 -3.8302027,1.2568 -0.3351418,0.371053 0.9408011,1.793013 2.4992218,3.2006076 l -1.4746239,1.632631 c -0.4691985,0.519474 -0.789976,1.173004 -1.036543,1.893563 l -0.299231,1.077247 1.0413361,-0.406964 C 2.945677,14.521967 3.5632965,14.13655 4.0995234,13.542866 l 1.4746238,-1.632631 c 1.5584207,1.407596 3.1695056,2.458503 3.4376186,2.161661 1.3405672,-1.48421 0.861783,-3.937935 0.861783,-3.937935 z M 6.8380997,7.5270374 c 0,0 -0.5721376,-0.11251 -2.1257651,-0.03351 -1.4123886,0.07182 -2.3866964,0.404575 -2.3866964,0.404575 0,0 0.7444941,-0.675077 1.8672229,-0.873773 1.4052065,-0.21306 1.9031336,-0.167578 1.9031336,-0.167578 l 3.7535881,-4.155786 0.7421052,0.670284 z" + id="path2" /> +</svg> diff --git a/Crow/Templates/DirectoryView.template b/Crow/Templates/DirectoryView.template index 98094c90..7a157bdd 100644 --- a/Crow/Templates/DirectoryView.template +++ b/Crow/Templates/DirectoryView.template @@ -15,7 +15,7 @@ <ListItem Selected="{/exp.Background=${ControlHighlight}}" Unselected="{/exp.Background=Transparent}"> - <Expandable Name="exp" Caption="{Name}" MouseDoubleClick="/onClickForExpand" BubbleMouseEvent="true"> + <Expandable Name="exp" Caption="{Name}" MouseDoubleClick="/onClickForExpand" > <Template> <VerticalStack> <Border CornerRadius="2" Margin="0" Height="Fit" MouseDoubleClick="./onClickForExpand" diff --git a/Crow/Templates/DockWindow.template b/Crow/Templates/DockWindow.template index 7f6183e3..9e8e623a 100644 --- a/Crow/Templates/DockWindow.template +++ b/Crow/Templates/DockWindow.template @@ -5,23 +5,36 @@ <HorizontalStack Visible="{./IsDocked}" Height="Fit" Margin="1" Background="vgradient|0:0.3,0.5,0.8,0.9|1:0.1,0.1,0.1,0.9"> <Label Text="{./CurDir}" TextAlignment="Left" Width="Stretched" Foreground="White" /> - <Border CornerRadius="6" BorderWidth="1" Foreground="Transparent" Height="10" Width="10" - MouseEnter="{Foreground=White}" MouseLeave="{Foreground=Transparent}"> - <Image Focusable="true" Name="Image" Margin="0" Path="#Crow.Icons.exit2.svg" - MouseClick="./onQuitPress"/> - </Border> + <ListBox Data="{./DockCommands}" Fit="true"> + <Template> + <HorizontalStack Name="ItemsContainer" /> + </Template> + <ItemTemplate Path="#Crow.WindowButton.template"/> + </ListBox> + <ListBox Data="{./Commands}" Fit="true"> + <Template> + <HorizontalStack Name="ItemsContainer" /> + </Template> + <ItemTemplate Path="#Crow.WindowButton.template"/> + </ListBox> </HorizontalStack> <HorizontalStack Background="vgradient|0:0.5,0.6,0.5,0.5|1:0.2,0.3,0.3,0.7" Name="hs" Margin="0" Spacing="0" Height="Fit" Visible="{./IsFloating}"> <Widget Width="5"/> <Image Margin="1" Width="10" Height="10" Path="{./Icon}"/> <Label Width="Stretched" Foreground="White" Margin="1" TextAlignment="Left" Text="{./CurDir}" /> - <Border CornerRadius="6" BorderWidth="1" Foreground="Transparent" Height="10" Width="10" - MouseEnter="{Foreground=White}" MouseLeave="{Foreground=Transparent}"> - <Image Focusable="true" Name="Image" Margin="0" Path="#Crow.Icons.exit2.svg" - MouseClick="./onQuitPress"/> - </Border> - <Widget Width="5"/> + <ListBox Data="{./DockCommands}" Fit="true"> + <Template> + <HorizontalStack Name="ItemsContainer" /> + </Template> + <ItemTemplate Path="#Crow.WindowButton.template"/> + </ListBox> + <ListBox Data="{./Commands}" Fit="true"> + <Template> + <HorizontalStack Name="ItemsContainer" /> + </Template> + <ItemTemplate Path="#Crow.WindowButton.template"/> + </ListBox> </HorizontalStack> <Container Name="Content" MinimumSize="50,50"/> </VerticalStack> diff --git a/Crow/Templates/MenuItem.template b/Crow/Templates/MenuItem.template index d712d3fb..4945b009 100644 --- a/Crow/Templates/MenuItem.template +++ b/Crow/Templates/MenuItem.template @@ -1,7 +1,7 @@ <?xml version="1.0"?> <ListItem> <Popper Font="{./Font}" Caption="{./Caption}" Background="{./Background}" PopDirection="{./PopDirection}" - Foreground = "{./Foreground}" BubbleMouseEvent="true" + Foreground = "{./Foreground}" BubbleMouseEvent="All" IsPopped="{²./IsOpened}" PopWidth="{./PopWidth}" PopHeight="{./PopHeight}"> <Template> diff --git a/Crow/Templates/MessageBox.template b/Crow/Templates/MessageBox.template index 3cccc4d2..2598e57a 100644 --- a/Crow/Templates/MessageBox.template +++ b/Crow/Templates/MessageBox.template @@ -6,11 +6,12 @@ <Widget Width="5" /> <Image Margin="1" Width="12" Height="12" Path="{./Icon}"/> <Label Name="MoveHandle" Width="Stretched" Foreground="${WindowTitleBarForeground" Margin="2" TextAlignment="Center" Text="{./Caption}" /> - <Border CornerRadius="3" BorderWidth="1" Foreground="Transparent" Height="12" Width="12" - MouseEnter="{Foreground=White}" MouseLeave="{Foreground=Transparent}"> - <Image Focusable="true" Name="Image" Path="#Crow.Icons.exit2.svg" - MouseClick="./onQuitPress"/> - </Border> + <ListBox Data="{./Commands}" Fit="true"> + <Template> + <HorizontalStack Name="ItemsContainer" /> + </Template> + <ItemTemplate Path="#Crow.WindowButton.template"/> + </ListBox> <Widget Width="5" /> </HorizontalStack> <HorizontalStack Margin="5" > diff --git a/Crow/Templates/ToolWindow.template b/Crow/Templates/ToolWindow.template index b0af1c5d..40ac987b 100644 --- a/Crow/Templates/ToolWindow.template +++ b/Crow/Templates/ToolWindow.template @@ -7,11 +7,12 @@ <Widget Width="5"/> <Image Margin="1" Width="12" Height="12" Path="{./Icon}"/> <Label Width="Stretched" Foreground="{./TitleBarForeground}" Margin="1" TextAlignment="Center" Text="{./Caption}" /> - <Border CornerRadius="6" BorderWidth="1" Foreground="Transparent" Height="12" Width="12" - MouseEnter="{Foreground=White}" MouseLeave="{Foreground=Transparent}"> - <Image Focusable="true" Name="Image" Margin="0" Width="Stretched" Height="Stretched" Path="#Crow.Icons.exit2.svg" - MouseClick="./onQuitPress"/> - </Border> + <ListBox Data="{./Commands}" Fit="true"> + <Template> + <HorizontalStack Name="ItemsContainer" /> + </Template> + <ItemTemplate Path="#Crow.WindowButton.template"/> + </ListBox> <Widget Width="5"/> </HorizontalStack> <Container Name="Content" MinimumSize="50,50"/> diff --git a/Crow/Templates/Window.template b/Crow/Templates/Window.template index a1de29de..9ea0cd98 100644 --- a/Crow/Templates/Window.template +++ b/Crow/Templates/Window.template @@ -5,23 +5,12 @@ <Widget Width="5"/> <Image Margin="1" Width="12" Height="12" Path="{./Icon}"/> <Label Name="MoveHandle" Width="Stretched" Foreground="${WindowTitleBarForeground" Margin="2" TextAlignment="Center" Text="{./Caption}" /> - <Border Visible="{./ShowMinimize}" Style="WindowIconBorder"> - <Image Focusable="true" Path="#Crow.Icons.minimize.svg" - MouseClick="./onMinimized"/> - </Border> - <Border Visible="{./ShowNormal}" Style="WindowIconBorder"> - <Image Focusable="true" Path="#Crow.Icons.normalize.svg" - MouseClick="./onUnmaximized"/> - </Border> - <Border Visible="{./ShowMaximize}" Style="WindowIconBorder"> - <Image Focusable="true" Path="#Crow.Icons.maximize.svg" - MouseClick="./onMaximized"/> - </Border> - <Border BorderWidth="1" Style="WindowIconBorder"> - <Image Focusable="true" Path="#Crow.Icons.exit2.svg" - MouseClick="./onQuitPress"/> - </Border> - <Widget Width="5"/> + <ListBox Data="{./Commands}" Fit="true"> + <Template> + <HorizontalStack Name="ItemsContainer" /> + </Template> + <ItemTemplate Path="#Crow.WindowButton.template"/> + </ListBox> </HorizontalStack> <Container Name="Content" MinimumSize="0,0" /> </VerticalStack> diff --git a/Crow/Templates/WindowButton.template b/Crow/Templates/WindowButton.template new file mode 100644 index 00000000..19ce8f90 --- /dev/null +++ b/Crow/Templates/WindowButton.template @@ -0,0 +1,9 @@ +<?xml version="1.0"?> +<Button Command="{}" MinimumSize="0,0" > + <Template> + <Border Style="WindowIconBorder" IsVisible="{./IsEnabled}"> + <Image Path="{./Icon}" Tooltip="{./Caption}"/> + </Border> + </Template> +</Button> + diff --git a/Crow/src/Colors.cs b/Crow/src/Colors.cs index c1152031..323cba2e 100644 --- a/Crow/src/Colors.cs +++ b/Crow/src/Colors.cs @@ -5,7 +5,7 @@ using System; using System.Collections.Generic; using System.Linq; -using FastEnumUtility; +//using FastEnumUtility; namespace Crow { @@ -332,7 +332,7 @@ namespace Crow => value.GetHashCode (); public override string ToString() - => FastEnum.IsDefined<Colors> (value) ? FastEnum.GetName((Colors)value) : HtmlCode; + => EnumsNET.Enums.IsValid<Colors> ((Colors)value) ? EnumsNET.Enums.GetName((Colors)value) : HtmlCode; public static Color FromIml (string iml) { @@ -357,7 +357,7 @@ namespace Crow new Color (0xff + (UInt32.Parse (s.AsSpan ().Slice (1), System.Globalization.NumberStyles.HexNumber)<<8)) : new Color (UInt32.Parse (s.AsSpan().Slice (1), System.Globalization.NumberStyles.HexNumber)) : char.IsDigit(s[0]) ? FromIml (s) : - FastEnum.TryParse<Colors> (s, out Colors cc) ? new Color(cc) : + EnumsNET.Enums.TryParse<Colors> (s, out Colors cc) ? new Color(cc) : throw new Exception ("Unknown color name: " + s); public static Color FromHSV (double _h, double _v = 0xff, double _s = 0xff, double _alpha = 0xff) { diff --git a/Crow/src/Configuration.cs b/Crow/src/Configuration.cs index a04a80e4..55bbeefb 100644 --- a/Crow/src/Configuration.cs +++ b/Crow/src/Configuration.cs @@ -85,6 +85,13 @@ namespace Crow } startSavingThread (); } + /// <summary> + /// Create readonly configuration + /// </summary> + /// <param name="defaultConf"></param> + public Configuration (Stream defaultConf = null) { + load (defaultConf); + } static Configuration () { @@ -146,6 +153,14 @@ namespace Crow return !items.ContainsKey (key) ? default(T) : items [key].GetValue<T> (); } /// <summary> + /// retrive the value of the configuration key given in parameter + /// </summary> + /// <param name="key">option name</param> + public T Get<T>(string key, T defaultValue) + { + return !items.ContainsKey (key) ? defaultValue : items [key].GetValue<T> (); + } + /// <summary> /// store the value of the configuration key given in parameter /// </summary> /// <param name="key">option name</param> diff --git a/Crow/src/DebugUtils/DbgEvent.cs b/Crow/src/DebugUtils/DbgEvent.cs index c43cc15a..1b6144f2 100644 --- a/Crow/src/DebugUtils/DbgEvent.cs +++ b/Crow/src/DebugUtils/DbgEvent.cs @@ -14,6 +14,7 @@ namespace Crow.DebugLogger public int threadId; public DbgEvtType type; public DbgEvtType Category => type & DbgEvtType.All; + public string Message; public DbgEvent parentEvent; public bool HasChildEvents => Events != null && Events.Count > 0; public override long Duration => end - begin; @@ -22,6 +23,7 @@ namespace Crow.DebugLogger public double EndMS => Math.Round ((double)end / Stopwatch.Frequency, 6); public virtual bool IsWidgetEvent => false; public virtual bool IsLayoutEvent => false; + public bool HasMessage => !string.IsNullOrEmpty(Message); public void AddEvent (DbgEvent evt) { @@ -33,21 +35,22 @@ namespace Crow.DebugLogger } public DbgEvent () { } - public DbgEvent (long timeStamp, DbgEvtType evt) + public DbgEvent (long timeStamp, DbgEvtType evt, string message = null) { type = evt; begin = timeStamp; end = timeStamp; threadId = Thread.CurrentThread.ManagedThreadId; + Message = message; } public static DbgEvent Parse (string str) { if (str == null) return null; - string [] tmp = str.Trim ().Split (';'); + 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)) @@ -56,27 +59,30 @@ namespace Crow.DebugLogger end = long.Parse (tmp [1]), threadId = int.Parse (tmp [2]), type = evtType, - InstanceIndex = int.Parse (tmp [4]), - layouting = (LayoutingType)Enum.Parse (typeof (LayoutingType), tmp [5]), + Message = tmp[4], + InstanceIndex = int.Parse (tmp [5]), + layouting = (LayoutingType)Enum.Parse (typeof (LayoutingType), tmp [6]), result = evtType == DbgEvtType.GOProcessLayouting ? - (LayoutingQueueItem.Result)Enum.Parse (typeof (LayoutingQueueItem.Result), tmp [6]) + (LayoutingQueueItem.Result)Enum.Parse (typeof (LayoutingQueueItem.Result), tmp [7]) : LayoutingQueueItem.Result.Unknown, - OldSlot = Rectangle.Parse (tmp [7]), - NewSlot = Rectangle.Parse (tmp [8]), + OldSlot = Rectangle.Parse (tmp [8]), + NewSlot = Rectangle.Parse (tmp [9]), }; - return (tmp.Length < 5) ? + return (tmp.Length < 6) ? new DbgWidgetEvent () { begin = long.Parse (tmp [0]), end = long.Parse (tmp [1]), threadId = int.Parse (tmp [2]), type = evtType, + Message = tmp[4], InstanceIndex = -1, } : new DbgWidgetEvent () { begin = long.Parse (tmp [0]), end = long.Parse (tmp [1]), threadId = int.Parse (tmp [2]), type = evtType, - InstanceIndex = int.Parse (tmp [4]), + Message = tmp[4], + InstanceIndex = int.Parse (tmp [5]), }; } return new DbgEvent () { @@ -84,12 +90,13 @@ namespace Crow.DebugLogger end = long.Parse (tmp [1]), threadId = int.Parse (tmp [2]), type = evtType, + Message = tmp[4] }; } public virtual string Print () - => $"{begin,10}:{threadId,-2}:{type,-20}:"; + => $"{begin,10}:{threadId,-2}:{type,-20}:{Message}"; public override string ToString () - => $"{begin};{end};{threadId};{type}"; + => $"{begin};{end};{threadId};{type};{Message}"; public virtual Color Color { get { switch (type) { diff --git a/Crow/src/DebugUtils/DbgEvtType.cs b/Crow/src/DebugUtils/DbgEvtType.cs index b7f16acb..be7f66dd 100644 --- a/Crow/src/DebugUtils/DbgEvtType.cs +++ b/Crow/src/DebugUtils/DbgEvtType.cs @@ -57,6 +57,8 @@ namespace Crow GORegisterForRedraw = Widget | 0x0C, GOComputeChildrenPositions = Widget | 0x0D, GOOnChildLayoutChange = Widget | 0x0E, + GOAdjustStretchedGo = Widget | 0x0F, + GOSetProperty = Widget | 0x10, AlreadyDisposed = Widget | Dispose | Error | 0x01, DisposedByGC = Widget | Dispose | Error | 0x02, diff --git a/Crow/src/DebugUtils/DbgLayoutEvent.cs b/Crow/src/DebugUtils/DbgLayoutEvent.cs index 4444fe3d..750ac31a 100644 --- a/Crow/src/DebugUtils/DbgLayoutEvent.cs +++ b/Crow/src/DebugUtils/DbgLayoutEvent.cs @@ -34,20 +34,21 @@ namespace Crow.DebugLogger => $"{base.ToString ()};{layouting};{result};{OldSlot};{NewSlot}"; public override Color Color { get { - if (type == DbgEvtType.GORegisterLayouting) - return Colors.GreenYellow; - if (type == DbgEvtType.GOProcessLayoutingWithNoParent) - return Colors.DarkRed; - switch (result) { - case LayoutingQueueItem.Result.Success: - return Colors.Green; - case LayoutingQueueItem.Result.Deleted: - return Colors.Red; - case LayoutingQueueItem.Result.Discarded: - return Colors.OrangeRed; - default: - return Colors.Orange; - } } + if (type == DbgEvtType.GORegisterLayouting) + return Colors.GreenYellow; + if (type == DbgEvtType.GOProcessLayoutingWithNoParent) + return Colors.DarkRed; + switch (result) { + case LayoutingQueueItem.Result.Success: + return Colors.Green; + case LayoutingQueueItem.Result.Deleted: + return Colors.Red; + case LayoutingQueueItem.Result.Discarded: + return Colors.OrangeRed; + default: + return Colors.Orange; + } + } } } }
\ No newline at end of file diff --git a/Crow/src/DebugUtils/DbgWidgetEvent.cs b/Crow/src/DebugUtils/DbgWidgetEvent.cs index 9b9a2b15..383fc94a 100644 --- a/Crow/src/DebugUtils/DbgWidgetEvent.cs +++ b/Crow/src/DebugUtils/DbgWidgetEvent.cs @@ -23,10 +23,17 @@ namespace Crow.DebugLogger public override Color Color { get { switch (type) { + case DbgEvtType.GOSetProperty: + return Colors.Lime; case DbgEvtType.GOMeasure: + return Colors.Pink; case DbgEvtType.GOSearchLargestChild: case DbgEvtType.GOSearchTallestChild: return Colors.HotPink; + case DbgEvtType.GOOnChildLayoutChange: + return Colors.DarkViolet; + case DbgEvtType.GOAdjustStretchedGo: + return Colors.PaleVioletRed; case DbgEvtType.GOClassCreation: return Colors.DarkSlateGrey; case DbgEvtType.GOInitialization: diff --git a/Crow/src/DebugUtils/DbgWidgetRecord.cs b/Crow/src/DebugUtils/DbgWidgetRecord.cs index 2fde7377..6b0bfb5f 100644 --- a/Crow/src/DebugUtils/DbgWidgetRecord.cs +++ b/Crow/src/DebugUtils/DbgWidgetRecord.cs @@ -23,9 +23,7 @@ namespace Crow.DebugLogger //useful to track events for obj shown later, not on start public int InstanceIndex; public int yIndex;//index in parenting, the whole main graphic tree is one continuous suite - public int xLevel;//depth - public String Width; - public String Height; + public int xLevel;//depth public static DbgWidgetRecord Parse (string str) { @@ -37,8 +35,6 @@ namespace Crow.DebugLogger g.InstanceIndex = int.Parse (tmp [1]); g.yIndex = int.Parse (tmp [2]); g.xLevel = int.Parse (tmp [3]); - g.Width = tmp [4]; - g.Height = tmp [5]; return g; } diff --git a/Crow/src/DebugUtils/DebugLogger.cs b/Crow/src/DebugUtils/DebugLogger.cs index e048008f..b773b990 100644 --- a/Crow/src/DebugUtils/DebugLogger.cs +++ b/Crow/src/DebugUtils/DebugLogger.cs @@ -69,7 +69,24 @@ namespace Crow } #endif } - +[Conditional ("DEBUG_LOG")] + public static void SetMsg (DbgEvtType evtType, string message) + { +#if DEBUG_LOG + if (!logevt (evtType)) + return; +lock (logMutex) { + chrono.Stop (); + if (!startedEvents.ContainsKey (Thread.CurrentThread.ManagedThreadId)) + throw new Exception ("Current thread has no event started"); + DbgEvent e = startedEvents [Thread.CurrentThread.ManagedThreadId].Peek (); + if (e.type != evtType) + throw new Exception ($"Begin/end event logging mismatch: {e.type}/{evtType}"); + e.Message = message; + chrono.Start (); + } +#endif + } [Conditional ("DEBUG_LOG")] public static void EndEvent (DbgEvtType evtType, bool discardIfNoChildEvents = false) { @@ -149,6 +166,20 @@ namespace Crow } #endif } + [Conditional("DEBUG_LOG")] + public static void AddEventWithMsg (DbgEvtType evtType, string message, params object [] data) { +#if DEBUG_LOG + if (!logevt (evtType)) + return; + + lock (logMutex) { + chrono.Stop (); + DbgEvent evt = addEventInternal (evtType, data); + evt.Message = message; + chrono.Start (); + } +#endif + } #if DEBUG_LOG static DbgEvent addEventInternal (DbgEvtType evtType, params object [] data) @@ -156,10 +187,19 @@ namespace Crow DbgEvent evt = null; if (data == null || data.Length == 0) evt = new DbgEvent (chrono.ElapsedTicks, evtType); - else if (data [0] is Widget w) + else if (data [0] is Widget w) { evt = new DbgWidgetEvent (chrono.ElapsedTicks, evtType, w.instanceIndex); - else if (data [0] is LayoutingQueueItem lqi) - evt = new DbgLayoutEvent (chrono.ElapsedTicks, evtType, lqi.graphicObject.instanceIndex, lqi.LayoutType, lqi.result, lqi.Slot, lqi.NewSlot); + if (evtType == DbgEvtType.GONewParent) { + if (data[1] is Widget wi) + evt.Message = $"{wi.instanceIndex}"; + else if (data[1] is Interface) + evt.Message = "Interface"; + else + evt.Message = $"{data[1]}"; + } + + } else if (data [0] is LayoutingQueueItem lqi) + evt = new DbgLayoutEvent (chrono.ElapsedTicks, evtType, (lqi.Layoutable as Widget).instanceIndex, lqi.LayoutType, lqi.result, lqi.Slot, lqi.NewSlot); else evt = new DbgEvent (chrono.ElapsedTicks, evtType); @@ -245,7 +285,7 @@ namespace Crow writer.WriteLine ("[GraphicObjects]"); for (int i = startingWidgetsIndex; i < Widget.GraphicObjects.Count; i++) { Widget g = Widget.GraphicObjects [i]; - writer.WriteLine ($"{g.GetType ().Name};{g.instanceIndex};{g.yIndex};{g.xLevel};{g.Width};{g.Height}"); + writer.WriteLine ($"{g.GetType ().Name};{g.instanceIndex};{g.yIndex};{g.xLevel}"); } } diff --git a/Crow/src/Fill/SolidColor.cs b/Crow/src/Fill/SolidColor.cs index 8ed77fbe..40c7cdc1 100644 --- a/Crow/src/Fill/SolidColor.cs +++ b/Crow/src/Fill/SolidColor.cs @@ -40,32 +40,17 @@ namespace Crow public static implicit operator Color(SolidColor c) => c.color; public static implicit operator SolidColor(Color c) => new SolidColor (c); - //public static bool operator ==(SolidColor left, SolidColor right) => left?.color == right?.color; - //public static bool operator !=(SolidColor left, SolidColor right) => left?.color != right?.color; - - public override int GetHashCode () - { - return color.GetHashCode(); - } + public override int GetHashCode () => color.GetHashCode(); public override bool Equals (object obj) => obj is Color c ? color.Equals (c) : obj is Colors cl ? color.Equals(cl) : obj is SolidColor sc && color.Equals (sc.color); public static SolidColor operator *(SolidColor c, Double f) - { - return new SolidColor(new Color(c.color.R,c.color.G,c.color.B,c.color.A * f)); - } + => new SolidColor(new Color(c.color.R,c.color.G,c.color.B,c.color.A * f)); public static SolidColor operator +(SolidColor c1, SolidColor c2) - { - return new SolidColor(new Color(c1.color.R + c2.color.R,c1.color.G + c2.color.G,c1.color.B + c2.color.B,c1.color.A + c2.color.A)); - } + => new SolidColor(new Color(c1.color.R + c2.color.R,c1.color.G + c2.color.G,c1.color.B + c2.color.B,c1.color.A + c2.color.A)); public static SolidColor operator -(SolidColor c1, SolidColor c2) - { - return new SolidColor(new Color(c1.color.R - c2.color.R,c1.color.G - c2.color.G,c1.color.B - c2.color.B,c1.color.A - c2.color.A)); - } + => new SolidColor(new Color(c1.color.R - c2.color.R,c1.color.G - c2.color.G,c1.color.B - c2.color.B,c1.color.A - c2.color.A)); #endregion - public override string ToString() - { - return color.ToString (); - } + public override string ToString() => color.ToString (); } } diff --git a/Crow/src/Font.cs b/Crow/src/Font.cs index f05c6fb1..1ec0b2cc 100644 --- a/Crow/src/Font.cs +++ b/Crow/src/Font.cs @@ -4,7 +4,7 @@ using System; using Crow.Cairo; -using FastEnumUtility; +//using FastEnumUtility; namespace Crow { @@ -88,7 +88,7 @@ namespace Crow f.Name = tmp.ToString (); else { f.Name = tmp.Slice (0, ioc).ToString (); - f.Style = FastEnum.Parse<FontStyle> (tmp.Slice (ioc + 1).ToString (), true); + f.Style = EnumsNET.Enums.Parse<FontStyle> (tmp.Slice (ioc + 1).ToString (), true); } } return f; diff --git a/Crow/src/IML/CompilerServices.cs b/Crow/src/IML/CompilerServices.cs index e5d426d1..75248505 100644 --- a/Crow/src/IML/CompilerServices.cs +++ b/Crow/src/IML/CompilerServices.cs @@ -12,7 +12,7 @@ using System.Runtime.CompilerServices; using System.Xml; using Crow.IML; using System.Text; -using FastEnumUtility; +//using FastEnumUtility; namespace Crow.IML { @@ -32,9 +32,8 @@ namespace Crow.IML internal static MethodInfo stringEquals = typeof (string).GetMethod("Equals", new Type [3] { typeof (string), typeof (string), typeof (StringComparison) }); internal static MethodInfo miObjToString = typeof(object).GetMethod("ToString"); internal static MethodInfo miGetType = typeof(object).GetMethod("GetType"); - internal static MethodInfo miParseEnum = typeof(Enum).GetMethod("Parse", BindingFlags.Static | BindingFlags.Public, - Type.DefaultBinder, new Type [] {typeof (Type), typeof (string), typeof (bool)}, null); - internal static MethodInfo miParseEnumInversedParams = typeof(CompilerServices).GetMethod ("ParseEnum", BindingFlags.Static | BindingFlags.NonPublic); + internal static MethodInfo miParseEnum = typeof(CompilerServices).GetMethod("parseEnum", BindingFlags.Static | BindingFlags.NonPublic); + internal static MethodInfo miParseEnumInversedParams = typeof(CompilerServices).GetMethod ("parseEnumInverseParams", BindingFlags.Static | BindingFlags.NonPublic); internal static MethodInfo miGetTypeFromHandle = typeof(Type).GetMethod("GetTypeFromHandle"); internal static MethodInfo miGetEvent = typeof(Type).GetMethod("GetEvent", new Type[] {typeof(string)}); @@ -219,9 +218,7 @@ namespace Crow.IML il.Emit(OpCodes.Ldtoken, pi.PropertyType); il.Emit(OpCodes.Call, CompilerServices.miGetTypeFromHandle); //load enum value name - il.Emit (OpCodes.Ldstr, Convert.ToString (val));//TODO:implement here string format? - //load false - il.Emit (OpCodes.Ldc_I4_0); + il.Emit (OpCodes.Ldstr, Convert.ToString (val));//TODO:implement here string format? il.Emit (OpCodes.Call, CompilerServices.miParseEnum); if (CompilerServices.miParseEnum.ReturnType != pi.PropertyType) @@ -416,23 +413,28 @@ namespace Crow.IML foundMI = null; if (assembly == null) return false; - foreach (Type t in assembly.GetTypes ().Where - (ty => ty.IsDefined (typeof (ExtensionAttribute), false))) { - foreach (MethodInfo mi in t.GetMethods - (BindingFlags.Static | BindingFlags.Public | BindingFlags.NonPublic).Where - (m=> m.Name == methodName && m.IsDefined (typeof (ExtensionAttribute), false) && - m.GetParameters ().Length > 0)) { - Type curType = extendedType; - while (curType != null) { - if (mi.GetParameters () [0].ParameterType == curType) { - foundMI = mi; - return true; - } - curType = curType.BaseType; - } - } - + try + { + + foreach (Type t in assembly.GetExportedTypes().Where + (ty => ty.IsDefined (typeof (ExtensionAttribute), false))) { + foreach (MethodInfo mi in t.GetMethods + (BindingFlags.Static | BindingFlags.Public | BindingFlags.NonPublic).Where + (m=> m.Name == methodName && m.IsDefined (typeof (ExtensionAttribute), false) && + m.GetParameters ().Length > 0)) { + Type curType = extendedType; + while (curType != null) { + if (mi.GetParameters () [0].ParameterType == curType) { + foundMI = mi; + return true; + } + curType = curType.BaseType; + } + } + + } } + catch (System.Exception) {} return false; } /// <summary> @@ -632,7 +634,6 @@ namespace Crow.IML } } } - internal static object ParseEnum (string str, Type enumType) => Enum.Parse (enumType, str); internal static bool isValueType (object obj) => obj.GetType ().IsValueType; /// <summary> @@ -873,16 +874,16 @@ namespace Crow.IML knownTypes.Add (strDataType, dataType); return dataType; } - foreach (Assembly a in AppDomain.CurrentDomain.GetAssemblies ()) { - if (a.IsDynamic) - continue; - foreach (Type expT in a.GetExportedTypes ()) { - if (expT.Name != strDataType && expT.FullName != strDataType) - continue; - if (!knownTypes.ContainsKey(strDataType)) - knownTypes.Add (strDataType, expT); - return expT; - } + foreach (Assembly a in Interface.crowAssemblies) { + try { + foreach (Type expT in a.GetExportedTypes ()) { + if (expT.Name != strDataType && expT.FullName != strDataType) + continue; + if (!knownTypes.ContainsKey(strDataType)) + knownTypes.Add (strDataType, expT); + return expT; + } + }catch{} } knownTypes.Add (strDataType, null); return null; @@ -1016,6 +1017,25 @@ namespace Crow.IML mi.MemberType == MemberTypes.Field ? (mi as FieldInfo).FieldType : mi.MemberType == MemberTypes.Property ? (mi as PropertyInfo).PropertyType : mi.MemberType == MemberTypes.Method ? (mi as MethodInfo).ReturnType : null; + + /*internal static object parseEnum (Type enumType, string val) + => EnumsNET.FlagEnums.IsFlagEnum (enumType) ? + EnumsNET.FlagEnums.ParseFlags (enumType, val, true, "|") : + EnumsNET.Enums.Parse (enumType, val, true);*/ + internal static object parseEnum (Type enumType, string val) { + try + { + return EnumsNET.FlagEnums.IsFlagEnum (enumType) ? + EnumsNET.FlagEnums.ParseFlags (enumType, val, true, "|") : + EnumsNET.Enums.Parse (enumType, val, true); + } + catch (System.Exception) + { + Console.WriteLine($"{enumType} {val}"); + throw; + } + } + internal static object parseEnumInverseParams (string str, Type enumType) => parseEnum (enumType, str); } } diff --git a/Crow/src/IML/Instantiator.cs b/Crow/src/IML/Instantiator.cs index 855e8669..7a2472ae 100644 --- a/Crow/src/IML/Instantiator.cs +++ b/Crow/src/IML/Instantiator.cs @@ -732,8 +732,6 @@ namespace Crow.IML { il.Emit (OpCodes.Call, CompilerServices.miGetTypeFromHandle); //load enum value name il.Emit (OpCodes.Ldstr, operandes [1].Trim ()); - //load false - il.Emit (OpCodes.Ldc_I4_0); } else { lopParseMi = lopPI.PropertyType.GetMethod ("Parse"); if (lopParseMi == null) diff --git a/Crow/src/Input/MouseEventArgs.cs b/Crow/src/Input/MouseEventArgs.cs index e64e9a1b..9d3badda 100644 --- a/Crow/src/Input/MouseEventArgs.cs +++ b/Crow/src/Input/MouseEventArgs.cs @@ -2,14 +2,31 @@ // Copyright (c) 2014-2020 Jean-Philippe Bruyère <jp_bruyere@hotmail.com> // // This code is licensed under the MIT license (MIT) (http://opensource.org/licenses/MIT) +using System; using Glfw; namespace Crow { + [Flags] + public enum DeviceEventType { + None = 0x00, + MouseMove = 0x01, + ButtonDown = 0x02, + ButtonUp = 0x04, + Buttons = ButtonDown | ButtonUp, + MouseClick = 0x08, + MouseWheel = 0x10, + Mouse = Buttons | MouseWheel | MouseClick | MouseMove, + KeyDown = 0x20, + KeyUp = 0x40, + KeyPress = 0x80, + Keyboard = KeyDown | KeyUp | KeyPress, + All = Mouse | Keyboard + } public class MouseEventArgs : CrowEventArgs { public readonly int X, Y; - public Point Position => new Point (X, Y); + public Point Position => new Point (X, Y); public MouseEventArgs () { } public MouseEventArgs (int x, int y) { X = x; diff --git a/Crow/src/Interface.cs b/Crow/src/Interface.cs index a32577ce..44f0a786 100644 --- a/Crow/src/Interface.cs +++ b/Crow/src/Interface.cs @@ -60,6 +60,22 @@ namespace Crow #endregion internal static List<Assembly> crowAssemblies = new List<Assembly> (); + public void AddCrowAssembly (Assembly a) { + lock (UpdateMutex) { + if (crowAssemblies.Contains (a)) + return; + crowAssemblies.Add (a); + loadStylingFromAssembly (a); + } + } + public void RemoveCrowAssembly (Assembly a) { + lock (UpdateMutex) { + if (!crowAssemblies.Contains (a)) + return; + crowAssemblies.Remove (a); + init_internal (); + } + } #region CTOR static Interface () @@ -458,10 +474,10 @@ namespace Crow public const int MaxCacheSize = 2048; /// <summary> Above this count, the layouting is discard from the current /// update cycle and requeued for the next</summary> - public const int MaxLayoutingTries = 3; + public static int MaxLayoutingTries = 30; /// <summary> Above this count, the layouting is discard for the widget and it /// will not be rendered on screen </summary> - public const int MaxDiscardCount = 5; + public static int MaxDiscardCount = 5; /// <summary> Global font rendering settings for Cairo </summary> public static FontOptions FontRenderingOptions; /// <summary> Global font rendering settings for Cairo </summary> @@ -1244,8 +1260,7 @@ namespace Crow lock (UpdateMutex) GraphicTree.Insert (ptr, g); - - g.RegisteredLayoutings = LayoutingType.None; + g.RegisterForLayouting (LayoutingType.Sizing | LayoutingType.ArrangeChildren); return g; @@ -1658,47 +1673,48 @@ namespace Crow public virtual bool OnMouseButtonUp (MouseButton button) { DbgLogger.StartEvent (DbgEvtType.MouseUp); - mouseRepeatTimer.Reset (); - lastMouseDownEvent = null; - if (DragAndDropInProgress) { - if (DragAndDropOperation.DropTarget != null) - DragAndDropOperation.DragSource.onDrop (this, DragAndDropOperation); - else - DragAndDropOperation.DragSource.onEndDrag (this, DragAndDropOperation); - DragAndDropOperation = null; - if (ActiveWidget != null) { - ActiveWidget.onMouseUp (_activeWidget, new MouseButtonEventArgs (MousePosition.X, MousePosition.Y, button, InputAction.Release)); - ActiveWidget = null; - } - DbgLogger.EndEvent (DbgEvtType.MouseUp); - return true; - } + try { + mouseRepeatTimer.Reset (); + lastMouseDownEvent = null; - if (_activeWidget == null) { - DbgLogger.EndEvent (DbgEvtType.MouseUp); - return false; - } + if (DragAndDropInProgress) { + if (DragAndDropOperation.DropTarget != null) + DragAndDropOperation.DragSource.onDrop (this, DragAndDropOperation); + else + DragAndDropOperation.DragSource.onEndDrag (this, DragAndDropOperation); + DragAndDropOperation = null; + if (ActiveWidget != null) { + ActiveWidget.onMouseUp (_activeWidget, new MouseButtonEventArgs (MousePosition.X, MousePosition.Y, button, InputAction.Release)); + ActiveWidget = null; + } + return true; + } - _activeWidget.onMouseUp (_activeWidget, new MouseButtonEventArgs (MousePosition.X, MousePosition.Y, button, InputAction.Release)); + if (_activeWidget == null) + return false; - if (_activeWidget == null) { - Debug.WriteLine ("[BUG]Mystery reset of _activeWidget"); - DbgLogger.EndEvent (DbgEvtType.MouseUp | DbgEvtType.Error); - return true; - } + _activeWidget.onMouseUp (_activeWidget, new MouseButtonEventArgs (MousePosition.X, MousePosition.Y, button, InputAction.Release)); - 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 (_activeWidget == null) { + DbgLogger.SetMsg (DbgEvtType.MouseUp, "[BUG]Mystery reset of _activeWidget"); + return true; + } - ActiveWidget = null; - // if (!lastActive.MouseIsIn (Mouse.Position)) { - // ProcessMouseMove (Mouse.X, Mouse.Y); - // } - DbgLogger.EndEvent (DbgEvtType.MouseUp); - 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)); + + ActiveWidget = null; + // if (!lastActive.MouseIsIn (Mouse.Position)) { + // ProcessMouseMove (Mouse.X, Mouse.Y); + // } + + return true; + } finally { + DbgLogger.EndEvent (DbgEvtType.MouseUp); + } } /// <summary> /// Forward the mouse wheel event from the host to the crow interface @@ -1909,7 +1925,7 @@ namespace Crow else ctxMenuContainer.IsOpened = true; - ctxMenuContainer.BubbleMouseEvent = false; + ctxMenuContainer.BubbleMouseEvent = DeviceEventType.None; ctxMenuContainer.LogicalParent = go; ctxMenuContainer.DataSource = go; @@ -1957,6 +1973,10 @@ namespace Crow get => LayoutingType.None; set { throw new NotImplementedException (); } } + public LayoutingType RequiredLayoutings { + get => LayoutingType.None; + set { throw new NotImplementedException (); } + } public void RegisterForLayouting (LayoutingType layoutType) { throw new NotImplementedException (); } public bool UpdateLayout (LayoutingType layoutType) { throw new NotImplementedException (); } public Rectangle ContextCoordinates (Rectangle r) => r; diff --git a/Crow/src/ItemTemplate.cs b/Crow/src/ItemTemplate.cs index 9a5700a6..dc8e29c0 100644 --- a/Crow/src/ItemTemplate.cs +++ b/Crow/src/ItemTemplate.cs @@ -220,7 +220,9 @@ namespace Crow //dm is unbound, arg0 is instance of Item container to expand dm = new DynamicMethod ("dyn_count_" + fetchMethodName, typeof (bool), new Type[] {typeof(object)}, true); - il = dm.GetILGenerator (256); + il = dm.GetILGenerator (256); + System.Reflection.Emit.Label end = il.DefineLabel (); + System.Reflection.Emit.Label test = il.DefineLabel (); //get the dataSource of the arg0 il.Emit (OpCodes.Ldarg_0); @@ -235,11 +237,22 @@ namespace Crow il.Emit (OpCodes.Call, CompilerServices.miGetDataTypeAndFetch); }else emitGetSubData(il, dataType); - } - - il.Emit (OpCodes.Callvirt, CompilerServices.miGetColCount); + } + il.Emit (OpCodes.Isinst, typeof(System.Collections.ICollection)); + il.Emit (OpCodes.Dup);//duplicate children for testing if it's a collection for childs counting + il.Emit (OpCodes.Brtrue, test);//if true, jump to perform count + il.Emit (OpCodes.Pop);//pop null + il.Emit (OpCodes.Ldc_I4_0);//push false + il.Emit (OpCodes.Br, end); + + il.MarkLabel (test); + + il.Emit (OpCodes.Callvirt, CompilerServices.miGetColCount); il.Emit (OpCodes.Ldc_I4_0); il.Emit (OpCodes.Cgt); + + il.MarkLabel (end); + il.Emit (OpCodes.Ret); HasSubItems = (BooleanTestOnInstance)dm.CreateDelegate (typeof(BooleanTestOnInstance)); #endregion diff --git a/Crow/src/LayoutingQueueItem.cs b/Crow/src/LayoutingQueueItem.cs index 3cfdaa47..a9a634c3 100644 --- a/Crow/src/LayoutingQueueItem.cs +++ b/Crow/src/LayoutingQueueItem.cs @@ -17,7 +17,7 @@ namespace Crow Height = 0x08, Sizing = 0x0C, ArrangeChildren = 0x10, - All = 0xFF + All = Positioning | Sizing | ArrangeChildren } /// <summary> @@ -43,21 +43,6 @@ namespace Crow } #if DEBUG_LOG public Result result; - public Widget graphicObject { - get { return Layoutable as Widget; } - } - public string Name { - get { return graphicObject.Name; } - } - public string FullName { - get { return graphicObject.ToString(); } - } - public Measure Width { - get { return graphicObject.Width; } - } - public Measure Height { - get { return graphicObject.Height; } - } public Rectangle Slot, NewSlot; #endif @@ -88,45 +73,62 @@ namespace Crow try { - if (go.Parent == null) {//TODO:improve this - //cancel layouting for object without parent, maybe some were in queue when - //removed from a listbox - DbgLogger.AddEvent (DbgEvtType.GOProcessLayoutingWithNoParent, this); + if (!go.layoutMutex.TryEnterWriteLock (1)) { + go.IFace.LayoutingQueue.Enqueue (this); +#if DEBUG_LOG + result = Result.Requeued; +#endif return; } + + try { + if (go.Parent == null) {//TODO:improve this + //cancel layouting for object without parent, maybe some were in queue when + //removed from a listbox + DbgLogger.AddEvent (DbgEvtType.GOProcessLayoutingWithNoParent, this); + return; + } #if DEBUG_LOG - Slot = graphicObject.Slot; + Slot = Layoutable.getSlot (); +#endif + LayoutingTries++; + + if (Layoutable.UpdateLayout (LayoutType)) { + Layoutable.RequiredLayoutings &= (~LayoutType); + if (Layoutable.RequiredLayoutings == LayoutingType.None && go.IsDirty) + go.IFace.EnqueueForRepaint (this); +#if DEBUG_LOG + result = Result.Success; #endif - LayoutingTries++; - if (!Layoutable.UpdateLayout (LayoutType)) { - if (LayoutingTries < Interface.MaxLayoutingTries) { - Layoutable.RegisteredLayoutings |= LayoutType; - (Layoutable as Widget).IFace.LayoutingQueue.Enqueue (this); + } else { + if (LayoutingTries < Interface.MaxLayoutingTries) { + Layoutable.RegisteredLayoutings |= LayoutType; + go.IFace.LayoutingQueue.Enqueue (this); #if DEBUG_LOG - result = Result.Requeued; + result = Result.Requeued; #endif - } else if (DiscardCount < Interface.MaxDiscardCount) { + } else if (DiscardCount < Interface.MaxDiscardCount) { #if DEBUG_LOG - result = Result.Discarded; + result = Result.Discarded; #endif - LayoutingTries = 0; - DiscardCount++; - Layoutable.RegisteredLayoutings |= LayoutType; - (Layoutable as Widget).IFace.DiscardQueue.Enqueue (this); - } + LayoutingTries = 0; + DiscardCount++; + Layoutable.RegisteredLayoutings |= LayoutType; + go.IFace.DiscardQueue.Enqueue (this); + } #if DEBUG_LOG - else { - result = Result.Deleted; + else { + result = Result.Deleted; + } +#endif } +#if DEBUG_LOG + NewSlot = Layoutable.getSlot(); #endif + } finally { + go.layoutMutex.ExitWriteLock (); } -#if DEBUG_LOG - else{ - result = Result.Success; - } - NewSlot = graphicObject.Slot; -#endif - }finally { + } finally { go.parentRWLock.ExitReadLock (); DbgLogger.EndEvent (DbgEvtType.GOProcessLayouting, this); } diff --git a/Crow/src/ObservableList.cs b/Crow/src/ObservableList.cs index dc211f0a..3cfe101a 100644 --- a/Crow/src/ObservableList.cs +++ b/Crow/src/ObservableList.cs @@ -10,7 +10,7 @@ using System.Collections; namespace Crow { - public class ObservableList<T> : IList<T>, IObservableList, IValueChange { + public class ObservableList<T> : IList<T>, IObservableList, IValueChange, ICollection { #region IValueChange implementation public event EventHandler<ValueChangeEventArgs> ValueChanged; public virtual void NotifyValueChanged (string MemberName, object _value) @@ -62,6 +62,10 @@ namespace Crow public bool IsReadOnly => false; + public bool IsSynchronized => throw new NotImplementedException(); + + public object SyncRoot => throw new NotImplementedException(); + public T this[int index] { get => items[index]; set { @@ -157,6 +161,8 @@ namespace Crow public IEnumerator<T> GetEnumerator() => items.GetEnumerator (); IEnumerator IEnumerable.GetEnumerator() => items.GetEnumerator (); + + public void CopyTo(Array array, int index) => items.ToArray().CopyTo (array, index); } } diff --git a/Crow/src/Widgets/ColorPicker.cs b/Crow/src/Widgets/ColorPicker.cs index 3ea8b547..58810666 100644 --- a/Crow/src/Widgets/ColorPicker.cs +++ b/Crow/src/Widgets/ColorPicker.cs @@ -34,7 +34,7 @@ namespace Crow } } public IList<Colors> AvailableColors => //Enum.GetValues (typeof (Color)).ToList<Color> ();// Colors. ColorDic.Values.OrderBy (c => c.Hue).ToList (); - FastEnumUtility.FastEnum.GetValues<Colors> ().ToList<Colors> (); + EnumsNET.Enums.GetValues<Colors> ().ToList<Colors> (); public void onSelectedItemChanged(object sender, SelectionChangeEventArgs e) { CurrentColor = (Color)(Colors)e.NewValue; diff --git a/Crow/src/Widgets/DockStack.cs b/Crow/src/Widgets/DockStack.cs index 41c7f8b4..3d70a84e 100644 --- a/Crow/src/Widgets/DockStack.cs +++ b/Crow/src/Widgets/DockStack.cs @@ -4,7 +4,6 @@ using System; using System.Text; -using FastEnumUtility; namespace Crow { @@ -289,9 +288,9 @@ namespace Crow } //read next value in config string until next ';' - string getConfAttrib (string conf, ref int i) { - int nextI = conf.Substring (i).IndexOf (';'); - string tmp = conf.Substring (i, nextI); + ReadOnlySpan<char> getConfAttrib (ReadOnlySpan<char> conf, ref int i) { + int nextI = conf.Slice (i).IndexOf (';'); + ReadOnlySpan<char> tmp = conf.Slice (i, nextI); i += nextI + 1; return tmp; } @@ -300,12 +299,12 @@ namespace Crow /// </summary> /// <param name="conf">Conf.</param> /// <param name="dataSource">Data source for the docked windows</param> - public void ImportConfig (string conf, object dataSource = null) { + public void ImportConfig (ReadOnlySpan<char> conf, object dataSource = null) { lock (IFace.UpdateMutex) { ClearChildren (); stretchedChild = null; int i = 0; - Orientation = FastEnum.Parse<Orientation> (getConfAttrib (conf, ref i)); + Orientation = EnumsNET.Enums.Parse<Orientation> (getConfAttrib (conf, ref i).ToString()); importConfig (conf, ref i, dataSource); } } @@ -313,38 +312,39 @@ namespace Crow return Orientation.ToString() + ";" + exportConfig(); } - DockWindow importDockWinConfig (string conf, ref int i, object dataSource){ + DockWindow importDockWinConfig (ReadOnlySpan<char> conf, ref int i, object dataSource){ DockWindow dw = null; - string wName = getConfAttrib (conf, ref i); + string wName = getConfAttrib (conf, ref i).ToString(); try { dw = IFace.CreateInstance (wName) as DockWindow; - } catch { + } catch (Exception ex){ + Console.WriteLine ($"[importDockWinConfig]{ex}"); dw = new DockWindow (IFace); } dw.Name = wName; - dw.Width = Measure.Parse (getConfAttrib (conf, ref i)); - dw.Height = Measure.Parse (getConfAttrib (conf, ref i)); - dw.DockingPosition = FastEnum.Parse<Alignment> (getConfAttrib (conf, ref i)); - dw.savedSlot = Rectangle.Parse (getConfAttrib (conf, ref i)); - dw.wasResizable = Boolean.Parse (getConfAttrib (conf, ref i)); + dw.Width = Measure.Parse (getConfAttrib (conf, ref i).ToString()); + dw.Height = Measure.Parse (getConfAttrib (conf, ref i).ToString()); + dw.DockingPosition = EnumsNET.Enums.Parse<Alignment> (getConfAttrib (conf, ref i).ToString()); + dw.savedSlot = Rectangle.Parse (getConfAttrib (conf, ref i).ToString()); + dw.wasResizable = Boolean.Parse (getConfAttrib (conf, ref i).ToString()); dw.Resizable = false; dw.DataSource = dataSource; return dw; } - void importConfig (string conf, ref int i, object dataSource) { + void importConfig (ReadOnlySpan<char> conf, ref int i, object dataSource) { if (conf [i++] != '(') return; DockWindow dw = null; while (i < conf.Length - 4) { - string sc = conf.Substring (i, 4); + string sc = conf.Slice (i, 4).ToString(); i += 4; switch (sc) { case "TVI;": TabView tv = new TabView (IFace, "DockingTabView"); - tv.Width = Measure.Parse (getConfAttrib (conf, ref i)); - tv.Height = Measure.Parse (getConfAttrib (conf, ref i)); + tv.Width = Measure.Parse (getConfAttrib (conf, ref i).ToString()); + tv.Height = Measure.Parse (getConfAttrib (conf, ref i).ToString()); this.AddChild (tv); i++; while (conf [i] != ')') { @@ -361,9 +361,9 @@ namespace Crow break; case "STK;": DockStack ds = new DockStack (IFace); - ds.Width = Measure.Parse (getConfAttrib (conf, ref i)); - ds.Height = Measure.Parse (getConfAttrib (conf, ref i)); - ds.Orientation = FastEnum.Parse<Orientation> (getConfAttrib (conf, ref i)); + ds.Width = Measure.Parse (getConfAttrib (conf, ref i).ToString()); + ds.Height = Measure.Parse (getConfAttrib (conf, ref i).ToString()); + ds.Orientation = EnumsNET.Enums.Parse<Orientation> (getConfAttrib (conf, ref i).ToString()); this.AddChild (ds); @@ -371,8 +371,8 @@ namespace Crow break; case "SPL;": Splitter sp = new Splitter (IFace); - sp.Width = Measure.Parse (getConfAttrib (conf, ref i)); - sp.Height = Measure.Parse (getConfAttrib (conf, ref i)); + sp.Width = Measure.Parse (getConfAttrib (conf, ref i).ToString()); + sp.Height = Measure.Parse (getConfAttrib (conf, ref i).ToString()); sp.Thickness = int.Parse (getConfAttrib (conf, ref i)); this.AddChild (sp); break; @@ -387,11 +387,11 @@ namespace Crow for (int i = 0; i < Children.Count; i++) { if (Children [i] is DockWindow dw) - tmp.Append (dw.GetConfigString()); + tmp.Append (dw.GetDockConfigString()); else if (Children [i] is TabView tv) { tmp.Append ($"TVI;{tv.Width};{tv.Height};("); foreach (DockWindow d in tv.Items) - tmp.Append (d.GetConfigString().Substring(4)); + tmp.Append (d.GetDockConfigString().Substring(4)); tmp.Append (")"); }else if (Children [i] is DockStack ds) tmp.Append ($"STK;{ds.Width};{ds.Height};{ds.Orientation};{ds.exportConfig()}"); diff --git a/Crow/src/Widgets/DockWindow.cs b/Crow/src/Widgets/DockWindow.cs index af47ce3a..7f36dad4 100644 --- a/Crow/src/Widgets/DockWindow.cs +++ b/Crow/src/Widgets/DockWindow.cs @@ -16,13 +16,20 @@ namespace Crow public DockWindow (Interface iface) : base (iface) {} #endregion + protected override void loadTemplate(Widget template = null) + { + initCommands (); + + base.loadTemplate (template); + } + int undockThreshold = 10; bool isDocked = false; Alignment docking = Alignment.Undefined; Point undockingMousePosOrig; //mouse pos when docking was donne, use for undocking on mouse move internal Rectangle savedSlot; //last undocked slot recalled when view is undocked - internal bool wasResizable; + internal bool wasResizable, freezeDockState; public bool IsDocked { get { return isDocked; } @@ -40,6 +47,35 @@ namespace Crow [XmlIgnore] public bool IsDockedInTabView => LogicalParent is TabView; [XmlIgnore] public bool IsDockedInStack => Parent is DockStack; + public Command CMDFreezeDockState, CMDUnfreezeDockState; + public CommandGroup DockCommands => new CommandGroup (CMDFreezeDockState, CMDUnfreezeDockState); + void initCommands () { + CMDFreezeDockState = new Command ("Freeze Dock State", () => FreezeDockState = true, "#Crow.Icons.unpin.svg", !FreezeDockState); + CMDUnfreezeDockState = new Command ("Unfreeze Dock State", () => FreezeDockState = false, "#Crow.Icons.pin.svg", FreezeDockState); + } + + /// <summary> + /// if true, current dock status (docked or undocked) is frozen, and trying to move the + /// window will not trigger docking try. + /// </summary> + /// <value></value> + public bool FreezeDockState { + get { return freezeDockState; } + set { + if (freezeDockState == value) + return; + freezeDockState = value; + NotifyValueChangedAuto (freezeDockState); + + if (CMDFreezeDockState == null) + initCommands (); + else { + CMDFreezeDockState.CanExecute = !freezeDockState; + CMDUnfreezeDockState.CanExecute = freezeDockState; + } + } + } + public Alignment DockingPosition { get { return docking; } set { @@ -49,27 +85,22 @@ namespace Crow NotifyValueChangedAuto (DockingPosition); } } - /*public override bool PointIsIn (ref Point m) - { - if (!base.PointIsIn(ref m)) - return false; - - Group p = Parent as Group; - if (p != null) { - lock (p.Children) { - for (int i = p.Children.Count - 1; i >= 0; i--) { - if (p.Children [i] == this) - break; - if (p.Children [i].IsDragged) - continue; - if (p.Children [i].Slot.ContainsOrIsEqual (m)) { - return false; - } - } - } + Group floatingGroup; + /// <summary> + /// If null, the default container for the floating windows is the Interface. If a valid + /// group is set, undocked windows will be contained in this widget, allowing multiple independant levels + /// of dockable windows + /// </summary> + /// <value></value> + public Group FloatingGroup { + get => floatingGroup; + set { + if (floatingGroup == value) + return; + floatingGroup = value; + NotifyValueChangedAuto (floatingGroup); } - return Slot.ContainsOrIsEqual(m); - }*/ + } bool tryGetTargetDockStack (DockWindow dw, out DockStack ds) { if (dw.Parent is DockStack dwp) @@ -83,14 +114,14 @@ namespace Crow bool dockParentParent = false; public override void onDrag (object sender, MouseMoveEventArgs e) { - if (isDocked) - CheckUndock (e.Position); + if (!freezeDockState && isDocked) + checkUndock (e.Position); else moveAndResize (e.XDelta, e.YDelta, currentDirection); base.onDrag (sender, e); - if (isDocked) + if (freezeDockState || isDocked) return; Alignment dockingPosSave = DockingPosition; @@ -190,16 +221,6 @@ namespace Crow if (this.HasFocus && IsDocked && e.Button == MouseButton.Left) undockingMousePosOrig = e.Position; } - public bool CheckUndock (Point mousePos) { - //if (DockingPosition == Alignment.Center) - // return false; - System.Diagnostics.Debug.WriteLine ($"{mousePos.X},{mousePos.Y}"); - if (Math.Abs (mousePos.X - undockingMousePosOrig.X) < undockThreshold || - Math.Abs (mousePos.X - undockingMousePosOrig.X) < undockThreshold) - return false; - Undock (); - return true; - } protected override void onStartDrag (object sender, DragDropEventArgs e) { @@ -246,6 +267,8 @@ namespace Crow tv.Dispose(); w.IsVisible = true; ds.checkAlignments(); + w.NotifyValueChanged ("IsDockedInTabView", false); + w.NotifyValueChanged ("IsDockedInStack", true); } } else if (Parent is DockStack ds) { ds.Undock (this); @@ -264,7 +287,16 @@ namespace Crow Resizable = wasResizable; } } - + bool checkUndock (Point mousePos) { + //if (DockingPosition == Alignment.Center) + // return false; + System.Diagnostics.Debug.WriteLine ($"{mousePos.X},{mousePos.Y}"); + if (Math.Abs (mousePos.X - undockingMousePosOrig.X) < undockThreshold || + Math.Abs (mousePos.X - undockingMousePosOrig.X) < undockThreshold) + return false; + Undock (); + return true; + } void dock () { IFace.RemoveWidget (this); @@ -276,9 +308,8 @@ namespace Crow LastSlots = LastPaintedSlot = Slot = default(Rectangle); Left = Top = 0; } - public void Dock (DockWindow target) { + void Dock (DockWindow target) { lock (IFace.UpdateMutex) { - //IsDocked = true; dock (); if (target.LogicalParent is TabView tv) { @@ -299,11 +330,14 @@ namespace Crow tv2.AddItem (this); target.Width = target.Height = this.Width = this.Height = Measure.Stretched; target.DockingPosition = this.DockingPosition = Alignment.Center; + target.NotifyValueChanged ("IsDockedInTabView", true); + target.NotifyValueChanged ("IsDockedInStack", false); + IsDocked = true; } } } - public void Dock (DockStack target){ + void Dock (DockStack target){ lock (IFace.UpdateMutex) { dock (); @@ -318,8 +352,34 @@ namespace Crow base.close (); } - internal string GetConfigString () => + internal string GetDockConfigString () => string.Format($"WIN;{Name};{Width};{Height};{DockingPosition};{savedSlot};{wasResizable};"); + + + public string FloatingConfigString => + $"{Name};{Left};{Top};{Width};{Height};{FreezeDockState};{Resizable}"; + public static DockWindow CreateFromFloatingConfigString (Interface iface, ReadOnlySpan<char> conf, object datasource = null) { + int i = conf.IndexOf (';'); + string wname = conf.Slice(0, i).ToString(); + DockWindow dw = iface.CreateInstance (wname) as DockWindow; + dw.Name = wname; + conf = conf.Slice (i + 1); i = conf.IndexOf (';'); + dw.Left = int.Parse (conf.Slice(0, i).ToString()); + conf = conf.Slice (i + 1); i = conf.IndexOf (';'); + dw.Top = int.Parse (conf.Slice(0, i).ToString()); + conf = conf.Slice (i + 1); i = conf.IndexOf (';'); + dw.Width = Measure.Parse (conf.Slice(0, i).ToString()); + conf = conf.Slice (i + 1); i = conf.IndexOf (';'); + dw.Height = Measure.Parse (conf.Slice(0, i).ToString()); + conf = conf.Slice (i + 1); i = conf.IndexOf (';'); + dw.FreezeDockState = bool.Parse (conf.Slice(0, i).ToString()); + + dw.Resizable = bool.Parse (conf.Slice (i + 1).ToString()); + dw.DataSource = datasource; + + iface.AddWidget (dw); + return dw; + } } } diff --git a/Crow/src/Widgets/Expandable.cs b/Crow/src/Widgets/Expandable.cs index e2a7818b..d63249bb 100644 --- a/Crow/src/Widgets/Expandable.cs +++ b/Crow/src/Widgets/Expandable.cs @@ -46,9 +46,12 @@ namespace Crow } } #endregion + public override void OnDataSourceChanged(object sender, DataSourceChangeEventArgs e) + { + base.OnDataSourceChanged(sender, e); + NotifyValueChanged ("IsExpandable", IsExpandable); - public BooleanTestOnInstance GetIsExpandable; - + } /// <summary> /// mouse click event handler for easy expand triggering in IML /// </summary> @@ -96,7 +99,7 @@ namespace Crow [XmlIgnore]public bool IsExpandable { get { try { - return GetIsExpandable == null ? true : GetIsExpandable (this); + return IsToggleable == null ? true : IsToggleable (this); } catch (Exception ex) { System.Diagnostics.Debug.WriteLine ("Not Expandable error: " + ex.ToString ()); return false; diff --git a/Crow/src/Widgets/GenericStack.cs b/Crow/src/Widgets/GenericStack.cs index 29329611..5ae3ac36 100644 --- a/Crow/src/Widgets/GenericStack.cs +++ b/Crow/src/Widgets/GenericStack.cs @@ -56,14 +56,26 @@ namespace Crow { layoutType &= (~LayoutingType.Y); } public override int measureRawSize (LayoutingType lt) { - int totSpace = Math.Max (0, Spacing * (Children.Count (c => c.IsVisible) - 1)); - if (lt == LayoutingType.Width) { - if (Orientation == Orientation.Horizontal) - return contentSize.Width + totSpace + 2 * Margin; - } else if (Orientation == Orientation.Vertical) - return contentSize.Height + totSpace + 2 * Margin; + DbgLogger.StartEvent(DbgEvtType.GOMeasure, this, lt); + try { + + int totSpace = Math.Max (0, Spacing * (Children.Count (c => c.IsVisible) - 1)); + if (lt == LayoutingType.Width) { + if (Orientation == Orientation.Horizontal) + //return contentSize.Width + totSpace + 2 * Margin; + return stretchedGO == null ? + contentSize.Width + totSpace + 2 * Margin : + contentSize.Width + stretchedGO.measureRawSize(lt) + totSpace + 2 * Margin; + } else if (Orientation == Orientation.Vertical) + //return contentSize.Height + totSpace + 2 * Margin; + return stretchedGO == null ? + contentSize.Height + totSpace + 2 * Margin : + contentSize.Height + stretchedGO.measureRawSize(lt) + totSpace + 2 * Margin; - return base.measureRawSize (lt); + return base.measureRawSize (lt); + } finally { + DbgLogger.EndEvent(DbgEvtType.GOMeasure); + } } public virtual void ComputeChildrenPositions () { DbgLogger.StartEvent(DbgEvtType.GOComputeChildrenPositions, this); @@ -76,6 +88,7 @@ namespace Crow { c.Slot.X = d; c.OnLayoutChanges (LayoutingType.X); c.LastSlots.X = c.Slot.X; + IsDirty = true; } d += c.Slot.Width + Spacing; } @@ -87,11 +100,11 @@ namespace Crow { c.Slot.Y = d; c.OnLayoutChanges (LayoutingType.Y); c.LastSlots.Y = c.Slot.Y; + IsDirty = true; } d += c.Slot.Height + Spacing; } - } - IsDirty = true; + } DbgLogger.EndEvent(DbgEvtType.GOComputeChildrenPositions); } Widget stretchedGO = null; @@ -99,16 +112,11 @@ namespace Crow { RegisteredLayoutings &= (~layoutType); if (layoutType == LayoutingType.ArrangeChildren) { - //allow 1 child to have size to 0 if stack has fixed or streched size policy, + //allow 1 child to have stretched size, //this child will occupy remaining space //if stack size policy is Fit, no child may have stretch enabled //in the direction of stacking. ComputeChildrenPositions (); - - //if no layouting remains in queue for item, registre for redraw - if (RegisteredLayoutings == LayoutingType.None && IsDirty) - IFace.EnqueueForRepaint (this); - return true; } @@ -128,6 +136,7 @@ namespace Crow { w.OnLayoutChanges (LayoutingType.Width); w.LayoutChanged += OnChildLayoutChanges; w.LastSlots.Width = w.Slot.Width; + DbgLogger.SetMsg(DbgEvtType.GOAdjustStretchedGo, $"new width={newW}"); } protected void setChildHeight (Widget w, int newH) { if (w.MaximumSize.Height > 0) @@ -142,83 +151,90 @@ namespace Crow { w.OnLayoutChanges (LayoutingType.Height); w.LayoutChanged += OnChildLayoutChanges; w.LastSlots.Height = w.Slot.Height; + DbgLogger.SetMsg(DbgEvtType.GOAdjustStretchedGo, $"new height={newH}"); } - internal void adjustStretchedGo (LayoutingType lt) { + internal void adjustStretchedGo (LayoutingType lt) { if (stretchedGO == null) return; + //Console.WriteLine ($"adjust stretched go: {stretchedGO} {lt}"); + DbgLogger.StartEvent(DbgEvtType.GOAdjustStretchedGo, this); if (lt == LayoutingType.Width) setChildWidth (stretchedGO, Math.Max ( ClientRectangle.Width - contentSize.Width - Spacing * (Children.Count - 1), stretchedGO.MinimumSize.Width)); else setChildHeight (stretchedGO, Math.Max ( - ClientRectangle.Height - contentSize.Height - Spacing * (Children.Count - 1), stretchedGO.MinimumSize.Height)); + ClientRectangle.Height - contentSize.Height - Spacing * (Children.Count - 1), stretchedGO.MinimumSize.Height)); + DbgLogger.EndEvent(DbgEvtType.GOAdjustStretchedGo); } public override void OnChildLayoutChanges (object sender, LayoutingEventArgs arg) { DbgLogger.StartEvent(DbgEvtType.GOOnChildLayoutChange, this); - Widget go = sender as Widget; - //Debug.WriteLine ("child layout change: " + go.LastSlots.ToString() + " => " + go.Slot.ToString()); - switch (arg.LayoutType) { - case LayoutingType.Width: - if (Orientation == Orientation.Horizontal) { - if (go.Width == Measure.Stretched) { - if (stretchedGO == null && Width != Measure.Fit) { - stretchedGO = go; - contentSize.Width -= go.LastSlots.Width; - } else if (stretchedGO != go) { - go.Slot.Width = 0; - go.Width = Measure.Fit; - DbgLogger.EndEvent(DbgEvtType.GOOnChildLayoutChange); - return; - } - } else if (stretchedGO == go) { - stretchedGO = null; - contentSize.Width += go.Slot.Width; - } else - contentSize.Width += go.Slot.Width - go.LastSlots.Width; + try { + Widget go = sender as Widget; + switch (arg.LayoutType) { + case LayoutingType.Width: + if (Orientation == Orientation.Horizontal) { + if (go.Width == Measure.Stretched) { + if (stretchedGO == null && Width != Measure.Fit) { + stretchedGO = go; + contentSize.Width -= go.LastSlots.Width; + DbgLogger.SetMsg (DbgEvtType.GOOnChildLayoutChange, $"new stretched go: {stretchedGO}"); + } else if (stretchedGO != go) { + go.Slot.Width = 0; + go.Width = Measure.Fit; + DbgLogger.SetMsg (DbgEvtType.GOOnChildLayoutChange, $"force stretched width to Fit: {go}"); + return; + } + } else if (stretchedGO == go) { + stretchedGO = null; + contentSize.Width += go.Slot.Width; + DbgLogger.SetMsg (DbgEvtType.GOOnChildLayoutChange, $"reset stretched go"); + } else + contentSize.Width += go.Slot.Width - go.LastSlots.Width; + adjustStretchedGo (LayoutingType.Width); - adjustStretchedGo (LayoutingType.Width); + if (Width == Measure.Fit) + this.RegisterForLayouting (LayoutingType.Width); - if (Width == Measure.Fit) - this.RegisterForLayouting (LayoutingType.Width); - - this.RegisterForLayouting (LayoutingType.ArrangeChildren); - DbgLogger.EndEvent(DbgEvtType.GOOnChildLayoutChange); - return; - } - break; - case LayoutingType.Height: - if (Orientation == Orientation.Vertical) { - if (go.Height == Measure.Stretched) { - if (stretchedGO == null && Height != Measure.Fit) { - stretchedGO = go; - contentSize.Height -= go.LastSlots.Height; - } else if (stretchedGO != go) { - go.Slot.Height = 0; - go.Height = Measure.Fit; - DbgLogger.EndEvent(DbgEvtType.GOOnChildLayoutChange); - return; - } - } else if (stretchedGO == go) { - stretchedGO = null; - contentSize.Height += go.Slot.Height; - } else - contentSize.Height += go.Slot.Height - go.LastSlots.Height; + this.RegisterForLayouting (LayoutingType.ArrangeChildren); + return; + } + break; + case LayoutingType.Height: + if (Orientation == Orientation.Vertical) { + if (go.Height == Measure.Stretched) { + if (stretchedGO == null && Height != Measure.Fit) { + stretchedGO = go; + contentSize.Height -= go.LastSlots.Height; + DbgLogger.SetMsg (DbgEvtType.GOOnChildLayoutChange, $"new stretched go: {stretchedGO}"); + } else if (stretchedGO != go) { + go.Slot.Height = 0; + go.Height = Measure.Fit; + DbgLogger.SetMsg (DbgEvtType.GOOnChildLayoutChange, $"force stretched width to Fit: {go}"); + return; + } + } else if (stretchedGO == go) { + stretchedGO = null; + contentSize.Height += go.Slot.Height; + DbgLogger.SetMsg (DbgEvtType.GOOnChildLayoutChange, $"reset stretched go"); + } else + contentSize.Height += go.Slot.Height - go.LastSlots.Height; - adjustStretchedGo (LayoutingType.Height); + adjustStretchedGo (LayoutingType.Height); - if (Height == Measure.Fit) - this.RegisterForLayouting (LayoutingType.Height); + if (Height == Measure.Fit) + this.RegisterForLayouting (LayoutingType.Height); - this.RegisterForLayouting (LayoutingType.ArrangeChildren); - DbgLogger.EndEvent(DbgEvtType.GOOnChildLayoutChange); - return; + this.RegisterForLayouting (LayoutingType.ArrangeChildren); + return; + } + break; } - break; + base.OnChildLayoutChanges (sender, arg); + } finally { + DbgLogger.EndEvent(DbgEvtType.GOOnChildLayoutChange); } - base.OnChildLayoutChanges (sender, arg); - DbgLogger.EndEvent(DbgEvtType.GOOnChildLayoutChange); } #endregion diff --git a/Crow/src/Widgets/Group.cs b/Crow/src/Widgets/Group.cs index 8b17b0da..e771426e 100644 --- a/Crow/src/Widgets/Group.cs +++ b/Crow/src/Widgets/Group.cs @@ -74,8 +74,7 @@ namespace Crow contentSize.Height = g.LastSlots.Height; } - g.LayoutChanged += OnChildLayoutChanges; - g.RegisteredLayoutings = LayoutingType.None; + g.LayoutChanged += OnChildLayoutChanges; g.RegisterForLayouting (LayoutingType.Sizing | LayoutingType.ArrangeChildren); } public override void ClearChildren() @@ -101,16 +100,21 @@ namespace Crow #region GraphicObject overrides public override int measureRawSize (LayoutingType lt) { - if (Children.Count > 0) { - if (lt == LayoutingType.Width) { - //if (largestChild == null) - searchLargestChild (); - } else { - //if (tallestChild == null) - searchTallestChild (); + DbgLogger.StartEvent(DbgEvtType.GOMeasure, this, lt); + try { + if (Children.Count > 0) { + if (lt == LayoutingType.Width) { + //if (largestChild == null) + searchLargestChild (); + } else { + //if (tallestChild == null) + searchTallestChild (); + } } + return base.measureRawSize (lt); + } finally { + DbgLogger.EndEvent(DbgEvtType.GOMeasure); } - return base.measureRawSize (lt); } public override void OnLayoutChanges (LayoutingType layoutType) @@ -163,8 +167,9 @@ namespace Crow contentSize.Width = g.Slot.Width; } else if (g == largestChild) searchLargestChild (); - else - break; + /*else + Console.WriteLine ($"else: {g} largest:{largestChild} {g.RequiredLayoutings} {this.RequiredLayoutings} {largestChild?.RequiredLayoutings}");*/ + /*break;*/ this.RegisterForLayouting (LayoutingType.Width); } break; @@ -175,8 +180,8 @@ namespace Crow contentSize.Height = g.Slot.Height; } else if (g == tallestChild) searchTallestChild (); - else - break; + /*else + break;*/ this.RegisterForLayouting (LayoutingType.Height); } break; @@ -195,6 +200,7 @@ namespace Crow childrenRWLock.EnterReadLock (); try { + DbgLogger.SetMsg (DbgEvtType.GOSearchLargestChild, $"forced={forceMeasure}"); largestChild = null; contentSize.Width = 0; @@ -204,7 +210,7 @@ namespace Crow int cw = 0; if (forceMeasure) cw = Children [i].measureRawSize (LayoutingType.Width); - else if (Children[i].Width.IsRelativeToParent || Children [i].RegisteredLayoutings.HasFlag (LayoutingType.Width)) + else if (Children[i].Width.IsRelativeToParent || Children [i].RequiredLayoutings.HasFlag (LayoutingType.Width)) continue; else cw = Children [i].Slot.Width; @@ -226,6 +232,8 @@ namespace Crow childrenRWLock.EnterReadLock (); try { + DbgLogger.SetMsg (DbgEvtType.GOSearchTallestChild, $"forced={forceMeasure}"); + tallestChild = null; contentSize.Height = 0; for (int i = 0; i < Children.Count; i++) { @@ -234,7 +242,7 @@ namespace Crow int ch = 0; if (forceMeasure) ch = Children [i].measureRawSize (LayoutingType.Height); - else if (Children[i].Height.IsRelativeToParent || Children [i].RegisteredLayoutings.HasFlag (LayoutingType.Height)) + else if (Children[i].Height.IsRelativeToParent || Children [i].RequiredLayoutings.HasFlag (LayoutingType.Height)) continue; else ch = Children [i].Slot.Height; diff --git a/Crow/src/Widgets/GroupBase.cs b/Crow/src/Widgets/GroupBase.cs index 7baf1ba4..752c98de 100644 --- a/Crow/src/Widgets/GroupBase.cs +++ b/Crow/src/Widgets/GroupBase.cs @@ -236,7 +236,7 @@ namespace Crow try { for (int i = 0; i < Children.Count; i++) - Children[i].Paint (gr); + Children[i].Paint (gr); } finally { childrenRWLock.ExitReadLock (); } diff --git a/Crow/src/Widgets/ILayoutable.cs b/Crow/src/Widgets/ILayoutable.cs index 5a03b7da..c9148668 100644 --- a/Crow/src/Widgets/ILayoutable.cs +++ b/Crow/src/Widgets/ILayoutable.cs @@ -20,6 +20,7 @@ namespace Crow bool ArrangeChildren { get; } LayoutingType RegisteredLayoutings { get; set; } + LayoutingType RequiredLayoutings { get; set; } void ChildrenLayoutingConstraints(ILayoutable layoutable, ref LayoutingType layoutType); void RegisterForLayouting(LayoutingType layoutType); void RegisterClip(Rectangle clip); diff --git a/Crow/src/Widgets/Label.cs b/Crow/src/Widgets/Label.cs index 5ca6edf2..c2c68648 100644 --- a/Crow/src/Widgets/Label.cs +++ b/Crow/src/Widgets/Label.cs @@ -156,7 +156,7 @@ namespace Crow return; int oldTextLength = string.IsNullOrEmpty (_text) ? 0 : _text.Length; - lock (linesMutex) { + lock (linesMutex) { _text = value; getLines (); textMeasureIsUpToDate = false; diff --git a/Crow/src/Widgets/PrivateContainer.cs b/Crow/src/Widgets/PrivateContainer.cs index c2f44816..d7d269b4 100644 --- a/Crow/src/Widgets/PrivateContainer.cs +++ b/Crow/src/Widgets/PrivateContainer.cs @@ -59,8 +59,7 @@ namespace Crow if (child != null) { child.Parent = this; child.LayoutChanged += OnChildLayoutChanges; - contentSize = child.Slot.Size; - child.RegisteredLayoutings = LayoutingType.None; + contentSize = child.Slot.Size; child.RegisterForLayouting (LayoutingType.Sizing); } } @@ -103,20 +102,26 @@ namespace Crow public override int measureRawSize (LayoutingType lt) { - if (child != null) { - //force measure of child if sizing on children and child has stretched size - switch (lt) { - case LayoutingType.Width: - if (child.Width.IsRelativeToParent) - contentSize.Width = child.measureRawSize (LayoutingType.Width); - break; - case LayoutingType.Height: - if (child.Height.IsRelativeToParent) - contentSize.Height = child.measureRawSize (LayoutingType.Height); - break; + DbgLogger.StartEvent(DbgEvtType.GOMeasure, this, lt); + try { + if (child != null) { + //force measure of child if sizing on children and child has stretched size + switch (lt) { + case LayoutingType.Width: + if (child.Width.IsRelativeToParent) + contentSize.Width = child.measureRawSize (LayoutingType.Width); + break; + case LayoutingType.Height: + if (child.Height.IsRelativeToParent) + contentSize.Height = child.measureRawSize (LayoutingType.Height); + break; + } + DbgLogger.SetMsg(DbgEvtType.GOMeasure, $"{lt} contentSize:{contentSize}"); } + return base.measureRawSize (lt); + } finally { + DbgLogger.EndEvent(DbgEvtType.GOMeasure); } - return base.measureRawSize (lt); } public override bool UpdateLayout (LayoutingType layoutType) { diff --git a/Crow/src/Widgets/ScrollBar.cs b/Crow/src/Widgets/ScrollBar.cs index 8ef519f1..ebec12f1 100644 --- a/Crow/src/Widgets/ScrollBar.cs +++ b/Crow/src/Widgets/ScrollBar.cs @@ -26,13 +26,16 @@ namespace Crow set { if (cursorRatio == value) return; - cursorRatio = value; + if (double.IsFinite(value)) + cursorRatio = value; + else + cursorRatio = -1; updateCursor (); } } void updateCursor () { - if (cursorRatio < 0) + if (cursorRatio < 0 || !double.IsFinite(cursorRatio)) return; ILayoutable l = cursor?.Parent; if (l == null) diff --git a/Crow/src/Widgets/TableRow.cs b/Crow/src/Widgets/TableRow.cs index 1f646bcb..fbb0e7c4 100644 --- a/Crow/src/Widgets/TableRow.cs +++ b/Crow/src/Widgets/TableRow.cs @@ -107,9 +107,14 @@ namespace Crow } public override int measureRawSize (LayoutingType lt) { - if (lt == LayoutingType.Height && Children.Count > 0 && tallestChild == null) - searchTallestChild (); - return base.measureRawSize (lt); + DbgLogger.StartEvent(DbgEvtType.GOMeasure, this); + try { + if (lt == LayoutingType.Height && Children.Count > 0 && tallestChild == null) + searchTallestChild (); + return base.measureRawSize (lt); + } finally { + DbgLogger.EndEvent(DbgEvtType.GOMeasure); + } } public override void OnLayoutChanges (LayoutingType layoutType) { @@ -166,7 +171,7 @@ namespace Crow int ch = 0; if (forceMeasure) ch = Children [i].measureRawSize (LayoutingType.Height); - else if (Children [i].RegisteredLayoutings.HasFlag (LayoutingType.Height)) + else if (Children [i].RequiredLayoutings.HasFlag (LayoutingType.Height)) continue; else ch = Children [i].Slot.Height; diff --git a/Crow/src/Widgets/TemplatedContainer.cs b/Crow/src/Widgets/TemplatedContainer.cs index c51ea3eb..5977203c 100644 --- a/Crow/src/Widgets/TemplatedContainer.cs +++ b/Crow/src/Widgets/TemplatedContainer.cs @@ -42,6 +42,7 @@ namespace Crow if (_contentContainer == null) throw new Exception ("TemplatedContainer template Must contain a Container named 'Content'"); _contentContainer.SetChild(value); + value.LogicalParent = this; NotifyValueChanged ("HasContent", HasContent); } } diff --git a/Crow/src/Widgets/TemplatedControl.cs b/Crow/src/Widgets/TemplatedControl.cs index 7c804651..3d0d4258 100644 --- a/Crow/src/Widgets/TemplatedControl.cs +++ b/Crow/src/Widgets/TemplatedControl.cs @@ -98,9 +98,8 @@ namespace Crow CairoHelpers.CairoRectangle (gr, ClientRectangle, CornerRadius); gr.Clip (); } - - if (child != null) - child.Paint (gr); + + child?.Paint (gr); gr.Restore (); diff --git a/Crow/src/Widgets/TemplatedGroup.cs b/Crow/src/Widgets/TemplatedGroup.cs index 601e2183..2ebede8e 100644 --- a/Crow/src/Widgets/TemplatedGroup.cs +++ b/Crow/src/Widgets/TemplatedGroup.cs @@ -513,6 +513,9 @@ namespace Crow { Monitor.Exit (IFace.UpdateMutex); } + if (g is ISelectable li) + li.Selected += Li_Selected; + if (iTemp.Expand != null) { IToggle toggle = g as IToggle; @@ -521,16 +524,10 @@ namespace Crow { if (toggle != null) { toggle.ToggleOn += iTemp.Expand; - if (o is ICollection) - toggle.IsToggleable = iTemp.HasSubItems; - else - toggle.IsToggleable = new BooleanTestOnInstance ((instance) => true); + toggle.IsToggleable = iTemp.HasSubItems; } } - if (g is ISelectable li) - li.Selected += Li_Selected; - g.DataSource = o; } diff --git a/Crow/src/Widgets/Widget.cs b/Crow/src/Widgets/Widget.cs index 7255ca45..d595e164 100644 --- a/Crow/src/Widgets/Widget.cs +++ b/Crow/src/Widgets/Widget.cs @@ -28,7 +28,7 @@ namespace Crow /// </summary> public class Widget : ILayoutable, IValueChange, IDisposable { - internal ReaderWriterLockSlim parentRWLock = new ReaderWriterLockSlim(); + internal ReaderWriterLockSlim parentRWLock = new ReaderWriterLockSlim(LockRecursionPolicy.SupportsRecursion); #if DEBUG_LOG //0 is the main graphic tree, for other obj tree not added to main tree, it range from 1->n //useful to track events for obj shown later, not on start, or never added to main tree @@ -210,12 +210,14 @@ namespace Crow /// </summary> public virtual void NotifyValueChanged(string MemberName, object _value) { + DbgLogger.AddEventWithMsg (DbgEvtType.GOSetProperty, $"{MemberName} = {_value}", this); //Debug.WriteLine ("Value changed: {0}->{1} = {2}", this, MemberName, _value); if (ValueChanged != null) ValueChanged.Invoke(this, new ValueChangeEventArgs(MemberName, _value)); } public void NotifyValueChangedAuto (object _value, [CallerMemberName] string caller = null) { + DbgLogger.AddEventWithMsg (DbgEvtType.GOSetProperty, $"{caller} = {_value}", this); if (ValueChanged != null) NotifyValueChanged (caller, _value); } @@ -264,6 +266,7 @@ namespace Crow } #region private fields LayoutingType registeredLayoutings;// = LayoutingType.Sizing; + LayoutingType requiredLayoutings = LayoutingType.Sizing; ILayoutable logicalParent; ILayoutable parent; string name; @@ -278,7 +281,7 @@ namespace Crow bool hasFocus; bool isActive; bool isHover; - bool bubbleMouseEvent; + DeviceEventType bubbledEvents; bool mouseRepeat; bool stickyMouseEnabled; int stickyMouse; @@ -336,7 +339,14 @@ namespace Crow #endregion #region ILayoutable - [XmlIgnore]public LayoutingType RegisteredLayoutings { get => registeredLayoutings; set => registeredLayoutings = value; } + [XmlIgnore]public LayoutingType RegisteredLayoutings { + get => registeredLayoutings; + set => registeredLayoutings = value; + } + [XmlIgnore]public LayoutingType RequiredLayoutings { + get => requiredLayoutings; + set => requiredLayoutings = value; + } //TODO: it would save the recurent cost of a cast in event bubbling if parent type was GraphicObject // or we could add to the interface the mouse events /// <summary> @@ -414,7 +424,7 @@ namespace Crow return default(Rectangle); } } - public virtual Rectangle getSlot () { return Slot;} + public virtual Rectangle getSlot () => Slot; #endregion public Point ScreenPointToLocal(Point p){ Point pt = p - ScreenCoordinates (Slot).TopLeft - ClientRectangle.TopLeft; @@ -757,14 +767,14 @@ namespace Crow /// if false, prevent mouse events to bubble to the parent in any case. /// </summary> [DesignCategory ("Behaviour")] - [DefaultValue (true)] - public virtual bool BubbleMouseEvent { - get => bubbleMouseEvent; + [DefaultValue (DeviceEventType.All)] + public virtual DeviceEventType BubbleMouseEvent { + get => bubbledEvents; set { - if (bubbleMouseEvent == value) + if (bubbledEvents == value) return; - bubbleMouseEvent = value; - NotifyValueChangedAuto (bubbleMouseEvent); + bubbledEvents = value; + NotifyValueChangedAuto (bubbledEvents); } } /// <summary> @@ -1267,9 +1277,12 @@ namespace Crow } } if (styleIndex >= 0) { - if (pi.PropertyType.IsEnum)//maybe should be in parser.. - defaultValue = Enum.Parse (pi.PropertyType, (string)styling [styleIndex] [pi.Name], true); - else + if (pi.PropertyType.IsEnum) {//maybe should be in parser.. + if (EnumsNET.FlagEnums.IsFlagEnum (pi.PropertyType)) + defaultValue = EnumsNET.FlagEnums.ParseFlags (pi.PropertyType, (string)styling [styleIndex] [pi.Name], true, "|"); + else + defaultValue = EnumsNET.Enums.Parse (pi.PropertyType, (string)styling [styleIndex] [pi.Name], true); + }else defaultValue = styling [styleIndex] [pi.Name]; #if DESIGN_MODE @@ -1474,8 +1487,9 @@ namespace Crow if (parent != null) { parent.RegisterClip (LastPaintedSlot); parent.RegisterClip (Slot); - }//else - //Console.WriteLine ($"clipping reg canceled (no parent): {this.ToString()}"); + }else { + DbgLogger.SetMsg (DbgEvtType.GOClippingRegistration, "clipping reg canceled (no parent)"); + } parentRWLock.ExitReadLock (); DbgLogger.EndEvent (DbgEvtType.GOClippingRegistration); @@ -1489,13 +1503,13 @@ namespace Crow DbgLogger.AddEvent (DbgEvtType.AlreadyDisposed | DbgEvtType.GORegisterClip, this); return; } - //we register clip in the parent, if it's dirty, all children will be redrawn - if (IsDirty && CacheEnabled) { - //Console.WriteLine ($"regclip canceled Dirty:{IsDirty} Cached:{CacheEnabled}: {this.ToString()}"); - return; - } DbgLogger.StartEvent(DbgEvtType.GORegisterClip, this); try { + //we register clip in the parent, if it's dirty, all children will be redrawn + if (IsDirty && CacheEnabled) { + DbgLogger.SetMsg (DbgEvtType.GORegisterClip, $"regclip canceled Dirty:{IsDirty} Cached:{CacheEnabled}"); + return; + } Rectangle cb = ClientRectangle; Rectangle r = clip + cb.Position; /*if (r.Right > cb.Right) @@ -1503,13 +1517,13 @@ namespace Crow if (r.Bottom > cb.Bottom) r.Height -= r.Bottom - cb.Bottom;*/ if (r.Width < 0 || r.Height < 0){ - //Console.WriteLine ($"regclip canceled size w:{r.Width} h:{r.Height}: {this.ToString()}"); + DbgLogger.SetMsg (DbgEvtType.GORegisterClip, $"regclip canceled size w:{r.Width} h:{r.Height}"); return; } if (cacheEnabled) Clipping.UnionRectangle (r); if (Parent == null){ - //Console.WriteLine ($"clip chain aborded (no parent): {this.ToString()}"); + DbgLogger.SetMsg (DbgEvtType.GORegisterClip, "clip chain aborded (no parent)"); return; } /*Widget p = Parent as Widget; @@ -1535,8 +1549,8 @@ namespace Crow IsDirty = true; if (Width.IsFit || Height.IsFit) RegisterForLayouting (LayoutingType.Sizing); - else if (RegisteredLayoutings == LayoutingType.None) - IFace.EnqueueForRepaint (this); + else + RegisterForRedraw (); DbgLogger.EndEvent(DbgEvtType.GORegisterForGraphicUpdate); } @@ -1549,8 +1563,7 @@ namespace Crow return; } IsDirty = true; - if (RegisteredLayoutings == LayoutingType.None) - IFace.EnqueueForRepaint (this); + RegisterForRepaint (); } /// <summary> /// query a repaint, if control is cached, cache will not be updated and simply repainted. @@ -1564,7 +1577,7 @@ namespace Crow /// /// </remark> public void RegisterForRepaint () { - if (RegisteredLayoutings == LayoutingType.None && !IsDirty) + if (RequiredLayoutings == LayoutingType.None)// && !IsDirty) IFace.EnqueueForRepaint (this); } #endregion @@ -1573,13 +1586,14 @@ namespace Crow /// <summary> return size of content + margins </summary> public virtual int measureRawSize (LayoutingType lt) { - DbgLogger.StartEvent(DbgEvtType.GOMeasure, this, lt); - - int tmp = lt == LayoutingType.Width ? - contentSize.Width + 2 * margin: contentSize.Height + 2 * margin; - - DbgLogger.EndEvent(DbgEvtType.GOMeasure); - return tmp; + DbgLogger.StartEvent(DbgEvtType.GOMeasure, this); + try { + DbgLogger.SetMsg(DbgEvtType.GOMeasure, $"{lt} contentSize:{contentSize}"); + return lt == LayoutingType.Width ? + contentSize.Width + 2 * margin : contentSize.Height + 2 * margin; + } finally { + DbgLogger.EndEvent(DbgEvtType.GOMeasure); + } } internal bool firstUnresolvedFitWidth (out Widget ancestorInUnresolvedFit) @@ -1595,8 +1609,32 @@ namespace Crow } return false; } + protected bool stretchedInFit (LayoutingType lt) { + + if (Parent == null) + return false; + Widget p = Parent as Widget; + if (lt == LayoutingType.Width) { + if (!Width.IsRelativeToParent) + return false; + while (p.Width.IsRelativeToParent) { + p = p.Parent as Widget; + if (p == null) + return false; + } + return p.Width.IsFit; + } + if (!Height.IsRelativeToParent) + return false; + while (p.Height.IsRelativeToParent) { + p = p.Parent as Widget; + if (p == null) + return false; + } + return p.Height.IsFit; + } - public virtual bool ArrangeChildren { get { return false; } } + public virtual bool ArrangeChildren => false; /// <summary> /// Used to prevent some layouting type in children. For example, in the GenericStack, /// x layouting is dismissed in the direction of the stacking to let the parent @@ -1606,17 +1644,25 @@ namespace Crow /// <param name="layoutType">The currently registering layouting types</param> public virtual void ChildrenLayoutingConstraints(ILayoutable layoutable, ref LayoutingType layoutType){ } /// <summary> Query a layouting for the type pass as parameter, redraw only if layout changed. </summary> + + internal ReaderWriterLockSlim layoutMutex = new ReaderWriterLockSlim (LockRecursionPolicy.SupportsRecursion); public virtual void RegisterForLayouting(LayoutingType layoutType){ if (disposed) { DbgLogger.AddEvent (DbgEvtType.AlreadyDisposed, this); return; } - if (Parent == null) - return; - DbgLogger.StartEvent (DbgEvtType.GOLockLayouting, this); + parentRWLock.EnterReadLock (); + try { - lock (IFace.LayoutMutex) { + if (Parent == null) + return; + + layoutMutex.EnterWriteLock (); + + try { + + //prevent queueing same LayoutingType for this layoutType &= (~RegisteredLayoutings); @@ -1641,20 +1687,30 @@ namespace Crow if (layoutType == LayoutingType.None) return; - //enqueue LQI LayoutingTypes separately - if (layoutType.HasFlag (LayoutingType.Width)) - IFace.LayoutingQueue.Enqueue (new LayoutingQueueItem (LayoutingType.Width, this)); - if (layoutType.HasFlag (LayoutingType.Height)) - IFace.LayoutingQueue.Enqueue (new LayoutingQueueItem (LayoutingType.Height, this)); - if (layoutType.HasFlag (LayoutingType.X)) - IFace.LayoutingQueue.Enqueue (new LayoutingQueueItem (LayoutingType.X, this)); - if (layoutType.HasFlag (LayoutingType.Y)) - IFace.LayoutingQueue.Enqueue (new LayoutingQueueItem (LayoutingType.Y, this)); - if (layoutType.HasFlag (LayoutingType.ArrangeChildren)) - IFace.LayoutingQueue.Enqueue (new LayoutingQueueItem (LayoutingType.ArrangeChildren, this)); + RequiredLayoutings |= layoutType; + } finally { + layoutMutex.ExitWriteLock (); } - } finally { + + DbgLogger.StartEvent (DbgEvtType.GOLockLayouting, this); + lock (IFace.LayoutMutex) { + layoutMutex.EnterWriteLock (); + //enqueue LQI LayoutingTypes separately + if (layoutType.HasFlag (LayoutingType.Width)) + IFace.LayoutingQueue.Enqueue (new LayoutingQueueItem (LayoutingType.Width, this)); + if (layoutType.HasFlag (LayoutingType.Height)) + IFace.LayoutingQueue.Enqueue (new LayoutingQueueItem (LayoutingType.Height, this)); + if (layoutType.HasFlag (LayoutingType.X)) + IFace.LayoutingQueue.Enqueue (new LayoutingQueueItem (LayoutingType.X, this)); + if (layoutType.HasFlag (LayoutingType.Y)) + IFace.LayoutingQueue.Enqueue (new LayoutingQueueItem (LayoutingType.Y, this)); + if (layoutType.HasFlag (LayoutingType.ArrangeChildren)) + IFace.LayoutingQueue.Enqueue (new LayoutingQueueItem (LayoutingType.ArrangeChildren, this)); + layoutMutex.ExitWriteLock (); + } DbgLogger.EndEvent (DbgEvtType.GOLockLayouting); + } finally { + parentRWLock.ExitReadLock (); } } @@ -1698,8 +1754,8 @@ namespace Crow case LayoutingType.X: if (left == 0) { - if (Parent.RegisteredLayoutings.HasFlag (LayoutingType.Width) || - RegisteredLayoutings.HasFlag (LayoutingType.Width)) + if (Parent.RequiredLayoutings.HasFlag (LayoutingType.Width) || + RequiredLayoutings.HasFlag (LayoutingType.Width)) return false; switch (horizontalAlignment) { @@ -1728,8 +1784,8 @@ namespace Crow case LayoutingType.Y: if (top == 0) { - if (Parent.RegisteredLayoutings.HasFlag (LayoutingType.Height) || - RegisteredLayoutings.HasFlag (LayoutingType.Height)) + if (Parent.RequiredLayoutings.HasFlag (LayoutingType.Height) || + RequiredLayoutings.HasFlag (LayoutingType.Height)) return false; switch (verticalAlignment) { @@ -1825,10 +1881,6 @@ namespace Crow break; } - //if no layouting remains in queue for item, registre for redraw - if (this.registeredLayoutings == LayoutingType.None && IsDirty) - IFace.EnqueueForRepaint (this); - return true; } #endregion @@ -1903,8 +1955,8 @@ namespace Crow /// of the widget </summary> public virtual void Paint (Context ctx) { - /*if (!IsVisible) - return;*/ + if (!IsVisible) + return; DbgLogger.StartEvent (DbgEvtType.GOPaint, this); @@ -1912,19 +1964,12 @@ namespace Crow if (disposed || Slot.Height < 0 || Slot.Width < 0 || parent == null){ #if DEBUG - Console.ForegroundColor = ConsoleColor.Red; if (disposed) - System.Diagnostics.Debug.WriteLine ($"Paint disposed widget: {this}"); - Console.ForegroundColor = ConsoleColor.DarkRed; + DbgLogger.SetMsg (DbgEvtType.GOPaint, "Paint disposed widget"); if (Slot.Height < 0 || Slot.Width < 0) - System.Diagnostics.Debug.WriteLine ($"Paint slot invalid ({Slot}): {this}"); - Console.ForegroundColor = ConsoleColor.DarkMagenta; + DbgLogger.SetMsg (DbgEvtType.GOPaint, $"Paint slot invalid ({Slot})"); if (parent == null) - System.Diagnostics.Debug.WriteLine ($"Paint with parent == null: {this}"); - Console.ForegroundColor = ConsoleColor.Magenta; - if (!isVisible) - System.Diagnostics.Debug.WriteLine ($"Paint invisible widget: {this}"); - Console.ResetColor (); + DbgLogger.SetMsg (DbgEvtType.GOPaint, "Paint with no parent"); #endif DbgLogger.AddEvent (DbgEvtType.Warning); DbgLogger.EndEvent (DbgEvtType.GOPaint); @@ -2041,7 +2086,7 @@ namespace Crow if (MouseMove != null) MouseMove.Invoke (this, e); - else if (!e.Handled && BubbleMouseEvent) + else if (!e.Handled && BubbleMouseEvent.HasFlag (DeviceEventType.MouseMove)) FocusParent?.onMouseMove (sender, e); } /// <summary> @@ -2065,7 +2110,7 @@ namespace Crow if (MouseDown != null) MouseDown?.Invoke (this, e); - else if (!e.Handled && BubbleMouseEvent) + else if (!e.Handled && BubbleMouseEvent.HasFlag (DeviceEventType.ButtonDown)) FocusParent?.onMouseDown (sender, e); } /// <summary> @@ -2080,7 +2125,7 @@ namespace Crow if (MouseUp != null) MouseUp.Invoke (this, e); - else if (!e.Handled && BubbleMouseEvent) + else if (!e.Handled && BubbleMouseEvent.HasFlag (DeviceEventType.ButtonUp)) FocusParent?.onMouseUp (sender, e); } /// <summary> @@ -2091,7 +2136,7 @@ namespace Crow public virtual void onMouseClick(object sender, MouseButtonEventArgs e){ if (MouseClick != null) MouseClick.Invoke (this, e); - else if (!e.Handled && BubbleMouseEvent) + else if (!e.Handled && BubbleMouseEvent.HasFlag (DeviceEventType.MouseClick)) FocusParent?.onMouseClick (sender, e); } /// <summary> @@ -2103,13 +2148,13 @@ namespace Crow public virtual void onMouseDoubleClick(object sender, MouseButtonEventArgs e){ if (MouseDoubleClick != null) MouseDoubleClick.Invoke (this, e); - else if (!e.Handled && BubbleMouseEvent) + else if (!e.Handled && BubbleMouseEvent.HasFlag (DeviceEventType.MouseClick)) FocusParent?.onMouseDoubleClick (sender, e); } public virtual void onMouseWheel(object sender, MouseWheelEventArgs e){ if (MouseWheelChanged != null) MouseWheelChanged.Invoke (this, e); - else if (!e.Handled && BubbleMouseEvent) + else if (!e.Handled && BubbleMouseEvent.HasFlag (DeviceEventType.MouseWheel)) FocusParent?.onMouseWheel (sender, e); } public virtual void onMouseEnter(object sender, MouseMoveEventArgs e) @@ -2155,7 +2200,7 @@ namespace Crow Disabled.Raise (this, e); } protected virtual void onParentChanged(object sender, DataSourceChangeEventArgs e) { - DbgLogger.AddEvent (DbgEvtType.GONewParent, this, e); + DbgLogger.AddEvent (DbgEvtType.GONewParent, this, e.NewDataSource); ParentChanged.Raise (this, e); if (logicalParent == null) LogicalParentChanged.Raise (this, e); @@ -2210,10 +2255,13 @@ namespace Crow } - if (IFace.ActiveWidget != null) { - if (IFace.ActiveWidget.IsOrIsInside (this)) - IFace.ActiveWidget = null; - } + /*if (IFace.ActiveWidget != null) { + if (IsActive) { + + + } else if (this.Contains (IFace.ActiveWidget)) + IFace.ActiveWidget = this; + }*/ if (IFace.FocusedWidget != null) { if (IFace.FocusedWidget.IsOrIsInside (this)) IFace.FocusedWidget = null; diff --git a/Crow/src/Widgets/Window.cs b/Crow/src/Widgets/Window.cs index 07b575b0..6540a305 100644 --- a/Crow/src/Widgets/Window.cs +++ b/Crow/src/Widgets/Window.cs @@ -22,7 +22,13 @@ namespace Crow SW, SE, } - + [Flags] + public enum Status { + None = 0x00, + Normal = 0x01, + Minimized = 0x02, + Maximized= 0x04 + } string _icon; bool resizable; bool movable; @@ -30,51 +36,203 @@ namespace Crow bool alwaysOnTop = false; Rectangle savedBounds; - bool _minimized = false; + bool wasResizable; + + Status currentState, allowedStates; protected Direction currentDirection = Direction.None; + #region Events public event EventHandler Closing; public event EventHandler Maximized; public event EventHandler Unmaximized; public event EventHandler Minimize; #endregion + [DefaultValue("Normal|Minimized|Maximized")] + public Status AllowedStates { + get => allowedStates; + set { + if (allowedStates == value) + return; + allowedStates = value; + NotifyValueChangedAuto (allowedStates); + + if (currentState == Status.None) + return; + + initCommands(); + + if (allowedStates.HasFlag (currentState)) { + CMDNormalize.CanExecute = currentState != Status.Normal & allowedStates.HasFlag (Status.Normal); + CMDMinimize.CanExecute = currentState != Status.Minimized & allowedStates.HasFlag (Status.Minimized); + CMDMaximize.CanExecute = currentState != Status.Maximized & allowedStates.HasFlag (Status.Maximized); + } else { + if (allowedStates.HasFlag (Status.Normal)) + CurrentState = Status.Normal; + else if (allowedStates.HasFlag (Status.Maximized)) + CurrentState = Status.Maximized; + else + CurrentState = Status.Minimized; + } + } + } + [DefaultValue("Normal")] + public Status CurrentState { + get => currentState; + set { + Status newState = value; + if (!allowedStates.HasFlag (newState)) { + if (allowedStates.HasFlag (Status.Normal)) + newState = Status.Normal; + else if (allowedStates.HasFlag (Status.Maximized)) + newState = Status.Maximized; + else + newState = Status.Minimized; + } + + if (currentState == newState) + return; + + if (currentState == Status.Normal) { + savedBounds = LastPaintedSlot; + wasResizable = Resizable; + } + + currentState = value; + NotifyValueChangedAuto (currentState); + + initCommands(); + + switch (currentState) { + case Status.Maximized: + Left = Top = 0; + RegisterForLayouting (LayoutingType.Positioning); + Width = Height = Measure.Stretched; + Resizable = false; + CMDNormalize.CanExecute = allowedStates.HasFlag (Status.Normal); + CMDMinimize.CanExecute = allowedStates.HasFlag (Status.Minimized); + CMDMaximize.CanExecute = false; + break; + case Status.Minimized: + Width = 200; + Height = 20; + Resizable = false; + CMDNormalize.CanExecute = allowedStates.HasFlag (Status.Normal); + CMDMinimize.CanExecute = false; + CMDMaximize.CanExecute = allowedStates.HasFlag (Status.Maximized); + break; + case Status.Normal: + Left = savedBounds.Left; + Top = savedBounds.Top; + Width = savedBounds.Width; + Height = savedBounds.Height; + Resizable = wasResizable; + CMDNormalize.CanExecute = false; + CMDMinimize.CanExecute = allowedStates.HasFlag (Status.Minimized); + CMDMaximize.CanExecute = allowedStates.HasFlag (Status.Maximized); + break; + } + } + } #region CTOR protected Window() {} - public Window (Interface iface, string style = null) : base (iface, style) { } + public Window (Interface iface, string style = null) : base (iface, style) {} #endregion Widget moveHandle, sizingHandle; + public Command CMDMinimize, CMDMaximize, CMDNormalize, CMDClose; + CommandGroup commands; + + public CommandGroup Commands { + get => commands; + set { + if (commands == value) + return; + commands = value; + NotifyValueChangedAuto (commands); + } + } + /*public Command CMDMinimize = new Command ("Minimize", (sender) => + {(sender as Window).CurrentState = Status.Minimized;}, "#Crow.Icons.minimize.svg", false); + public Command CMDMaximize = new Command ("Maximize", (sender) => + {(sender as Window).CurrentState = Status.Maximized;}, "#Crow.Icons.maximize.svg", false); + public Command CMDNormalize = new Command ("Normalize", (sender) => + {(sender as Window).CurrentState = Status.Normal;}, "#Crow.Icons.normalize.svg", false); + public Command CMDClose = new Command ("Close", (sender) => + {(sender as Window).close ();}, "#Crow.Icons.exit2.svg", true);*/ + + + void initCommands () { + if (CMDMinimize != null) + return; + CMDMinimize = new Command ("Minimize", () => CurrentState = Status.Minimized, "#Crow.Icons.minimize.svg", allowedStates.HasFlag (Status.Minimized)); + CMDMaximize = new Command ("Maximize", () => CurrentState = Status.Maximized, "#Crow.Icons.maximize.svg", allowedStates.HasFlag (Status.Maximized)); + CMDNormalize = new Command ("Normalize", () => CurrentState = Status.Normal, "#Crow.Icons.normalize.svg", false); + CMDClose = new Command ("Close", close, "#Crow.Icons.exit2.svg", true); + + Commands = new CommandGroup(CMDMinimize, CMDNormalize, CMDMaximize, CMDClose); + } + + #region TemplatedContainer overrides protected override void loadTemplate(Widget template = null) { + initCommands (); + base.loadTemplate (template); - NotifyValueChanged ("ShowNormal", false); - NotifyValueChanged ("ShowMinimize", true); - NotifyValueChanged ("ShowMaximize", true); + initHandles (); + } + protected void initHandles () { moveHandle = child?.FindByName ("MoveHandle"); sizingHandle = child?.FindByName ("SizeHandle"); - if (sizingHandle == null) - return; - //sizingHandle.Unhover += (arg1, arg2) => currentDirection = Direction.None; - sizingHandle.Unhover += SizingHandle_Unhover; + if (sizingHandle != null) { + sizingHandle.Unhover += SizingHandle_Unhover; + sizingHandle.MouseDown += setResizeOn; + sizingHandle.MouseUp += setResizeOff; + } + + if (moveHandle != null) { + moveHandle.MouseDown += setMoveOn; + moveHandle.MouseUp += setMoveOff; + } + } + protected void resetHandles () { + if (sizingHandle != null) { + sizingHandle.Unhover -= SizingHandle_Unhover; + sizingHandle.MouseDown -= setResizeOn; + sizingHandle.MouseUp -= setResizeOff; + } + + if (moveHandle != null) { + moveHandle.MouseDown -= setMoveOn; + moveHandle.MouseUp -= setMoveOff; + } + moveHandle = null; + sizingHandle = null; } + void setResizeOn (object o, EventArgs e) => resize = true; + void setResizeOff (object o, EventArgs e) => resize = false; + void setMoveOn (object o, EventArgs e) => move = true; + void setMoveOff (object o, EventArgs e) => move = false; + + + bool move, resize; - private void SizingHandle_Unhover (object sender, EventArgs e) { + void SizingHandle_Unhover (object sender, EventArgs e) { currentDirection = Direction.None; NotifyValueChanged ("CurDir", currentDirection); } - #endregion + #endregion - #region public properties - [DefaultValue("#Crow.Icons.crow.svg")] + #region public properties + [DefaultValue("#Crow.Icons.crow.svg")] public string Icon { get => _icon; set { @@ -115,22 +273,6 @@ namespace Crow } } [DefaultValue(false)] - public bool IsMinimized { - get => _minimized; - set{ - if (value == IsMinimized) - return; - - _minimized = value; - _contentContainer.IsVisible = !_minimized; - - NotifyValueChangedAuto (_minimized); - } - } - [XmlIgnore]public bool IsMaximized => - Width == Measure.Stretched & Height == Measure.Stretched & !_minimized; - [XmlIgnore]public bool IsNormal => !(IsMaximized|_minimized); - [DefaultValue(false)] public bool AlwaysOnTop { get => modal ? true : alwaysOnTop; set { @@ -177,11 +319,16 @@ namespace Crow else currentHeight = this.Slot.Height; - switch (currentDirection) { - case Direction.None: + if (move) { this.Left = currentLeft + XDelta; this.Top = currentTop + YDelta; - break; + return; + } + + if (!resize) + return; + + switch (currentDirection) { case Direction.N: this.Height = currentHeight - YDelta; if (this.Height == currentHeight - YDelta) @@ -226,22 +373,22 @@ namespace Crow //} } - bool maySize => sizingHandle == null ? false : resizable & sizingHandle.IsHover; - bool mayMove => moveHandle == null ? false : movable & moveHandle.IsHover; + bool maySize => sizingHandle != null && resizable && sizingHandle.IsHover; + bool mayMove => moveHandle != null && movable; #region GraphicObject Overrides public override void onMouseMove (object sender, MouseMoveEventArgs e) { base.onMouseMove (sender, e); - if (maySize || mayMove) { - if (grabMouse) { - moveAndResize (e.XDelta, e.YDelta, currentDirection); - return; - } - }else + if (!(mayMove || maySize)) return; + if (move || resize) { + moveAndResize (e.XDelta, e.YDelta, currentDirection); + return; + } + Point m = Parent is Widget ? (Parent as Widget).ScreenPointToLocal (e.Position) : e.Position; if (maySize) { @@ -269,9 +416,9 @@ namespace Crow return; switch (currentDirection) { - case Direction.None: + /*case Direction.None: IFace.MouseCursor = MouseCursor.move; - break; + break;*/ case Direction.N: IFace.MouseCursor = MouseCursor.top_side; break; @@ -306,74 +453,38 @@ namespace Crow IFace.MouseCursor = MouseCursor.top_left_arrow; NotifyValueChanged ("CurDir", currentDirection); } - bool grabMouse; - public override void onMouseDown (object sender, MouseButtonEventArgs e) - { - NotifyValueChanged ("GrabMouse", true); - grabMouse = true; - e.Handled = true; - base.onMouseDown (sender, e); - } - public override void onMouseUp (object sender, MouseButtonEventArgs e) - { - NotifyValueChanged ("GrabMouse", false); - NotifyValueChanged ("CurDir", currentDirection); - grabMouse = false; - e.Handled = true; - base.onMouseUp (sender, e); - } public override bool MouseIsIn (Point m) { return modal ? true : base.MouseIsIn (m); } #endregion - protected void onMaximized (object sender, EventArgs e){ + /*protected void onMaximized (){ lock (IFace.LayoutMutex) { - if (!IsMinimized) - savedBounds = this.LastPaintedSlot; - Left = Top = 0; - RegisterForLayouting (LayoutingType.Positioning); - Width = Height = Measure.Stretched; - IsMinimized = false; - Resizable = false; NotifyValueChanged ("ShowNormal", true); NotifyValueChanged ("ShowMinimize", true); NotifyValueChanged ("ShowMaximize", false); } - Maximized.Raise (sender, e); + Maximized.Raise (this, null); } - protected void onUnmaximized (object sender, EventArgs e){ + protected void onUnmaximized (){ lock (IFace.LayoutMutex) { - Left = savedBounds.Left; - Top = savedBounds.Top; - Width = savedBounds.Width; - Height = savedBounds.Height; - IsMinimized = false; - Resizable = true; NotifyValueChanged ("ShowNormal", false); NotifyValueChanged ("ShowMinimize", true); NotifyValueChanged ("ShowMaximize", true); } - Unmaximized.Raise (sender, e); + Unmaximized.Raise (this, null); } - protected void onMinimized (object sender, EventArgs e){ + protected void onMinimized (){ lock (IFace.LayoutMutex) { if (IsNormal) - savedBounds = this.LastPaintedSlot; - Width = 200; - Height = 20; - Resizable = false; - IsMinimized = true; - NotifyValueChanged ("ShowNormal", true); - NotifyValueChanged ("ShowMinimize", false); - NotifyValueChanged ("ShowMaximize", true); + } - Minimize.Raise (sender, e); - } + Minimize.Raise (this, null); + }*/ public void onQuitPress (object sender, MouseButtonEventArgs e) { diff --git a/Crow/src/Widgets/Wrapper.cs b/Crow/src/Widgets/Wrapper.cs index 19243ba0..71ef6a0d 100644 --- a/Crow/src/Widgets/Wrapper.cs +++ b/Crow/src/Widgets/Wrapper.cs @@ -97,78 +97,85 @@ namespace Crow public override int measureRawSize (LayoutingType lt) { int tmp = 0; - //Wrapper can't fit in the opposite direction of the wrapper, this func is called only if Fit - if (lt == LayoutingType.Width) { - if (Orientation == Orientation.Vertical) { - Width = Measure.Stretched; + DbgLogger.StartEvent(DbgEvtType.GOMeasure, this); + try { + DbgLogger.SetMsg(DbgEvtType.GOMeasure, $"{lt}"); + + //Wrapper can't fit in the opposite direction of the wrapper, this func is called only if Fit + if (lt == LayoutingType.Width) { + if (Orientation == Orientation.Vertical) { + Width = Measure.Stretched; + return -1; + } else if (RequiredLayoutings.HasFlag (LayoutingType.Height)) + return -1; + else { + int dy = 0; + int largestChild = 0; + + childrenRWLock.EnterReadLock(); + try { + foreach (Widget c in Children) { + if (!c.IsVisible) + continue; + if (c.Height.IsRelativeToParent && + c.RequiredLayoutings.HasFlag (LayoutingType.Height)) { + return -1; + } + if (dy + c.Slot.Height > ClientRectangle.Height) { + dy = 0; + tmp += largestChild + Spacing; + largestChild = c.Slot.Width; + } else if (largestChild < c.Slot.Width) + largestChild = c.Slot.Width; + + dy += c.Slot.Height + Spacing; + } + } finally { + childrenRWLock.ExitReadLock (); + } + + if (dy == 0) + tmp -= Spacing; + return tmp + largestChild + 2 * Margin; + } + } else if (Orientation == Orientation.Horizontal) { + Height = Measure.Stretched; return -1; - } else if (RegisteredLayoutings.HasFlag (LayoutingType.Height)) + } else if (RequiredLayoutings.HasFlag (LayoutingType.Width)) return -1; else { - int dy = 0; - int largestChild = 0; + int dx = 0; + int tallestChild = 0; childrenRWLock.EnterReadLock(); try { foreach (Widget c in Children) { if (!c.IsVisible) continue; - if (c.Height.IsRelativeToParent && - c.RegisteredLayoutings.HasFlag (LayoutingType.Height)) { + if (c.Width.IsRelativeToParent && + c.RequiredLayoutings.HasFlag (LayoutingType.Width)) { return -1; } - if (dy + c.Slot.Height > ClientRectangle.Height) { - dy = 0; - tmp += largestChild + Spacing; - largestChild = c.Slot.Width; - } else if (largestChild < c.Slot.Width) - largestChild = c.Slot.Width; + if (dx + c.Slot.Width > ClientRectangle.Width) { + dx = 0; + tmp += tallestChild + Spacing; + tallestChild = c.Slot.Height; + } else if (tallestChild < c.Slot.Height) + tallestChild = c.Slot.Height; - dy += c.Slot.Height + Spacing; + dx += c.Slot.Width + Spacing; } } finally { - childrenRWLock.ExitReadLock (); + childrenRWLock.ExitReadLock(); } - if (dy == 0) + if (dx == 0) tmp -= Spacing; - return tmp + largestChild + 2 * Margin; - } - } else if (Orientation == Orientation.Horizontal) { - Height = Measure.Stretched; - return -1; - } else if (RegisteredLayoutings.HasFlag (LayoutingType.Width)) - return -1; - else { - int dx = 0; - int tallestChild = 0; - - childrenRWLock.EnterReadLock(); - try { - foreach (Widget c in Children) { - if (!c.IsVisible) - continue; - if (c.Width.IsRelativeToParent && - c.RegisteredLayoutings.HasFlag (LayoutingType.Width)) { - return -1; - } - if (dx + c.Slot.Width > ClientRectangle.Width) { - dx = 0; - tmp += tallestChild + Spacing; - tallestChild = c.Slot.Height; - } else if (tallestChild < c.Slot.Height) - tallestChild = c.Slot.Height; - - dx += c.Slot.Width + Spacing; - } - } finally { - childrenRWLock.ExitReadLock(); - } - - if (dx == 0) - tmp -= Spacing; - return tmp + tallestChild + 2 * Margin; + return tmp + tallestChild + 2 * Margin; } + } finally { + DbgLogger.EndEvent(DbgEvtType.GOMeasure); + } } public override bool UpdateLayout (LayoutingType layoutType) @@ -176,15 +183,10 @@ namespace Crow RegisteredLayoutings &= (~layoutType); if (layoutType == LayoutingType.ArrangeChildren) { - if ((RegisteredLayoutings & LayoutingType.Sizing) != 0) + if ((RequiredLayoutings & LayoutingType.Sizing) != 0) return false; ComputeChildrenPositions (); - - //if no layouting remains in queue for item, registre for redraw - if (RegisteredLayoutings == LayoutingType.None && IsDirty) - IFace.EnqueueForRepaint (this); - return true; } diff --git a/Samples/DebugLogAnalyzer/src/DebugInterface.cs b/Samples/DebugLogAnalyzer/src/DebugInterface.cs index a9cd51f1..a15b63aa 100644 --- a/Samples/DebugLogAnalyzer/src/DebugInterface.cs +++ b/Samples/DebugLogAnalyzer/src/DebugInterface.cs @@ -70,8 +70,10 @@ namespace Crow Thread.Sleep(1000); } - if (IsDirty) - delRegisterForRepaint(); + if (IsDirty) { + delRegisterForRepaint(); + //Console.WriteLine ("[DbgIFace]RegisterForRepaint"); + } Thread.Sleep (UPDATE_INTERVAL); } @@ -131,8 +133,8 @@ namespace Crow } public override void ForceMousePosition() { - Point p = (Point)delGetScreenCoordinate(); + Point p = Point.Parse(delGetScreenCoordinate().ToString()); Glfw.Glfw3.SetCursorPosition (WindowHandle, p.X + MousePosition.X, p.Y + MousePosition.Y); } } -}
\ No newline at end of file +} diff --git a/Samples/DebugLogAnalyzer/src/DebugInterfaceWidget.cs b/Samples/DebugLogAnalyzer/src/DebugInterfaceWidget.cs index a1bb8156..3ba9faaa 100644 --- a/Samples/DebugLogAnalyzer/src/DebugInterfaceWidget.cs +++ b/Samples/DebugLogAnalyzer/src/DebugInterfaceWidget.cs @@ -375,7 +375,7 @@ namespace Crow } protected override void UpdateCache(Context ctx) { - if (initialized && bmp != null) { + if (initialized && bmp != null) { paintCache (ctx, Slot + Parent.ClientRectangle.Position); delResetDirtyState (); } diff --git a/Samples/DebugLogAnalyzer/ui/DbgEventView.template b/Samples/DebugLogAnalyzer/ui/DbgEventView.template index 6679f150..2a61874e 100644 --- a/Samples/DebugLogAnalyzer/ui/DbgEventView.template +++ b/Samples/DebugLogAnalyzer/ui/DbgEventView.template @@ -5,6 +5,7 @@ <Label Text="Instance:" Foreground="White" Width="50%" /> <Label Text="{InstanceIndex}" Foreground="White" Background="Onyx" Width="Stretched" TextAlignment="Center"/> </HorizontalStack> + <Label Text="{Message}" Foreground="White" Background="Onyx" Width="Stretched" Visible="{HasMessage}" Margin="2" Tooltip="{}"/> <HorizontalStack Height="Fit" Width="Stretched" Spacing="2" Background="DimGrey" Margin="2"> <Label Text="Duration(ms):" Foreground="White" Width="50%" /> <Label Text="{DurationMS}" Foreground="White" Background="Onyx" Width="Stretched" TextAlignment="Right"/> diff --git a/Samples/DebugLogAnalyzer/ui/DbgEvtTooltip.crow b/Samples/DebugLogAnalyzer/ui/DbgEvtTooltip.crow index 2d5815e9..a3369249 100644 --- a/Samples/DebugLogAnalyzer/ui/DbgEvtTooltip.crow +++ b/Samples/DebugLogAnalyzer/ui/DbgEvtTooltip.crow @@ -6,6 +6,7 @@ <Label Text="Instance:" Foreground="White" Width="50%" /> <Label Text="{InstanceIndex}" Foreground="White" Background="Onyx" Width="Stretched" TextAlignment="Center"/> </HorizontalStack> + <Label Text="{Message}" Foreground="White" Background="Onyx" Width="Stretched" Visible="{HasMessage}" Margin="2" Tooltip="{}"/> <HorizontalStack Height="Fit" Width="Stretched" Spacing="2" Background="DimGrey" Margin="2"> <Label Text="Duration:" Foreground="White" Width="50%" /> <Label Text="{DurationMS}" Foreground="White" Background="Onyx" Width="Stretched" TextAlignment="Right"/> diff --git a/Samples/ShowCase/ui/showcase.crow b/Samples/ShowCase/ui/showcase.crow index 9e6b0cd2..431745f9 100644 --- a/Samples/ShowCase/ui/showcase.crow +++ b/Samples/ShowCase/ui/showcase.crow @@ -25,7 +25,7 @@ <ListItem ContextCommands="{GetCommands}" Selected="{/exp.Background=${ControlHighlight}}" Unselected="{/exp.Background=Transparent}"> - <Expandable Name="exp" Caption="{Name}" MouseDoubleClick="/onClickForExpand" BubbleMouseEvent="true"> + <Expandable Name="exp" Caption="{Name}" MouseDoubleClick="/onClickForExpand" > <Template> <VerticalStack> <Border CornerRadius="2" Margin="0" Height="Fit" MouseDoubleClick="./onClickForExpand" diff --git a/Samples/common/src/Editor.cs b/Samples/common/src/Editor.cs index 7b0f1f04..686afaed 100644 --- a/Samples/common/src/Editor.cs +++ b/Samples/common/src/Editor.cs @@ -110,7 +110,7 @@ namespace Crow Suggestions = (new string[] {"Stretched", "Fit"}). Where (s => s.StartsWith (currentToken.AsString (_text), StringComparison.OrdinalIgnoreCase)).ToList (); else if (pi.PropertyType == typeof (Fill)) - Suggestions = FastEnumUtility.FastEnum.GetValues<Colors> () + Suggestions = EnumsNET.Enums.GetValues<Colors> () .Where (s => s.ToString().StartsWith (currentToken.AsString (_text), StringComparison.OrdinalIgnoreCase)).ToList (); } } else if (currentToken.Type == TokenType.AttributeValueOpen) { @@ -124,7 +124,7 @@ namespace Crow else if (pi.PropertyType == typeof(bool)) Suggestions = new List<string> (new string[] {"true", "false"}); else if (pi.PropertyType == typeof (Fill)) - Suggestions = FastEnumUtility.FastEnum.GetValues<Colors> ().ToList (); + Suggestions = EnumsNET.Enums.GetValues<Colors> ().ToList (); else if (pi.PropertyType == typeof (Measure)) Suggestions = new List<string> (new string[] {"Stretched", "Fit"}); } diff --git a/Samples/common/src/SampleBase.cs b/Samples/common/src/SampleBase.cs index 75f998cd..8d7718ed 100644 --- a/Samples/common/src/SampleBase.cs +++ b/Samples/common/src/SampleBase.cs @@ -317,7 +317,7 @@ namespace Samples } - IList<Colors> testList = (IList<Colors>)FastEnumUtility.FastEnum.GetValues<Colors>().ToList();//.ColorDic.Values//.OrderBy(c=>c.Hue) + IList<Colors> testList = (IList<Colors>)EnumsNET.Enums.GetValues<Colors>().ToList();//.ColorDic.Values//.OrderBy(c=>c.Hue) //.ThenBy(c=>c.Value).ThenBy(c=>c.Saturation) //.ToList (); public IList<Colors> TestList @@ -330,7 +330,7 @@ namespace Samples get { return testList; } } void OnClear(object sender, MouseButtonEventArgs e) => TestList = null; - void OnLoadList(object sender, MouseButtonEventArgs e) => TestList = (IList<Colors>)FastEnumUtility.FastEnum.GetValues<Colors>().ToList(); + void OnLoadList(object sender, MouseButtonEventArgs e) => TestList = (IList<Colors>)EnumsNET.Enums.GetValues<Colors>().ToList(); string curSources = ""; diff --git a/Samples/common/ui/Interfaces/Divers/0.crow b/Samples/common/ui/Interfaces/Divers/0.crow index 263edfc7..d9ba0161 100644 --- a/Samples/common/ui/Interfaces/Divers/0.crow +++ b/Samples/common/ui/Interfaces/Divers/0.crow @@ -1,5 +1,5 @@ <?xml version="1.0" encoding="UTF-8"?> -<Window Caption="Showcase" Height="90%" Width="90%" Background="DarkGrey"> +<Window Caption="Showcase" Height="90%" Width="91%" Background="DarkGrey"> <HorizontalStack> <VerticalStack Width="30%" Margin="5"> <ListBox Data="{PerfMeasures}" Height="Fit"> diff --git a/Samples/common/ui/Interfaces/Divers/color3.crow b/Samples/common/ui/Interfaces/Divers/color3.crow new file mode 100644 index 00000000..1788004c --- /dev/null +++ b/Samples/common/ui/Interfaces/Divers/color3.crow @@ -0,0 +1,7 @@ +<?xml version="1.0"?> +<VerticalStack> + <Widget Name="go" Width="100" Height="60" Background="DarkBlue"/> + <Widget Width="100" Height="60" Background="{../colorPicker.CurrentColor}"/> + <Label Text="{../colorPicker.CurrentColor}"/> + <ColorPicker CurrentColor="{²../go.Background}" Name="colorPicker" Background="DimGrey" MinimumSize="0,0" Width="300" Template="/mnt/devel/CrowIDE/Crow/Samples/common/ui/templates/ColorPicker.template" /> +</VerticalStack>
\ No newline at end of file diff --git a/Samples/common/ui/Interfaces/Divers/fitListWithStretchedItems.crow b/Samples/common/ui/Interfaces/Divers/fitListWithStretchedItems.crow index 6fd59f14..f159a6b2 100644 --- a/Samples/common/ui/Interfaces/Divers/fitListWithStretchedItems.crow +++ b/Samples/common/ui/Interfaces/Divers/fitListWithStretchedItems.crow @@ -1,5 +1,4 @@ <?xml version="1.0"?> - <ListBox Data="{TestList}" Width="Fit" Focusable="true" > <Template> <Scroller Name="ItemsScroller" Height="Stretched" Background="Onyx" Margin="10"> diff --git a/Samples/common/ui/Interfaces/Divers/testDisable.crow b/Samples/common/ui/Interfaces/Divers/testDisable.crow index 68d1cebb..f71a6110 100644 --- a/Samples/common/ui/Interfaces/Divers/testDisable.crow +++ b/Samples/common/ui/Interfaces/Divers/testDisable.crow @@ -6,8 +6,8 @@ <Label Text="{fps}" IsEnabled="true" Font="30"/> <Label Text="{fps}" IsEnabled="false" Font="30" Background="SeaGreen"/> <Label Text="{fps}" IsEnabled="true" Font="30" Background="SeaGreen"/> - <Button Caption="Button" IsEnabled="true" Background="Grey"/> - <Button Caption="Button" IsEnabled="false" Background="Grey"/> + <Button Caption="Button" IsEnabled="true" Background="DimGrey"/> + <Button Caption="Button" IsEnabled="false" Background="DimGrey"/> <Button Caption="Button" IsEnabled="true" /> <Button Caption="Button" IsEnabled="false" /> <Spinner Fit="true"/> diff --git a/Samples/common/ui/Interfaces/Divers/windows.crow b/Samples/common/ui/Interfaces/Divers/windows.crow new file mode 100644 index 00000000..5e4454a6 --- /dev/null +++ b/Samples/common/ui/Interfaces/Divers/windows.crow @@ -0,0 +1 @@ +<Window CurrentState="Normal" Width="200" Height="200"/>
\ No newline at end of file diff --git a/Samples/common/ui/Interfaces/Experimental/colorPicktest.crow b/Samples/common/ui/Interfaces/Experimental/colorPicktest.crow new file mode 100644 index 00000000..1db2be6b --- /dev/null +++ b/Samples/common/ui/Interfaces/Experimental/colorPicktest.crow @@ -0,0 +1,23 @@ +<ColorPicker Width="Fit" Height="Stretched" Background="Onyx"> + <Template> + <ListBox Data="{./AvailableColors}" Margin="15"> + <Template> + <Scroller> + <VerticalStack Name="ItemsContainer" Height="Fit" VerticalAlignment="Top" Background="DarkGrey" Margin="5" /> + </Scroller> + </Template> + <ItemTemplate> + <ListItem Margin="1" Width="Stretched" + Selected="{Background=RoyalBlue}" + Unselected="{Background=Transparent}"> + <HorizontalStack Height="Fit" > + <Widget Width="20" Height="14" Background="{}" CornerRadius="3"/> + <Label Text="{}" Width="Stretched" /> + </HorizontalStack> + </ListItem> + </ItemTemplate> + </ListBox> + </Template> +</ColorPicker> + +
\ No newline at end of file diff --git a/Samples/common/ui/Interfaces/Experimental/colorPicktest2.crow b/Samples/common/ui/Interfaces/Experimental/colorPicktest2.crow new file mode 100644 index 00000000..63991ff1 --- /dev/null +++ b/Samples/common/ui/Interfaces/Experimental/colorPicktest2.crow @@ -0,0 +1,19 @@ +<ColorPicker Height="Stretched" Background="Onyx" Width="Fit"> + <Template> + <ListBox Width="Stretched" Data="{./AvailableColors}" Margin="10"> + <Template> + <Scroller Name="scroller1" Margin="5" ClipToClientRect="true" Background="Onyx"> + <VerticalStack Name="ItemsContainer" Height="Fit" VerticalAlignment="Top"/> + </Scroller> + </Template> + <ItemTemplate> + <ListItem Margin="1" Width="Stretched" + Selected="{Background=White}" + Unselected="{Background=Transparent}" > + <Label CornerRadius="3" Margin="2" Background="{}" Text="{}" Width="Stretched" /> + </ListItem> + </ItemTemplate> + </ListBox> + </Template> +</ColorPicker> +
\ No newline at end of file diff --git a/Samples/common/ui/Interfaces/Experimental/multiColorPick2.crow b/Samples/common/ui/Interfaces/Experimental/multiColorPick2.crow index 5d6e2364..21490b71 100644 --- a/Samples/common/ui/Interfaces/Experimental/multiColorPick2.crow +++ b/Samples/common/ui/Interfaces/Experimental/multiColorPick2.crow @@ -11,7 +11,7 @@ </HorizontalStack> </Template>/> <TabView MinimumSize="{../MinimumPopupSize}" Width="200" Height="200" > - <ColorPicker Name="HSV" CurrentColor="{²../../../CurrentColor}" Background="Onyx" BubbleMouseEvent="false"/> + <ColorPicker Name="HSV" CurrentColor="{²../../../CurrentColor}" Background="Onyx" /> <ColorPicker IsVisible="false" Name="Names" CurrentColor="{²../../../CurrentColor}" Height="Stretched" Background="Onyx"> <Template> <ListBox Width="Stretched" Data="{./AvailableColors}" SelectedItemChanged="./onSelectedItemChanged"> diff --git a/Samples/common/ui/Interfaces/Experimental/tabView1.crow b/Samples/common/ui/Interfaces/Experimental/tabView1.crow index 5df13d0a..773ec4fe 100644 --- a/Samples/common/ui/Interfaces/Experimental/tabView1.crow +++ b/Samples/common/ui/Interfaces/Experimental/tabView1.crow @@ -1,4 +1,4 @@ <TabView> - <GroupBox Caption="test" Background="Black"/> - <GroupBox Caption="test" Background="Black"/> + <GroupBox Caption="test" Background="Red"/> + <GroupBox Caption="test" Background="Blue"/> </TabView>
\ No newline at end of file diff --git a/Samples/common/ui/Interfaces/Stack/StretchedInFit1.crow b/Samples/common/ui/Interfaces/Stack/StretchedInFit1.crow new file mode 100644 index 00000000..fc31fe00 --- /dev/null +++ b/Samples/common/ui/Interfaces/Stack/StretchedInFit1.crow @@ -0,0 +1,26 @@ +<?xml version="1.0"?> +<VerticalStack Background="DimGrey" Margin="1" Width="Fit" Height="Fit"> +<VerticalStack Background="DimGrey" Margin="1" Width="Stretched" Height="Fit"> +<VerticalStack Background="DimGrey" Margin="1" Width="Stretched" Height="Fit"> +<VerticalStack Background="DimGrey" Margin="1" Width="Stretched" Height="Fit"> + <Label Text="this " Margin="0" Width="Stretched" Height="Fit" Background="SeaGreen"/> + <Label Text="this is a test" Margin="0" Width="Stretched" Height="Fit" Background="SeaGreen"/> + <Label Text="this is a test" Margin="0" Width="Stretched" Height="Fit" Background="SeaGreen"/> + <Label Text="this is a test" Margin="0" Width="Stretched" Height="Fit" Background="SeaGreen"/> + <Label Text="this is a test" Margin="0" Width="Stretched" Height="Fit" Background="SeaGreen"/> + <Label Text="this is a test" Margin="0" Width="Stretched" Height="Fit" Background="SeaGreen"/> + <Label Text="this is a test" Margin="0" Width="Stretched" Height="Fit" Background="SeaGreen"/> + <Label Text="this is a test" Margin="0" Width="Stretched" Height="Fit" Background="SeaGreen"/> + <Label Text="this is a test" Margin="0" Width="Stretched" Height="Fit" Background="SeaGreen"/> + <Label Text="this is a test" Margin="0" Width="Stretched" Height="Fit" Background="SeaGreen"/> + <Label Text="this is a test" Margin="0" Width="Stretched" Height="Fit" Background="SeaGreen"/> + <Label Text="thismlkjqsdfmsmlfkj " Margin="0" Width="Stretched" Height="Fit" Background="SeaGreen"/> + <Label Text="this is a test" Margin="0" Width="Stretched" Height="Fit" Background="SeaGreen"/> + <Label Text="this is a test" Margin="0" Width="Stretched" Height="Fit" Background="SeaGreen"/> + <Label Text="this is a test" Margin="0" Width="Stretched" Height="Fit" Background="SeaGreen"/> + <Label Text="this is a test" Margin="0" Width="Stretched" Height="Fit" Background="SeaGreen"/> + <Label Text="this is a test" Margin="0" Width="Stretched" Height="Fit" Background="SeaGreen"/> +</VerticalStack> +</VerticalStack> +</VerticalStack> +</VerticalStack>
\ No newline at end of file diff --git a/Samples/common/ui/Interfaces/Stack/StretchedInFit3.1.crow b/Samples/common/ui/Interfaces/Stack/StretchedInFit3.1.crow new file mode 100644 index 00000000..586c36f1 --- /dev/null +++ b/Samples/common/ui/Interfaces/Stack/StretchedInFit3.1.crow @@ -0,0 +1,15 @@ +<?xml version="1.0"?> +<VerticalStack Height="Fit" Width="Fit" Margin="10" Background="Onyx"> + <HorizontalStack Width="Stretched"> + <Label Text="th" Width="Stretched" Background="Grey"/> + <Label Text="this is a fit label" Width="Fit" Background="Teal"/> + </HorizontalStack> + <HorizontalStack Width="Stretched"> + <Label Text="this is a stretchedlkqsdflkj" Width="Stretched" Background="Grey"/> + <Label Text="this" Width="Fit" Background="Teal"/> + </HorizontalStack> + <HorizontalStack Width="Stretched"> + <Label Text="this is a stretched label" Width="Stretched" Background="Grey"/> + <Label Text="th" Width="Fit" Background="Teal"/> + </HorizontalStack> +</VerticalStack> diff --git a/Samples/common/ui/Interfaces/Stack/StretchedInFit3.2.crow b/Samples/common/ui/Interfaces/Stack/StretchedInFit3.2.crow new file mode 100644 index 00000000..e08b09be --- /dev/null +++ b/Samples/common/ui/Interfaces/Stack/StretchedInFit3.2.crow @@ -0,0 +1,7 @@ +<?xml version="1.0"?> +<Container Height="Fit" Width="Fit" Margin="1" Background="CornflowerBlue"> + <VerticalStack Height="Stretched" > + <Label Text="this is a stretched label" Width="Stretched" Height="Stretched"/> + <Label Text="this is a fit label" Width="Stretched" Height="Fit"/> + </VerticalStack> +</Container> diff --git a/Samples/common/ui/Interfaces/Stack/StretchedInFit3.3.crow b/Samples/common/ui/Interfaces/Stack/StretchedInFit3.3.crow new file mode 100644 index 00000000..3643b13e --- /dev/null +++ b/Samples/common/ui/Interfaces/Stack/StretchedInFit3.3.crow @@ -0,0 +1,17 @@ +<?xml version="1.0"?> +<Container Width="Stretched"> +<VerticalStack Height="Fit" Width="Stretched" Margin="5" Background="Onyx"> + <HorizontalStack Width="Fit" > + <Label Text="thed label" Width="Stretched" Background="Grey"/> + <Label Text="this label" Width="Fit" Background="Teal"/> + </HorizontalStack> + <HorizontalStack Width="Stretched"> + <Label Text="this is a stretched label" Width="Stretched" Background="Grey"/> + <Label Text="this is a fit label" Width="Fit" Background="Teal"/> + </HorizontalStack> + <HorizontalStack Width="Stretched" > + <Label Text="this is a stret" Width="Stretched" Background="Grey"/> + <Label Text="thi" Width="Fit" Background="Teal"/> + </HorizontalStack> +</VerticalStack> +</Container> diff --git a/Samples/common/ui/Interfaces/Stack/StretchedInFit3.4.crow b/Samples/common/ui/Interfaces/Stack/StretchedInFit3.4.crow new file mode 100644 index 00000000..31791555 --- /dev/null +++ b/Samples/common/ui/Interfaces/Stack/StretchedInFit3.4.crow @@ -0,0 +1,4 @@ +<HorizontalStack Height="Fit" Width="Fit" Background="DarkSlateBlue" Margin="10"> + <Label Name="lab" Text="this is a long stretched label" Width="Stretched" Background="Grey"/> + <Label Text="label" Width="Fit" Background="Teal"/> +</HorizontalStack> diff --git a/Samples/common/ui/Interfaces/Stack/StretchedInFit3.5.crow b/Samples/common/ui/Interfaces/Stack/StretchedInFit3.5.crow new file mode 100644 index 00000000..b7fe4fa5 --- /dev/null +++ b/Samples/common/ui/Interfaces/Stack/StretchedInFit3.5.crow @@ -0,0 +1,17 @@ +<?xml version="1.0"?> +<Container Width="Stretched"> +<VerticalStack Height="Fit" Width="Fit" Margin="5" Background="Onyx"> + <HorizontalStack Width="Stretched" > + <Label Text="stretched-end" Width="Stretched" Background="Grey"/> + <Label Text="fit" Width="Fit" Background="Teal"/> + </HorizontalStack> + <HorizontalStack Width="Stretched"> + <Label Text="stretched labelsdqfqsfdqsdfqsdfqsdfdsqfqsdfqsdfqsdfdqsfdqsfdqsfdqsfdqsfqsdfdqsfdqsfdqsfdqsfdqsfqsdf" Width="Stretched" Background="Grey"/> + <Label Text="fit" Width="Fit" Background="Teal"/> + </HorizontalStack> + <HorizontalStack Width="Stretched" > + <Label Text="stretched-end" Width="Stretched" Background="Grey"/> + <Label Text="fit" Width="Fit" Background="Teal"/> + </HorizontalStack> +</VerticalStack> +</Container> diff --git a/Samples/common/ui/Interfaces/Stack/StretchedInFit3.crow b/Samples/common/ui/Interfaces/Stack/StretchedInFit3.crow index 84c057ff..b9516942 100644 --- a/Samples/common/ui/Interfaces/Stack/StretchedInFit3.crow +++ b/Samples/common/ui/Interfaces/Stack/StretchedInFit3.crow @@ -4,10 +4,10 @@ <VerticalStack Width="Stretched" Margin="10" Background="FireBrick"> <VerticalStack Width="Stretched" Margin="10" Background="Teal"> <VerticalStack Width="Stretched" Margin="10" Background="CornflowerBlue"> - <Label Text="{./Caption}" Width="Stretched"/> - <Label Text="{./Caption}" Width="Stretched"/> - <Label Text="{./Caption}" Width="Stretched"/> - <Label Text="{./Caption}" Width="Stretched"/> + <Label Text="label" Width="Stretched"/> + <Label Text="a bit longer" Width="Stretched"/> + <Label Text="cow" Width="Stretched"/> + <Label Text="horse" Width="Stretched"/> </VerticalStack> </VerticalStack> </VerticalStack> diff --git a/Samples/common/ui/Interfaces/Stack/StretchedInFit5.crow b/Samples/common/ui/Interfaces/Stack/StretchedInFit5.crow index 68078f98..0036d272 100644 --- a/Samples/common/ui/Interfaces/Stack/StretchedInFit5.crow +++ b/Samples/common/ui/Interfaces/Stack/StretchedInFit5.crow @@ -1,7 +1,9 @@ <?xml version="1.0"?> -<VerticalStack Background="DimGrey" Margin="10" Width="Fit" Height="Fit" > - <CheckBox Name="cb"/> - <CheckBox Name="cb2"/> +<VerticalStack Background="DimGrey" Margin="10" Width="Fit" Height="Fit" + MouseEnter="{Background=Blue}" + MouseLeave="{Background=DimGrey}" > + <CheckBox Name="cb" MouseEnter="{Background=DarkRed}" MouseLeave="{Background=Transparent}"/> + <CheckBox Name="cb2" MouseEnter="{Background=DarkRed}" MouseLeave="{Background=Transparent}"/> <Container Visible="{²../cb.IsChecked}" Width="Stretched" Margin="10" Background="RoyalBlue"> <VerticalStack Margin="5" Background="Yellow"> <VerticalStack Margin="5" Background="Teal"> diff --git a/Samples/common/ui/Interfaces/TemplatedControl/testItemTemplateTag.crow b/Samples/common/ui/Interfaces/TemplatedControl/testItemTemplateTag.crow index fd873489..ca8a955e 100644 --- a/Samples/common/ui/Interfaces/TemplatedControl/testItemTemplateTag.crow +++ b/Samples/common/ui/Interfaces/TemplatedControl/testItemTemplateTag.crow @@ -1,7 +1,7 @@ <?xml version="1.0"?> <Border BorderWidth="2" Fit="true" Background="DarkGrey"> <VerticalStack Fit="true" Margin="5"> - <ListBox Data="{TestList}" Background="Jet" HorizontalAlignment="Center" Width="200" Height="200" Margin="5"> + <ListBox Data="{TestList}" Background="Jet" HorizontalAlignment="Center" Width="Fit" Height="200" Margin="5"> <Template> <Border BorderWidth="1" Background="{./Background}"> <HorizontalStack Margin="1"> @@ -18,7 +18,7 @@ <ItemTemplate DataType="Crow.Colors"> <HorizontalStack HorizontalAlignment="Left" - Height="Fit" Width="200" Margin="1" Focusable="true" + Height="Fit" Width="Stretched" Margin="1" Focusable="true" MouseEnter="{Background=RoyalBlue}" MouseLeave="{Background=Transparent}"> diff --git a/Samples/common/ui/Interfaces/colorPicker.tmp b/Samples/common/ui/Interfaces/colorPicker.tmp index 085e17ad..e87399d6 100644 --- a/Samples/common/ui/Interfaces/colorPicker.tmp +++ b/Samples/common/ui/Interfaces/colorPicker.tmp @@ -8,7 +8,7 @@ </HorizontalStack> </Template>/> <TabView MinimumSize="{../MinimumPopupSize}" Width="200" Height="200" > - <ColorPicker Name="HSV" CurrentColor="{²../../../CurrentColor}" Background="Onyx" BubbleMouseEvent="false"/> + <ColorPicker Name="HSV" CurrentColor="{²../../../CurrentColor}" Background="Onyx" /> <ColorPicker IsVisible="false" Name="Names" CurrentColor="{²../../../CurrentColor}" Height="Stretched" Background="Onyx"> <Template> <ListBox Width="Stretched" Data="{./AvailableColors}" SelectedItemChanged="./onSelectedItemChanged"> diff --git a/Samples/common/ui/templates/ColorPicker.template b/Samples/common/ui/templates/ColorPicker.template index 085e17ad..e87399d6 100644 --- a/Samples/common/ui/templates/ColorPicker.template +++ b/Samples/common/ui/templates/ColorPicker.template @@ -8,7 +8,7 @@ </HorizontalStack> </Template>/> <TabView MinimumSize="{../MinimumPopupSize}" Width="200" Height="200" > - <ColorPicker Name="HSV" CurrentColor="{²../../../CurrentColor}" Background="Onyx" BubbleMouseEvent="false"/> + <ColorPicker Name="HSV" CurrentColor="{²../../../CurrentColor}" Background="Onyx" /> <ColorPicker IsVisible="false" Name="Names" CurrentColor="{²../../../CurrentColor}" Height="Stretched" Background="Onyx"> <Template> <ListBox Width="Stretched" Data="{./AvailableColors}" SelectedItemChanged="./onSelectedItemChanged"> diff --git a/Samples/common/ui/templates/testitems.crow b/Samples/common/ui/templates/testitems.crow new file mode 100644 index 00000000..f09b9c62 --- /dev/null +++ b/Samples/common/ui/templates/testitems.crow @@ -0,0 +1,23 @@ +<ColorPicker Name="Names" Height="Stretched" Background="Onyx"> + <Template> + <ListBox Height="Fit" Width="Stretched" Data="{./AvailableColors}" > + <ItemTemplate> + <ListItem Margin="0" Height="16" Width="Fit" + Selected="{Background=Black}" + Unselected="{Background=Transparent}"> + <Label Height="Fit" Width="Fit" Text="{}" Background="{}" Margin="5"/> + </ListItem> + </ItemTemplate> + <Template> + <VerticalStack Width="Stretched" > + <Scroller Name="scroller" > + <HorizontalStack Name="ItemsContainer" Width="Fit" HorizontalAlignment="Left"/> + </Scroller> + <ScrollBar Style="HScrollBar" Name="scrollbar1" Value="{²../scroller.ScrollX}" + LargeIncrement="{../scroller.PageWidth}" SmallIncrement="30" CursorRatio="{../scroller.ChildWidthRatio}" + Maximum="{../scroller.MaxScrollX}" Height="12" /> + </VerticalStack> + </Template> + </ListBox> + </Template> +</ColorPicker>
\ No newline at end of file diff --git a/Samples/dockableWindows/dockableWindows.cs b/Samples/dockableWindows/dockableWindows.cs index a08e7afb..1dccc7b8 100644 --- a/Samples/dockableWindows/dockableWindows.cs +++ b/Samples/dockableWindows/dockableWindows.cs @@ -9,6 +9,7 @@ namespace tests static void Main () { using (BasicTests app = new BasicTests ()) { + app.SolidBackground = false; app.Run (); } } diff --git a/Samples/dockableWindows/ui/dock.style b/Samples/dockableWindows/ui/dock.style index ef3f43e1..49c7f03c 100644 --- a/Samples/dockableWindows/ui/dock.style +++ b/Samples/dockableWindows/ui/dock.style @@ -5,6 +5,9 @@ DockStack { } DockWindow { Template="#ui.dockWin.template"; + AllowedStates="Normal|Maximized|Minimized"; + Width="260"; + Height="200"; } TabView { Template="#ui.TabView.template"; diff --git a/Samples/dockableWindows/ui/dockWin.template b/Samples/dockableWindows/ui/dockWin.template index c53b260c..971be0c4 100644 --- a/Samples/dockableWindows/ui/dockWin.template +++ b/Samples/dockableWindows/ui/dockWin.template @@ -1,24 +1,43 @@ <?xml version="1.0"?> <Border Name="SizeHandle" BorderWidth="1" Foreground="Black" CornerRadius="{./CornerRadius}" StickyMouse="8" StickyMouseEnabled="{./IsFloating}" Background="{./Background}"> - <VerticalStack Spacing="0"> + <VerticalStack Spacing="0" Name="MoveHandle"> <HorizontalStack Height="Fit" IsVisible="{./IsDocked}" Background="Black"> <Label Text="{./Caption}"/> + <Label Text="{./CurrentState}" Margin="1" Foreground="Black" Background="Grey"/> <Label Text="{./DockingPosition}"/> + <ListBox Data="{./DockCommands}" Fit="true"> + <Template> + <HorizontalStack Name="ItemsContainer" /> + </Template> + <ItemTemplate Path="#Crow.WindowButton.template"/> + </ListBox> + <ListBox Data="{./Commands}" Fit="true"> + <Template> + <HorizontalStack Name="ItemsContainer" /> + </Template> + <ItemTemplate Path="#Crow.WindowButton.template"/> + </ListBox> </HorizontalStack> <HorizontalStack Background="vgradient|0:0.5,0.6,0.5,0.5|1:0.2,0.3,0.3,0.7" Name="hs" Margin="0" Spacing="0" Height="Fit" Visible="{./IsFloating}"> <Widget Width="5"/> <Image Margin="1" Width="10" Height="10" Path="{./Icon}"/> <Label Text="{./Caption}"/> + <Label Text="{./CurrentState}" Margin="1" Foreground="Black" Background="Grey"/> <Label Width="Stretched" Foreground="White" Margin="1" TextAlignment="Left" Text="{./DockingPosition}" /> - <Border CornerRadius="6" BorderWidth="1" Foreground="Transparent" Height="10" Width="10" - MouseEnter="{Foreground=White}" MouseLeave="{Foreground=Transparent}"> - <Image Focusable="true" Name="Image" Margin="0" Path="#Crow.Icons.exit2.svg" - MouseClick="./onQuitPress"/> - </Border> - <Widget Width="5"/> - </HorizontalStack> + <ListBox Data="{./DockCommands}" Fit="true"> + <Template> + <HorizontalStack Name="ItemsContainer" /> + </Template> + <ItemTemplate Path="#Crow.WindowButton.template"/> + </ListBox> + <ListBox Data="{./Commands}" Fit="true"> + <Template> + <HorizontalStack Name="ItemsContainer" /> + </Template> + <ItemTemplate Path="#Crow.WindowButton.template"/> + </ListBox> </HorizontalStack> <Container Name="Content" MinimumSize="50,50"/> </VerticalStack> </Border> |