diff options
| author | Jean-Philippe Bruyère <jp_bruyere@hotmail.com> | 2021-07-01 23:38:09 +0200 |
|---|---|---|
| committer | Jean-Philippe Bruyère <jp_bruyere@hotmail.com> | 2021-07-01 23:38:09 +0200 |
| commit | a4386e4844dbb85b804770d936b2d47c7584d258 (patch) | |
| tree | 85113f4aa66fa77f2e4cde0d4e02bc8eeadbd962 | |
| parent | 6c4bb7e2c26c3a4c612fdece4dee96282391007a (diff) | |
wip
109 files changed, 1598 insertions, 1475 deletions
diff --git a/Crow/Crow.csproj b/Crow/Crow.csproj index 29aca878..d5d50114 100644 --- a/Crow/Crow.csproj +++ b/Crow/Crow.csproj @@ -23,7 +23,7 @@ <GeneratePackageOnBuild>True</GeneratePackageOnBuild> <GenerateDocumentationFile>true</GenerateDocumentationFile> <NoWarn>$(NoWarn);1591;1587;1570;1572;1573;1574</NoWarn> - <DefineConstants>DESIGN_MODE;MEASURE_TIME;_DEBUG_HIGHLIGHT_FOCUS</DefineConstants> + <DefineConstants>MEASURE_TIME;_DEBUG_HIGHLIGHT_FOCUS</DefineConstants> <EnableDefaultItems>false</EnableDefaultItems> <EnableDefaultCompileItems>false</EnableDefaultCompileItems> <!--<AllowUnsafeBlocks>true</AllowUnsafeBlocks>--> @@ -60,15 +60,21 @@ <PropertyGroup Condition=" '$(CrowDebugLogEnabled)' == 'true'" > <DefineConstants>$(DefineConstants);DEBUG_LOG</DefineConstants> </PropertyGroup> - <ItemGroup> + <PropertyGroup Condition=" '$(CrowDebugStatsEnabled)' == 'true'" > + <DefineConstants>$(DefineConstants);DEBUG_STATS</DefineConstants> + </PropertyGroup> + <PropertyGroup Condition=" '$(CrowDesignModeEnabled)' == 'true'" > + <DefineConstants>$(DefineConstants);DESIGN_MODE</DefineConstants> + </PropertyGroup> + <!--<ItemGroup> <ProjectReference Include="..\CrowDbgShared\CrowDbgShared.csproj" /> - </ItemGroup> + </ItemGroup>--> <ItemGroup> <Content Include="..\Images\crow.png" Pack="true" PackagePath="" /> <Compile Include="src\**\*.cs" Exclude="src\Mono.Cairo\NativeMethods-internal.cs" /> <EmbeddedResource Include="Templates\*.*"> - <LogicalName>Crow.%(Filename).template</LogicalName> + <LogicalName>Crow.%(Filename)%(Extension)</LogicalName> </EmbeddedResource> <EmbeddedResource Include="Default.style" /> <EmbeddedResource Include="Icons\*.*" /> diff --git a/Crow/Default.style b/Crow/Default.style index 9f206629..5c88c062 100644 --- a/Crow/Default.style +++ b/Crow/Default.style @@ -25,28 +25,25 @@ MenuBackground = "Jet"; InactiveTabItem = "DarkGrey"; -Button, CheckBox, RadioButton, ComboBox, Expandable, -MessageBox, Popper, Slider, Spinner, TextBox { - //Focusable = "true"; - Foreground="${ControlForeground}"; - Height = "Fit"; - Background = "${ControlBackground}"; - CornerRadius = "${ControlCornerRadius}"; - Margin="0"; +Border { + BorderWidth = "${ControlBorderWidth}"; + Foreground = "${ControlBorderColor}"; + Margin = "${ControlInsideMargin}"; } -Border { Margin = "1"; } - CheckBox { Caption = "CheckBox"; } RadioButton { Caption = "RadioButton"; } Expandable { Caption = "Expandable"; } Popper { Caption = "Popper";} -GroupBox { Caption = "Group Box"; } +GroupBox { + Caption = "Group Box"; + Foreground = "${ControlForeground}"; +} Control { Margin="${ControlInsideMargin}"; Spacing="3"; - //Foreground = "${ControlForeground}"; + Foreground = "${ControlForeground}"; //MouseEnter = "{Foreground=${ControlCaptionHoverColor}}"; //MouseLeave = "{Foreground=${ControlForeground}}"; } @@ -77,7 +74,7 @@ Wrapper { Button { Caption = "Button"; MinimumSize = "50,22"; - Height = "22"; + Height = "Fit"; Width = "Fit"; } Label { @@ -96,6 +93,8 @@ TextBox { Foreground = "Black"; CursorColor = "Black"; Focusable = "True"; + Width = "Inherit"; + Height = "Inherit"; //Text = "TextBox"; Margin = "1"; } @@ -105,6 +104,7 @@ Menu { Height = "Fit"; Width = "Stretched"; VerticalAlignment = "Top"; + UseLoadingThread = "false"; //SelectionBackground = "${ControlHighlight}"; //SelectionColoring = "false"; } @@ -116,6 +116,7 @@ MenuItem { Foreground = "${ControlForeground}"; MouseEnter = "{Background=${ControlHighlight}}"; MouseLeave = "{Background=${MenuBackground}}"; + UseLoadingThread = "false"; //SelectionBackground = "${ControlHighlight}"; //SelectionBackground = "Transparent"; //SelectionColoring = "false"; @@ -238,8 +239,8 @@ TxtInFileDialog { CheckBoxAlt { Template= "#Crow.CheckBox2.template"; Background = "Transparent"; - Checked="{Background=Grey;Foreground=LightGrey;}"; - Unchecked = "{Background=Transparent;Foreground=DimGrey;}"; + Checked="{Background=Grey};{Foreground=LightGrey}"; + Unchecked = "{Background=Transparent};{Foreground=DimGrey}"; } ArrowBut { @@ -262,6 +263,7 @@ ScrollBar { Foreground="Transparent"; Background="Onyx"; Width = "14"; + Height = "Inherit"; CornerRadius = "0"; } HScrollBar { @@ -269,7 +271,7 @@ HScrollBar { Maximum = "0"; Value = "0"; Height = "14"; - Width = "Stretched"; + Width = "Inherit"; Orientation = "Horizontal"; } EnumSelector { @@ -309,4 +311,18 @@ TableHeaderLabel { Margin = "1"; //Background = "Jet"; Foreground = "LightGrey"; +} + +Button, CheckBox, RadioButton, ComboBox, Expandable, +MessageBox, Popper, Slider, Spinner, TextBox, NumericControl { + //Focusable = "true"; + Foreground="${ControlForeground}"; + Height = "Fit"; + Background = "${ControlBackground}"; + CornerRadius = "${ControlCornerRadius}"; + Margin="0"; + BubbleMouseEvent="false"; +} +TemplatedControl, GenericStack { + CacheEnabled="true"; }
\ No newline at end of file diff --git a/Crow/Icons/crow.png b/Crow/Icons/crow.png Binary files differnew file mode 100644 index 00000000..7b737d04 --- /dev/null +++ b/Crow/Icons/crow.png diff --git a/Crow/Templates/Button.template b/Crow/Templates/Button.template index ca1119a5..daa09c6a 100644 --- a/Crow/Templates/Button.template +++ b/Crow/Templates/Button.template @@ -1,10 +1,9 @@ <?xml version="1.0"?> -<Border Background="{./Background}" Name="Content" Width="Stretched" Height="Stretched" +<Border Background="{./Background}" Name="Content" Foreground="Transparent" CornerRadius="{../CornerRadius}" BorderWidth="1" - MouseEnter="{Foreground=vgradient|0:White|0.2:Grey|0.9:Grey|1:Black};{caption.Foreground=White}" - MouseLeave="{Foreground=Transparent};{caption.Foreground=LightGrey}" + MouseEnter="{Foreground=vgradient|0:White|0.2:Grey|0.9:Grey|1:Black}" + MouseLeave="{Foreground=Transparent}" MouseDown="{Foreground=vgradient|0:Black|0.05:Grey|0.85:Grey|1:White}" - MouseUp="{Foreground=vgradient|0:White|0.2:Grey|0.9:Grey|1:Black}" - > - <Label Font="{./Font}" Name="caption" Margin="3" Foreground="LightGrey" Text="{./Caption}"/> + MouseUp="{Foreground=vgradient|0:White|0.2:Grey|0.9:Grey|1:Black}" > + <Label Font="{./Font}" Name="caption" Margin="6" Foreground="{./Foreground}" Text="{./Caption}"/> </Border> diff --git a/Crow/Templates/ContextMenu.template b/Crow/Templates/ContextMenu.template index 5ca0f177..2d41ffbf 100644 --- a/Crow/Templates/ContextMenu.template +++ b/Crow/Templates/ContextMenu.template @@ -1,41 +1,10 @@ <?xml version="1.0" encoding="UTF-8" ?> -<MenuItem MinimumSize="20,20" Height="Fit" Width="160" Caption="Context Menu" Data="{ContextCommands}" Orientation="Vertical" - IsOpened ="true" Visible="{/IsOpened}" Background="Red"> - <Template> - <HorizontalStack> - <Border Background="DarkGrey" Foreground="Black" CornerRadius="0"> - <GenericStack Orientation="{./Orientation}" Name="ItemsContainer" Margin="2"/> - </Border> - </HorizontalStack> +<MenuItem MinimumSize="20,20" Height="Fit" Width="160" Caption="Context Menu" Data="{ContextCommands}" + Orientation="Vertical" + IsOpened ="true" IsVisible="{/IsOpened}" + ItemTemplate="#Crow.MenuItem.itmp"> + <Template> + <GenericStack Orientation="{./Orientation}" Name="ItemsContainer" Margin="0" Background="${MenuBackground}"/> </Template> - <ItemTemplate> - <MenuItem Command="{}" Width="150" PopWidth="120" IsEnabled="{CanExecute}"> - <Template> - <Popper Font="{./Font}" Caption="{./Caption}" Background="{./Background}" PopDirection="{./PopDirection}" - Foreground = "{./Foreground}" CanPop="{./HasChildren}" MouseDown="./onMI_Click" - IsPopped="{²./IsOpened}" PopWidth="{./PopWidth}" PopHeight="{./PopHeight}"> - <Template> - <Border Name="border1" - CornerRadius="0" - MouseEnter="{Foreground=vgradient|0:White|0.2:Grey|0.9:Grey|1:Black}" - MouseLeave="{Foreground=Transparent}" - MouseDown="{Foreground=vgradient|0:Black|0.05:Grey|0.85:Grey|1:White}" - MouseUp="{Foreground=vgradient|0:White|0.2:Grey|0.9:Grey|1:Black}" - MinimumSize = "60,0" - Foreground="Transparent" - Background="{./Background}"> - <Label Text="{./Caption}" - Foreground="{./Foreground}" - Margin="1" HorizontalAlignment="Left" - Font="{./Font}" /> - </Border> - </Template> - <Border Foreground="DimGrey" Width="{../PopWidth}" Height="{../PopHeight}" Background="DimGrey"> - <VerticalStack Name="ItemsContainer"/> - </Border> - </Popper> - </Template> - </MenuItem> - </ItemTemplate> </MenuItem> diff --git a/Crow/Templates/DirectoryView.template b/Crow/Templates/DirectoryView.template index 009f46d0..98094c90 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"> + <Expandable Name="exp" Caption="{Name}" MouseDoubleClick="/onClickForExpand" BubbleMouseEvent="true"> <Template> <VerticalStack> <Border CornerRadius="2" Margin="0" Height="Fit" MouseDoubleClick="./onClickForExpand" diff --git a/Crow/Templates/FileDialog.template b/Crow/Templates/FileDialog.template index 2c49e470..a349905a 100644 --- a/Crow/Templates/FileDialog.template +++ b/Crow/Templates/FileDialog.template @@ -34,7 +34,7 @@ </Scroller> <ScrollBar Name="scrollbar1" Orientation="Vertical" Value="{²../scroller1.ScrollY}" Maximum="{../scroller1.MaxScrollY}" - CursorSize="{../scroller1.ChildHeightRatio}" + CursorRatio="{../scroller1.ChildHeightRatio}" LargeIncrement="{../scroller1.PageHeight}" SmallIncrement="30" Width="14" /> </HorizontalStack> diff --git a/Crow/Templates/GroupBox.template b/Crow/Templates/GroupBox.template index 1cc48774..4931b87c 100644 --- a/Crow/Templates/GroupBox.template +++ b/Crow/Templates/GroupBox.template @@ -3,10 +3,11 @@ <Group CacheEnabled="true"> <VerticalStack Spacing="0"> <Widget Height="6"/> - <Border CornerRadius="{./CornerRadius}" BorderWidth="1" Margin="10" Foreground="{./Foreground}"> + <Border Style="ControlBorder" CornerRadius="{./CornerRadius}" Margin="10" > <Container Name="Content" Margin="0" MinimumSize="70,10"/> </Border> </VerticalStack> - <Label Text="{./Caption}" VerticalAlignment="Top" Left="8" Background="Clear" Margin="1" CacheEnabled="true"/> + <Label Text="{./Caption}" VerticalAlignment="Top" Left="8" Background="Clear" Margin="1" CacheEnabled="true" + Foreground="{./Foreground}"/> </Group> </Container>
\ No newline at end of file diff --git a/Crow/Templates/ListBox.template b/Crow/Templates/ListBox.template index eb162ba7..9112a979 100644 --- a/Crow/Templates/ListBox.template +++ b/Crow/Templates/ListBox.template @@ -1,7 +1,6 @@ <?xml version="1.0"?> -<Border BorderWidth="1" Margin="1" MinimumSize="10,10" Background="{./Background}"> - <Scroller Name="scroller1" Margin="1" > - <VerticalStack - Height="Fit" Name="ItemsContainer" Margin="0" VerticalAlignment="Top"/> +<Border Style="ControlBorder" MinimumSize="10,10" Background="{./Background}" CornerRadius="{./CornerRadius}"> + <Scroller Name="scroller1" > + <VerticalStack Height="Fit" Name="ItemsContainer" VerticalAlignment="Top"/> </Scroller> </Border> diff --git a/Crow/Templates/MenuButton.template b/Crow/Templates/MenuButton.template new file mode 100644 index 00000000..abc3ff2c --- /dev/null +++ b/Crow/Templates/MenuButton.template @@ -0,0 +1,8 @@ +<?xml version="1.0"?> +<Button Command="{}" Width="Stretched"> + <Template> + <Label Text="{./Caption}" Width="Stretched" Height="Stretched" Margin="3" + MouseEnter="{Background=${ControlHighlight}}" + MouseLeave="{Background=Transparent}"/> + </Template> +</Button> diff --git a/Crow/Templates/MenuItem.itmp b/Crow/Templates/MenuItem.itmp new file mode 100644 index 00000000..7bbf2765 --- /dev/null +++ b/Crow/Templates/MenuItem.itmp @@ -0,0 +1,15 @@ +<?xml version="1.0"?> +<ItemTemplate DataType="Crow.Command" Path="#Crow.MenuButton.template"/> +<ItemTemplate DataType="Crow.CommandGroup" Data="Commands"> + <Popper PopDirection="Right" Caption="{Caption}" IsEnabled="{CanExecute}" Width="Stretched" + MouseEnter="{Background=${ControlHighlight}}" + MouseLeave="{Background=Transparent}"> + <Template> + <HorizontalStack Background="{./Background}" Width="Stretched" Height="Stretched" Margin="3"> + <Label Text="{./Caption}" Width="Fit" Height="Stretched"/> + <Label Text="..."/> + </HorizontalStack> + </Template> + <VerticalStack Margin="0" Name="ItemsContainer" Fit="true" Background="${MenuBackground}"/> + </Popper> +</ItemTemplate> diff --git a/Crow/Templates/MenuItem.template b/Crow/Templates/MenuItem.template index 96adbd1e..d712d3fb 100644 --- a/Crow/Templates/MenuItem.template +++ b/Crow/Templates/MenuItem.template @@ -1,11 +1,10 @@ <?xml version="1.0"?> <ListItem> <Popper Font="{./Font}" Caption="{./Caption}" Background="{./Background}" PopDirection="{./PopDirection}" - Foreground = "{./Foreground}" + Foreground = "{./Foreground}" BubbleMouseEvent="true" IsPopped="{²./IsOpened}" PopWidth="{./PopWidth}" PopHeight="{./PopHeight}"> <Template> - <CheckBox IsChecked="{²./IsPopped}" Caption="{./Caption}" Background="{./Background}" Foreground="{./Foreground}"> - <Template> + <Border Name="border1" MinimumSize = "60,0" Foreground="Transparent" @@ -15,8 +14,7 @@ Margin="2" HorizontalAlignment="Left" Font="{./Font}" /> </Border> - </Template> - </CheckBox> + </Template> <Border Foreground="DimGrey" Width="{../PopWidth}" Height="{../PopHeight}" Background="${MenuBackground}"> <VerticalStack Name="ItemsContainer" Width="Stretched" /> diff --git a/Crow/Templates/ScrollingListBox.template b/Crow/Templates/ScrollingListBox.template index a5a9b629..a9d3863f 100644 --- a/Crow/Templates/ScrollingListBox.template +++ b/Crow/Templates/ScrollingListBox.template @@ -1,13 +1,12 @@ <?xml version="1.0"?> <Border BorderWidth="1" Background="{./Background}"> <HorizontalStack Margin="1"> - <Scroller Name="ItemsScroller" - Margin="2"> + <Scroller Name="ItemsScroller" Margin="2"> <VerticalStack Height="Fit" MinimumSize="10,10" Name="ItemsContainer" Margin="0" VerticalAlignment="Top"/> </Scroller> <ScrollBar Name="scrollbar1" Value="{²../ItemsScroller.ScrollY}" - LargeIncrement="{../ItemsScroller.PageHeight}" SmallIncrement="30" CursorSize="{../ItemsScroller.ChildHeightRatio}" + LargeIncrement="{../ItemsScroller.PageHeight}" SmallIncrement="30" CursorRatio="{../ItemsScroller.ChildHeightRatio}" Maximum="{../ItemsScroller.MaxScrollY}" Orientation="Vertical" Width="12" /> </HorizontalStack> diff --git a/Crow/Templates/TreeView.template b/Crow/Templates/TreeView.template index 54910de5..f9704ab5 100644 --- a/Crow/Templates/TreeView.template +++ b/Crow/Templates/TreeView.template @@ -9,7 +9,7 @@ <ScrollBar Name="scrollbar1" LargeIncrement="{../scroller1.PageHeight}" SmallIncrement="30" - CursorSize="{../scroller1.ChildHeightRatio}" + CursorRatio="{../scroller1.ChildHeightRatio}" Value="{²../scroller1.ScrollY}" Maximum="{../scroller1.MaxScrollY}" /> </HorizontalStack> diff --git a/Crow/src/Command/CommandBase.cs b/Crow/src/Command/CommandBase.cs index 41aef606..ed360333 100644 --- a/Crow/src/Command/CommandBase.cs +++ b/Crow/src/Command/CommandBase.cs @@ -9,7 +9,8 @@ namespace Crow { /// <summary> /// Base class for Command and CommandGroup. /// </summary> - public abstract class CommandBase : IValueChange { + public abstract class CommandBase : IValueChange + { #region IValueChange implementation public event EventHandler<ValueChangeEventArgs> ValueChanged; public virtual void NotifyValueChanged(string MemberName, object _value) diff --git a/Crow/src/Command/CommandGroup.cs b/Crow/src/Command/CommandGroup.cs index ef4b0eff..039f1a49 100644 --- a/Crow/src/Command/CommandGroup.cs +++ b/Crow/src/Command/CommandGroup.cs @@ -8,19 +8,21 @@ using System.Collections.Generic; namespace Crow { public class CommandGroup : CommandBase, IEnumerable, IList<CommandBase> { - public List<CommandBase> Commands = new List<CommandBase>(); + public IList<CommandBase> Commands; - public CommandGroup () { } + public CommandGroup () { + Commands = new ObservableList<CommandBase>(); + } public CommandGroup (string caption, string icon, params CommandBase[] commands) : base (caption, icon) { - Commands.AddRange (commands); + Commands = new ObservableList<CommandBase>(commands); } public CommandGroup (string caption, params CommandBase[] commands) : base (caption) { - Commands.AddRange (commands); + Commands = new ObservableList<CommandBase>(commands); } public CommandGroup (params CommandBase[] commands) { - Commands.AddRange (commands); + Commands = new ObservableList<CommandBase>(commands); } @@ -46,10 +48,7 @@ namespace Crow { public void CopyTo(CommandBase[] array, int arrayIndex) => Commands.CopyTo (array, arrayIndex); - public bool Remove(CommandBase item) { - Commands.Remove (item); - return true; - } + public bool Remove(CommandBase item) => Commands.Remove (item); IEnumerator<CommandBase> IEnumerable<CommandBase>.GetEnumerator() => Commands.GetEnumerator(); diff --git a/Crow/src/Configuration.cs b/Crow/src/Configuration.cs index f6f4cee9..a04a80e4 100644 --- a/Crow/src/Configuration.cs +++ b/Crow/src/Configuration.cs @@ -92,8 +92,6 @@ namespace Crow Path.Combine (Environment.GetFolderPath (Environment.SpecialFolder.UserProfile), ".config"); Assembly a = Assembly.GetEntryAssembly (); - if (a == null) - a = AppDomain.CurrentDomain.GetAssemblies ()[1]; string appName = a.GetName().Name; string globalConfigPath = Path.Combine (configRoot, appName); @@ -105,8 +103,8 @@ namespace Crow string defaultConfigResID = appName + ".default.config"; foreach (string resIds in a.GetManifestResourceNames()) { if (string.Equals (defaultConfigResID, resIds, StringComparison.OrdinalIgnoreCase)) { - using (Stream s = a.GetManifestResourceStream (defaultConfigResID)) - globalConfig = new Configuration (globalConfigPath, s); + using (Stream s = a.GetManifestResourceStream (defaultConfigResID)) + globalConfig = new Configuration (globalConfigPath, s); return; } } @@ -131,6 +129,14 @@ namespace Crow Thread.Sleep (100); } } + public bool TryGet<T> (string key, out T result) { + if (items.ContainsKey (key)){ + result = items [key].GetValue<T> (); + return true; + } + result = default(T); + return false; + } /// <summary> /// retrive the value of the configuration key given in parameter /// </summary> diff --git a/Crow/src/ExtensionsMethods.cs b/Crow/src/ExtensionsMethods.cs index f8aefaf1..45610be2 100644 --- a/Crow/src/ExtensionsMethods.cs +++ b/Crow/src/ExtensionsMethods.cs @@ -7,6 +7,7 @@ using System; using System.IO; using System.Linq; using System.Linq.Expressions; +using System.Reflection; namespace Crow { @@ -197,6 +198,14 @@ namespace Crow internal static bool IsAnyLineBreakCharacter (this char c) => c == '\n' || c == '\r' || c == '\u0085' || c == '\u2028' || c == '\u2029'; + + public static bool TryGetResource (this Assembly a, string resId, out Stream stream) { + stream = null; + if (a == null) + return false; + stream = a.GetManifestResourceStream (resId); + return stream != null; + } } } diff --git a/Crow/src/IML/CompilerServices.cs b/Crow/src/IML/CompilerServices.cs index 8d63bb8d..32bb258f 100644 --- a/Crow/src/IML/CompilerServices.cs +++ b/Crow/src/IML/CompilerServices.cs @@ -70,7 +70,7 @@ namespace Crow.IML internal static FieldInfo miSetCurIface = typeof(Widget).GetField ("IFace", BindingFlags.Public | BindingFlags.Instance); internal static MethodInfo miFindByName = typeof (Widget).GetMethod ("FindByName"); internal static MethodInfo miFindByNameInTemplate = typeof (TemplatedControl).GetMethod ("FindByNameInTemplate"); - internal static MethodInfo miGetGObjItem = typeof(List<Widget>).GetMethod("get_Item", new Type[] { typeof(Int32) }); + internal static MethodInfo miGetGObjItem = typeof(IList<Widget>).GetMethod("get_Item", new Type[] { typeof(Int32) }); internal static MethodInfo miLoadDefaultVals = typeof (Widget).GetMethod ("loadDefaultValues"); internal static PropertyInfo piStyle = typeof (Widget).GetProperty ("Style"); internal static MethodInfo miGetLogicalParent = typeof(Widget).GetProperty("LogicalParent").GetGetMethod(); @@ -289,7 +289,9 @@ namespace Crow.IML #if DEBUG_BINDING_FUNC_CALLS Console.WriteLine ($"getMethodInfoWithReflexion ({instance},{method}); type:{instance.GetType ()}"); #endif - return instance.GetType ().GetMethod (method, BindingFlags.Instance | BindingFlags.NonPublic | BindingFlags.Public); + Type t = instance.GetType(); + MethodInfo mi = t.GetMethod (method, BindingFlags.Instance | BindingFlags.NonPublic | BindingFlags.Public); + return mi ?? CompilerServices.SearchExtMethod (t, method); } /// <summary> /// set value, convert if required @@ -417,7 +419,7 @@ namespace Crow.IML 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 == 1)) { + m.GetParameters ().Length > 0)) { Type curType = extendedType; while (curType != null) { if (mi.GetParameters () [0].ParameterType == curType) { @@ -831,7 +833,7 @@ namespace Crow.IML /// <summary> /// Splits expression on semicolon but ignore those between accolades /// </summary> - internal static string[] splitOnSemiColumnOutsideAccolades (string expression){ + /*internal static string[] splitOnSemiColumnOutsideAccolades (string expression){ List<String> exps = new List<string>(); int accCount = 0; int expPtr = 0; @@ -846,7 +848,7 @@ namespace Crow.IML case ';': if (accCount > 0) break; - exps.Add(expression.Substring(expPtr, c - expPtr - 1)); + exps.Add(expression.Substring(expPtr, c - expPtr)); expPtr = c + 1; break; } @@ -854,7 +856,7 @@ namespace Crow.IML if (exps.Count == 0) exps.Add(expression); return exps.ToArray (); - } + }*/ /// <summary> /// Try to get the type named strDataType, search first in crow assembly then in /// entry assembly. diff --git a/Crow/src/IML/Instantiator.cs b/Crow/src/IML/Instantiator.cs index ee1b615f..855e8669 100644 --- a/Crow/src/IML/Instantiator.cs +++ b/Crow/src/IML/Instantiator.cs @@ -490,6 +490,7 @@ namespace Crow.IML { if (mi.MemberType == MemberTypes.Event) { foreach (string exp in imlValue.ToString().Split (';')) { + //foreach (string exp in CompilerServices.splitOnSemiColumnOutsideAccolades (imlValue.ToString())) { string trimed = exp.Trim(); if (trimed.StartsWith ("{", StringComparison.Ordinal)) @@ -826,9 +827,10 @@ namespace Crow.IML { System.Reflection.Emit.Label finish = il.DefineLabel (); il.Emit (OpCodes.Br, finish); il.MarkLabel (cancel); - #if DEBUG_BINDING + //#if DEBUG_BINDING + //TODO: try to print datasource type in the error message il.EmitWriteLine (string.Format ("Handler method '{0}' for '{1}' NOT FOUND in new dataSource", bindingDef.TargetMember, sourceEvent.Name)); - #endif + //#endif il.MarkLabel (finish); #if DEBUG_BINDING il.EmitWriteLine (string.Format ("Handler method '{0}' for '{1}' FOUND in new dataSource", bindingDef.TargetMember, sourceEvent.Name)); diff --git a/Crow/src/IValueChange.cs b/Crow/src/IValueChange.cs index 011f7e80..b79c7fae 100644 --- a/Crow/src/IValueChange.cs +++ b/Crow/src/IValueChange.cs @@ -1,4 +1,4 @@ -// Copyright (c) 20132020 Jean-Philippe Bruyère <jp_bruyere@hotmail.com> +// Copyright (c) 2013-2021 Jean-Philippe Bruyère <jp_bruyere@hotmail.com> // // This code is licensed under the MIT license (MIT) (http://opensource.org/licenses/MIT) diff --git a/Crow/src/Interface.cs b/Crow/src/Interface.cs index 8755d817..a32577ce 100644 --- a/Crow/src/Interface.cs +++ b/Crow/src/Interface.cs @@ -78,23 +78,40 @@ namespace Crow FontRenderingOptions.HintStyle = HintStyle.Full; FontRenderingOptions.SubpixelOrder = SubpixelOrder.Default; - preloadCrowAssemblies (); + } - static void preloadCrowAssemblies () { + public static string [] CrowAssemblyNames { + set { + if (value == null) + return; + preloadCrowAssemblies (value); + } + } + static void preloadCrowAssemblies (string [] crowAssemblyNames) { //ensure all assemblies are loaded, because IML could contains classes not instanciated in source - Assembly ea = Assembly.GetEntryAssembly (); + /*Assembly ea = Assembly.GetEntryAssembly (); System.IO.FileStream[] files = ea.GetFiles (); foreach (AssemblyName an in ea.GetReferencedAssemblies()) { try { Assembly a = Assembly.ReflectionOnlyLoad (an.Name); if (a == Assembly.GetExecutingAssembly ()) - continue; + continue; if (a.GetCustomAttribute (typeof (CrowAttribute)) != null) - crowAssemblies.Add (a); + crowAssemblies.Add (a); } catch { } + }*/ + foreach (string assemblyName in crowAssemblyNames) { + try { + crowAssemblies.Add (Assembly.Load (assemblyName)); + } catch (Exception ex) { + Console.ForegroundColor = ConsoleColor.Red; + Console.WriteLine ($"Unable to preload CrowAssembly: {assemblyName}: {ex}"); + Console.ResetColor(); + } } + } public Interface (int width, int height, IntPtr glfwWindowHandle) : this (width, height, false, false) @@ -144,6 +161,7 @@ namespace Crow Glfw3.SetScrollCallback (hWin, HandleScrollDelegate); Glfw3.SetCharCallback (hWin, HandleCharDelegate); Glfw3.SetWindowSizeCallback (hWin, HandleWindowSizeDelegate); + Glfw3.SetWindowRefreshCallback (hWin, HandleWindowRefreshDelegate); } protected void initSurface () @@ -157,7 +175,7 @@ namespace Crow hWin = Glfw3.CreateWindow (clientRectangle.Width, clientRectangle.Height, "win name", MonitorHandle.Zero, IntPtr.Zero); if (hWin == IntPtr.Zero) throw new Exception ("[GLFW3] Unable to create vulkan Window"); - ownWindow = true; + ownWindow = true; registerGlfwCallbacks (); @@ -183,6 +201,41 @@ namespace Crow throw new PlatformNotSupportedException ("Unable to create cairo surface."); } } + + public void SetWindowIcon (string path) { + using (Stream stream = GetStreamFromPath (path)) { +#if STB_SHARP + StbImageSharp.ImageResult stbi = StbImageSharp.ImageResult.FromStream (stream, StbImageSharp.ColorComponents.RedGreenBlueAlpha); + byte[] image = new byte[stbi.Data.Length]; + //rgba to argb for cairo. + for (int i = 0; i < stbi.Data.Length; i += 4) { + image[i] = stbi.Data[i + 2]; + image[i + 1] = stbi.Data[i + 1]; + image[i + 2] = stbi.Data[i]; + image[i + 3] = stbi.Data[i + 3]; + } + Glfw.Image icon = new Glfw.Image ((uint)stbi.Width, (uint)stbi.Height, image); + Glfw3.SetWindowIcon (hWin, 1, ref icon); + icon.Dispose(); + +#else + using (StbImage stbi = new StbImage (stream)) { + byte[] image = new byte [stbi.Size]; + //rgba to argb for cairo. + for (int i = 0; i < stbi.Size; i+=4) { + image [i] = Marshal.ReadByte (stbi.Handle, i + 2); + image [i + 1] = Marshal.ReadByte (stbi.Handle, i + 1); + image [i + 2] = Marshal.ReadByte (stbi.Handle, i); + image [i + 3] = Marshal.ReadByte (stbi.Handle, i + 3); + } + Glfw.Image icon = new Glfw.Image (stbi.Width, stbi.Height, image); + Glfw3.setWindowIcon (hWin, 1, ref icon); + icon.Dispose(); + } +#endif + } + } + internal Dictionary<string, MethodInfo> knownExtMethods = new Dictionary<string, MethodInfo> (); internal MethodInfo SearchExtMethod (Type t, string methodName) { string key = t.Name + "." + methodName; @@ -235,6 +288,9 @@ namespace Crow static WindowSizeDelegate HandleWindowSizeDelegate = (IntPtr window, int Width, int Height) => { windows [window].ProcessResize (new Rectangle (0, 0, Width, Height)); }; + static WindowDelegate HandleWindowRefreshDelegate = (IntPtr window) => { + windows [window].registerRefreshClientRectangle (); + }; #endregion @@ -265,15 +321,23 @@ namespace Crow /// </summary> public void Init () { DbgLogger.StartEvent (DbgEvtType.IFaceInit); - initDictionaries (); - loadStyling (); - loadThemeFiles (); + init_internal (); initTooltip (); - initContextMenus (); OnInitialized (); DbgLogger.EndEvent (DbgEvtType.IFaceInit); } /// <summary> + /// Maybe called anytime to reset all Instantiators, Styles and Theme. Lock the UpdateMutex to + /// call it after the normal startup. + /// </summary> + protected void init_internal() { + disposeContextMenus (); + initDictionaries (); + loadStyling (); + loadThemeFiles (); + initContextMenus (); + } + /// <summary> /// call Init() then enter the running loop performing ProcessEvents until running==false. /// </summary> public virtual void Run () { @@ -283,7 +347,10 @@ namespace Crow Glfw3.PollEvents (); UpdateFrame (); } + + Terminate (); } + public virtual void Terminate () {} public virtual void UpdateFrame () { Thread.Sleep (1); } public virtual void Quit () => Glfw3.SetWindowShouldClose (hWin, 1); @@ -295,6 +362,22 @@ namespace Crow public bool Alt => Glfw3.GetKey (hWin, Key.LeftAlt) == InputAction.Press || Glfw3.GetKey (hWin, Key.RightAlt) == InputAction.Press; +#if DEBUG_STATS + public long TotalWidgetCreated => Widget.TotalWidgetCreated; + public long TotalWidgetDisposed => Widget.TotalWidgetDisposed; + public long TotalWidgetActive => Widget.TotalWidgetCreated - Widget.TotalWidgetDisposed; + public long TotalWidgetInGraphicTree { + get { + lock(UpdateMutex) { + long total = 0; + foreach (Widget w in GraphicTree) + total += 1 + w.ChildCount; + return total; + } + } + } +#endif + #region IDisposable Support private bool disposedValue = false; // To detect redundant calls @@ -307,7 +390,7 @@ namespace Crow // TODO: dispose managed state (managed objects). } - currentCursor?.Dispose (); + currentCursor?.Dispose (); disposeContextMenus (); if (ownWindow) { @@ -523,13 +606,14 @@ namespace Crow /// </remarks> public Dictionary<string, string> StylingConstants; /// <summary> parse all styling data's during application startup and build global Styling Dictionary </summary> + /// <remarks> + /// </remarks> protected virtual void loadStyling() { - loadStylingFromAssembly (Assembly.GetExecutingAssembly ()); - foreach (Assembly a in crowAssemblies) { - loadStylingFromAssembly (a); - } + loadThemeStyle (); loadStylingFromAssembly (Assembly.GetEntryAssembly ()); - loadThemeStyle (); + foreach (Assembly a in crowAssemblies) + loadStylingFromAssembly (a); + loadStylingFromAssembly (Assembly.GetExecutingAssembly ()); } /// <summary> Search for .style resources in assembly </summary> protected void loadStylingFromAssembly (Assembly assembly) { @@ -567,11 +651,7 @@ namespace Crow return; lock (UpdateMutex) { DbgLogger.StartEvent (DbgEvtType.IFaceReloadTheme); - disposeContextMenus (); - initDictionaries (); - loadStyling (); - loadThemeFiles (); - initContextMenus (); + init_internal (); DbgLogger.EndEvent (DbgEvtType.IFaceReloadTheme); } } @@ -691,8 +771,7 @@ namespace Crow if (tryGetResource (Assembly.GetEntryAssembly (), resId, out stream)) return stream; string[] assemblyNames = resId.Split ('.'); - if (tryGetResource (AppDomain.CurrentDomain.GetAssemblies () - .FirstOrDefault (aa => aa.GetName ().Name == assemblyNames[0]), resId, out stream)) + if (AppDomain.CurrentDomain.GetAssemblies ().FirstOrDefault (aa => aa.GetName ().Name == assemblyNames[0]).TryGetResource (resId, out stream)) return stream; if (assemblyNames.Length > 3) if (tryGetResource (AppDomain.CurrentDomain.GetAssemblies () @@ -994,6 +1073,17 @@ namespace Crow PerformanceMeasure.End (PerformanceMeasure.Kind.Clipping); DbgLogger.EndEvent (DbgEvtType.ClippingRegistration, true); } + void clear(Context ctx) { + for (int i = 0; i < clipping.NumRectangles; i++) + ctx.Rectangle (clipping.GetRectangle (i)); + + ctx.ClipPreserve (); + ctx.Operator = Operator.Clear; + ctx.Fill (); + ctx.Operator = Operator.Over; + } + public bool SolidBackground = true; + /// <summary>Clipping Rectangles drive the drawing process. For compositing, each object under a clip rectangle should be /// repainted. If it contains also clip rectangles, its cache will be update, or if not cached a full redraw will take place</summary> protected virtual void processDrawing(Context ctx){ @@ -1008,6 +1098,9 @@ namespace Crow ctx.PushGroup (); + if (SolidBackground) + clear (ctx); + for (int i = GraphicTree.Count -1; i >= 0 ; i--){ Widget p = GraphicTree[i]; if (!p.IsVisible) @@ -1015,9 +1108,9 @@ namespace Crow if (clipping.Contains (p.Slot) == RegionOverlap.Out) continue; - ctx.Save (); + //ctx.Save (); p.Paint (ctx); - ctx.Restore (); + //ctx.Restore (); } if (DragAndDropOperation != null) { @@ -1046,22 +1139,16 @@ namespace Crow #endif ctx.PopGroupToSource (); - - for (int i = 0; i < clipping.NumRectangles; i++) - ctx.Rectangle (clipping.GetRectangle (i)); - - ctx.ClipPreserve (); - ctx.Operator = Operator.Clear; - ctx.Fill (); - ctx.Operator = Operator.Over; + if (!SolidBackground) + clear (ctx); ctx.Paint (); - + surf.Flush (); - clipping.Dispose (); - clipping = new Region (); + + clipping.Reset (); PerformanceMeasure.End (PerformanceMeasure.Kind.Drawing); IsDirty = true; @@ -1273,10 +1360,12 @@ namespace Crow foreach (Widget g in GraphicTree) g.RegisterForLayouting (LayoutingType.All); - RegisterClip (clientRectangle); + registerRefreshClientRectangle (); } } + internal void registerRefreshClientRectangle () => RegisterClip (clientRectangle); + #region Mouse and Keyboard Handling MouseCursor cursor = MouseCursor.top_left_arrow; [Obsolete]void loadCursors () @@ -1403,6 +1492,9 @@ namespace Crow HoverWidget = value; } } + /// <summary> + /// Ask OS to force the mouse position to the actual coordinate of Interface.MousePosition + /// </summary> public virtual void ForceMousePosition () { Glfw3.SetCursorPosition (hWin, MousePosition.X, MousePosition.Y); } @@ -1414,124 +1506,122 @@ namespace Crow { DbgLogger.StartEvent (DbgEvtType.MouseMove); - int deltaX = x - MousePosition.X; - int deltaY = y - MousePosition.Y; + try { - if (!DragAndDropInProgress) { - if (stickedWidget != null && ActiveWidget == null) { - stickyMouseDelta.X += deltaX; - stickyMouseDelta.Y += deltaY; + int deltaX = x - MousePosition.X; + int deltaY = y - MousePosition.Y; - if (Math.Abs (stickyMouseDelta.X) > stickedWidget.StickyMouse || Math.Abs (stickyMouseDelta.Y) > stickedWidget.StickyMouse) { - stickedWidget = null; - stickyMouseDelta = default; - } else { - ForceMousePosition (); - DbgLogger.EndEvent (DbgEvtType.MouseMove); - return true; + if (!DragAndDropInProgress) { + if (stickedWidget != null && ActiveWidget == null) { + stickyMouseDelta.X += deltaX; + stickyMouseDelta.Y += deltaY; + + if (Math.Abs (stickyMouseDelta.X) > stickedWidget.StickyMouse || Math.Abs (stickyMouseDelta.Y) > stickedWidget.StickyMouse) { + stickedWidget = null; + stickyMouseDelta = default; + } else { + ForceMousePosition (); + return true; + } } } - } - MousePosition = new Point (x, y); - MouseMoveEventArgs e = new MouseMoveEventArgs (x, y, deltaX, deltaY); + MousePosition = new Point (x, y); + MouseMoveEventArgs e = new MouseMoveEventArgs (x, y, deltaX, deltaY); - if (!(DragAndDropInProgress || ActiveWidget == null)) { - //TODO, ensure object is still in the graphic tree - //send move evt even if mouse move outside bounds - ActiveWidget.onMouseMove (this, e); - DbgLogger.EndEvent (DbgEvtType.MouseMove); - return true; - } + if (!(DragAndDropInProgress || ActiveWidget == null)) { + //TODO, ensure object is still in the graphic tree + //send move evt even if mouse move outside bounds + ActiveWidget.onMouseMove (this, e); + return true; + } - if (HoverOrDropTarget != null) { - resetTooltip (); + if (HoverOrDropTarget != null) { + resetTooltip (); - //check topmost graphicobject first - Widget topContainer = HoverOrDropTarget; - while (topContainer.LogicalParent is Widget w) - topContainer = w; - - int indexOfTopContainer = GraphicTree.IndexOf (topContainer); - if (indexOfTopContainer != 0) { - for (int i = 0; i < indexOfTopContainer; i++) { - //if logical parent of top container is a Interface, that's not a popup. - if (GraphicTree [i].LogicalParent is Interface) { - if (GraphicTree [i].MouseIsIn (e.Position)) { - //mouse is in another top container than the actual one, - //so we must leave first the current top container starting from HoverWidget - if (DragAndDropInProgress) { - DragAndDropOperation.DropTarget?.onDragLeave (this, DragAndDropOperation); - GraphicTree[i].checkHoverWidget (e); - DragAndDropOperation.DragSource.onDrag (this, e); - } else { - while (HoverWidget != null) { - HoverWidget.onMouseLeave (this, e); - HoverWidget = HoverWidget.FocusParent; + //check topmost graphicobject first + Widget topContainer = HoverOrDropTarget; + while (topContainer.LogicalParent is Widget w) + topContainer = w; + + int indexOfTopContainer = GraphicTree.IndexOf (topContainer); + if (indexOfTopContainer != 0) { + for (int i = 0; i < indexOfTopContainer; i++) {//check all top containers that are at a higher level + //if logical parent of top container is the Interface, that's not a popup. + if (GraphicTree [i].LogicalParent is Interface) { + if (GraphicTree [i].MouseIsIn (e.Position)) { + //mouse is in another top container than the actual one, + //so we must leave first the current top container starting from HoverWidget + if (DragAndDropInProgress) { + DragAndDropOperation.DropTarget?.onDragLeave (this, DragAndDropOperation); + GraphicTree[i].checkHoverWidget (e); + DragAndDropOperation.DragSource.onDrag (this, e); + } else { + while (HoverWidget != null) { + HoverWidget.onMouseLeave (this, e); + HoverWidget = HoverWidget.FocusParent; + } + GraphicTree[i].checkHoverWidget (e); + HoverWidget.onMouseMove (this, e); } - GraphicTree[i].checkHoverWidget (e); - HoverWidget.onMouseMove (this, e); + return true; } - DbgLogger.EndEvent (DbgEvtType.MouseMove); - return true; } } } - } - if (HoverOrDropTarget.MouseIsIn (e.Position)) { - HoverOrDropTarget.checkHoverWidget (e); - if (DragAndDropInProgress) - DragAndDropOperation.DragSource.onDrag (this, e); - else - HoverWidget.onMouseMove (this, e); - DbgLogger.EndEvent (DbgEvtType.MouseMove); - return true; - } else { - if (DragAndDropInProgress && dragndropHover == DragAndDropOperation.DropTarget) - DragAndDropOperation.DropTarget.onDragLeave (this, DragAndDropOperation); - //seek upward from last focused graph obj's - while (HoverOrDropTarget.FocusParent != null) { - if (!DragAndDropInProgress) - HoverWidget.onMouseLeave (this, e); - HoverOrDropTarget = HoverOrDropTarget.FocusParent; - if (HoverOrDropTarget.MouseIsIn (e.Position)) { - HoverOrDropTarget.checkHoverWidget (e); - if (DragAndDropInProgress) - DragAndDropOperation.DragSource?.onDrag (this, e); - else - HoverWidget.onMouseMove (this, e); - DbgLogger.EndEvent (DbgEvtType.MouseMove); - return true; - } + if (HoverOrDropTarget.MouseIsIn (e.Position)) { + HoverOrDropTarget.checkHoverWidget (e); + if (DragAndDropInProgress) + DragAndDropOperation.DragSource.onDrag (this, e); + else + HoverWidget.onMouseMove (this, e); + return true; + } else { + if (DragAndDropInProgress && dragndropHover == DragAndDropOperation.DropTarget) + DragAndDropOperation.DropTarget.onDragLeave (this, DragAndDropOperation); + //seek upward from last focused graph obj's + while (HoverOrDropTarget.FocusParent != null) { + if (!DragAndDropInProgress) + HoverWidget.onMouseLeave (this, e); + HoverOrDropTarget = HoverOrDropTarget.FocusParent; + if (HoverOrDropTarget.MouseIsIn (e.Position)) { + HoverOrDropTarget.checkHoverWidget (e); + if (DragAndDropInProgress) + DragAndDropOperation.DragSource?.onDrag (this, e); + else + HoverWidget.onMouseMove (this, e); + return true; + } + } } } - } - //top level graphic obj's parsing - lock (GraphicTree) { - for (int i = 0; i < GraphicTree.Count; i++) { - Widget g = GraphicTree [i]; - if (DragAndDropInProgress && DragAndDropOperation.DragSource == g) - continue; - if (g.MouseIsIn (e.Position)) { - g.checkHoverWidget (e); - if (!DragAndDropInProgress) { - if (g is Window && FOCUS_ON_HOVER && g.Focusable) { - FocusedWidget = g; - if (RAISE_WIN_ON_FOCUS) - PutOnTop (g); + //top level graphic obj's parsing + lock (GraphicTree) { + for (int i = 0; i < GraphicTree.Count; i++) { + Widget g = GraphicTree [i]; + if (DragAndDropInProgress && DragAndDropOperation.DragSource == g) + continue; + if (g.MouseIsIn (e.Position)) { + g.checkHoverWidget (e); + if (!DragAndDropInProgress) { + if (g is Window && FOCUS_ON_HOVER && g.Focusable) { + FocusedWidget = g; + if (RAISE_WIN_ON_FOCUS) + PutOnTop (g); + } + HoverWidget.onMouseMove (this, e); } - HoverWidget.onMouseMove (this, e); + return true; } - DbgLogger.EndEvent (DbgEvtType.MouseMove); - return true; } } + HoverOrDropTarget = null; + return false; + } finally { + DbgLogger.EndEvent (DbgEvtType.MouseMove); } - HoverOrDropTarget = null; - DbgLogger.EndEvent (DbgEvtType.MouseMove); - return false; } /// <summary> /// Forward the mouse down event from the host to the hover widget in the crow interface @@ -1541,21 +1631,24 @@ namespace Crow public virtual bool OnMouseButtonDown (MouseButton button) { DbgLogger.StartEvent (DbgEvtType.MouseDown); - doubleClickTriggered = (lastMouseDown.ElapsedMilliseconds < DOUBLECLICK_TRESHOLD); - lastMouseDown.Restart (); - lastMouseDownEvent = new MouseButtonEventArgs (MousePosition.X, MousePosition.Y, button, InputAction.Press); + try { + doubleClickTriggered = (lastMouseDown.ElapsedMilliseconds < DOUBLECLICK_TRESHOLD); + lastMouseDown.Restart (); - if (HoverWidget == null) { - DbgLogger.EndEvent (DbgEvtType.MouseDown); - return false; - } + lastMouseDownEvent = new MouseButtonEventArgs (MousePosition.X, MousePosition.Y, button, InputAction.Press); - HoverWidget.onMouseDown (this, lastMouseDownEvent); + if (HoverWidget == null) + return false; - ActiveWidget = HoverWidget; - DbgLogger.EndEvent (DbgEvtType.MouseDown); - return true; + HoverWidget.onMouseDown (this, lastMouseDownEvent); + + ActiveWidget = HoverWidget; + return true; + + } finally { + DbgLogger.EndEvent (DbgEvtType.MouseDown); + } } /// <summary> /// Forward the mouse up event from the host to the crow interface @@ -1645,6 +1738,33 @@ namespace Crow } public virtual bool OnKeyDown (Key key) { +#if DEBUG_STATS + if (Shift && key == Key.F1) { + LoadIMLFragment (@" +<Window Caption='Debug Statistick' Width='50%' Height='50%' Background='DarkGrey'> + <VerticalStack> + <HorizontalStack Height='Fit'> + <Label Text='TotalWidgetCreated:' Width='50%'/> + <Label Text='{TotalWidgetCreated}' TextAlignment='Right'/> + </HorizontalStack> + <HorizontalStack Height='Fit'> + <Label Text='TotalWidgetDisposed:' Width='50%'/> + <Label Text='{TotalWidgetDisposed}' TextAlignment='Right'/> + </HorizontalStack> + <HorizontalStack Height='Fit'> + <Label Text='TotalWidgetActive:' Width='50%'/> + <Label Text='{TotalWidgetActive}' TextAlignment='Right'/> + </HorizontalStack> + <HorizontalStack Height='Fit'> + <Label Text='TotalWidgetInGraphicTree:' Width='50%'/> + <Label Text='{TotalWidgetInGraphicTree}' TextAlignment='Right'/> + </HorizontalStack> + </VerticalStack> +</Window> + ").DataSource = this; + } +#endif + //Keyboard.SetKeyState((Crow.Key)Key,true); lastKeyDownEvt = new KeyEventArgs (key, true); @@ -1665,6 +1785,7 @@ namespace Crow Stopwatch tooltipTimer = new Stopwatch (); Widget ToolTipContainer; volatile bool tooltipVisible; + object tooltipMutex = new object (); protected void initTooltip () { @@ -1674,26 +1795,28 @@ namespace Crow } void toolTipThreadFunc () { - while (true) { - if (tooltipTimer.ElapsedMilliseconds > TOOLTIP_DELAY) { - if (!tooltipVisible) { - Widget g = _hoverWidget; - while (g != null) { - if (!string.IsNullOrEmpty (g.Tooltip)) { - if (g.Tooltip.StartsWith("#", StringComparison.Ordinal)) { - //custom tooltip container - ToolTipContainer = CreateInstance (g.Tooltip); - } else - ToolTipContainer = CreateInstance ("#Crow.Tooltip.template"); - ToolTipContainer.LayoutChanged += ToolTipContainer_LayoutChanged; - AddWidget (ToolTipContainer); - ToolTipContainer.DataSource = g; - ToolTipContainer.Top = MousePosition.Y + 10; - ToolTipContainer.Left = MousePosition.X + 10; - tooltipVisible = true; - break; + while (true) { + lock (tooltipMutex) { + if (tooltipTimer.ElapsedMilliseconds > TOOLTIP_DELAY) { + if (!tooltipVisible) { + Widget g = _hoverWidget; + while (g != null) { + if (!string.IsNullOrEmpty (g.Tooltip)) { + if (g.Tooltip.StartsWith("#", StringComparison.Ordinal)) { + //custom tooltip container + ToolTipContainer = CreateInstance (g.Tooltip); + } else + ToolTipContainer = CreateInstance ("#Crow.Tooltip.template"); + ToolTipContainer.LayoutChanged += ToolTipContainer_LayoutChanged; + AddWidget (ToolTipContainer); + ToolTipContainer.DataSource = g; + ToolTipContainer.Top = MousePosition.Y + 10; + ToolTipContainer.Left = MousePosition.X + 10; + tooltipVisible = true; + break; + } + g = g.LogicalParent as Widget; } - g = g.LogicalParent as Widget; } } } @@ -1703,13 +1826,15 @@ namespace Crow } void resetTooltip () { - if (tooltipVisible) { - ToolTipContainer.LayoutChanged -= ToolTipContainer_LayoutChanged; - ToolTipContainer.DataSource = null; - RemoveWidget (ToolTipContainer); - tooltipVisible = false; - ToolTipContainer.Dispose (); - ToolTipContainer = null; + lock (tooltipMutex) { + if (tooltipVisible) { + ToolTipContainer.LayoutChanged -= ToolTipContainer_LayoutChanged; + ToolTipContainer.DataSource = null; + RemoveWidget (ToolTipContainer); + tooltipVisible = false; + ToolTipContainer.Dispose (); + ToolTipContainer = null; + } } tooltipTimer.Restart (); } @@ -1718,7 +1843,7 @@ namespace Crow Widget ttc = sender as Widget; //tooltip container datasource is the widget triggering the tooltip - Rectangle r = ScreenCoordinates ((ttc.DataSource as Widget).Slot); + Rectangle r = ttc?.DataSource is Widget w ? ScreenCoordinates (w.Slot) : ClientRectangle; if (e.LayoutType == LayoutingType.X) { if (ttc.Slot.Right > clientRectangle.Right) diff --git a/Crow/src/ItemTemplate.cs b/Crow/src/ItemTemplate.cs index 7e2f7194..9a5700a6 100644 --- a/Crow/src/ItemTemplate.cs +++ b/Crow/src/ItemTemplate.cs @@ -277,7 +277,7 @@ namespace Crow public static string GetIcon (this Widget go) { return "#Icons." + go.GetType ().FullName + ".svg"; } - public static List<Widget> GetChildren (this Widget go) { + public static IList<Widget> GetChildren (this Widget go) { Type goType = go.GetType (); if (typeof (GroupBase).IsAssignableFrom (goType)) return (go as GroupBase).Children; diff --git a/Crow/src/Mono.Cairo/Context.cs b/Crow/src/Mono.Cairo/Context.cs index 5cd60dc1..eb855157 100644 --- a/Crow/src/Mono.Cairo/Context.cs +++ b/Crow/src/Mono.Cairo/Context.cs @@ -438,6 +438,10 @@ namespace Crow.Cairo { { NativeMethods.cairo_arc_negative (handle, xc, yc, radius, angle1, angle2); } + public void ArcNegative (PointD center, double radius, double angle1, double angle2) + { + NativeMethods.cairo_arc_negative (handle, center.X, center.Y, radius, angle1, angle2); + } public void Rectangle (Crow.Rectangle rectangle) { diff --git a/Crow/src/ObservableList.cs b/Crow/src/ObservableList.cs index b67e27b6..dc211f0a 100644 --- a/Crow/src/ObservableList.cs +++ b/Crow/src/ObservableList.cs @@ -6,10 +6,11 @@ using System; using System.Collections.Generic; using System.Linq; +using System.Collections; namespace Crow { - public class ObservableList<T> : List<T>, IObservableList, IValueChange { + public class ObservableList<T> : IList<T>, IObservableList, IValueChange { #region IValueChange implementation public event EventHandler<ValueChangeEventArgs> ValueChanged; public virtual void NotifyValueChanged (string MemberName, object _value) @@ -25,8 +26,13 @@ namespace Crow public event EventHandler<ListClearEventArg> ListClear; #endregion - public ObservableList() : base () {} - public ObservableList (IEnumerable<T> collection) : base (collection) { } + List<T> items; + public ObservableList() { + items = new List<T>(); + } + public ObservableList (IEnumerable<T> collection) { + items = new List<T> (collection); + } int selectedIndex = -1; @@ -51,28 +57,47 @@ namespace Crow this [selectedIndex] = value; } } - public new void Add (T elem) { - base.Add (elem); + + public int Count => items.Count; + + public bool IsReadOnly => false; + + public T this[int index] { + get => items[index]; + set { + + if (items[index] == null) { + if (value == null) + return; + }else if (items[index].Equals (value)) + return; + Replace (items[index], value); + } + } + + public void Add (T elem) { + items.Add (elem); ListAdd.Raise (this, new ListChangedEventArg (this.Count - 1, elem)); SelectedIndex = this.Count - 1; } - public new void Insert (int index, T elem) { - base.Insert (index, elem); + public void Insert (int index, T elem) { + items.Insert (index, elem); ListAdd.Raise (this, new ListChangedEventArg (index, elem)); SelectedIndex = index; } - public new void Remove (T elem) { + public bool Remove (T elem) { int idx = IndexOf (elem); if (idx < 0) - Console.WriteLine ($"ObsList.Remove idx < 0: {new System.Diagnostics.StackTrace()}"); + return false; else - base.RemoveAt (idx); + items.RemoveAt (idx); ListRemove.Raise (this, new ListChangedEventArg (idx, elem)); + return true; } - public new void Clear () + public void Clear () { ListClearEventArg eventArg = new ListClearEventArg (this.Cast<object>()); - base.Clear (); + items.Clear (); ListClear.Raise (this, eventArg); } public void Remove () { @@ -83,13 +108,13 @@ namespace Crow } public void Insert () { - base.Insert (selectedIndex+1, default(T)); + items.Insert (selectedIndex+1, default(T)); SelectedIndex++; ListAdd.Raise (this, new ListChangedEventArg (selectedIndex, SelectedItem)); } public void Replace (T oldValue, T newValue) { int idx = IndexOf (oldValue); - base[idx] = newValue; + items[idx] = newValue; ListEdit.Raise (this, new ListChangedEventArg (idx, newValue)); } public void RaiseEdit () { @@ -98,9 +123,9 @@ namespace Crow ListEdit.Raise (this, new ListChangedEventArg (selectedIndex, SelectedItem)); } - public new void RemoveAt (int index) + public void RemoveAt (int index) { - base.RemoveAt (index); + items.RemoveAt (index); ListRemove.Raise (this, new ListChangedEventArg (index, null)); } public void RaiseEditAt (int index) { @@ -121,6 +146,17 @@ namespace Crow } return tmp; } + + public int IndexOf(T item) => items.IndexOf (item); + + public bool Contains(T item) => items.Contains (item); + + public void CopyTo(T[] array, int arrayIndex) => items.CopyTo (array, arrayIndex); + + + public IEnumerator<T> GetEnumerator() => items.GetEnumerator (); + + IEnumerator IEnumerable.GetEnumerator() => items.GetEnumerator (); } } diff --git a/Crow/src/Text/TextSpan.cs b/Crow/src/Text/TextSpan.cs index ca1f3474..ddc21c47 100644 --- a/Crow/src/Text/TextSpan.cs +++ b/Crow/src/Text/TextSpan.cs @@ -15,7 +15,7 @@ namespace Crow.Text Start = start; End = end; } - + public static TextSpan FromStartAndLength (int start, int length = 0) => new TextSpan (start, start + length); public bool IsEmpty => Start == End; public int Length => End - Start; diff --git a/Crow/src/Widgets/CircleMeter.cs b/Crow/src/Widgets/CircleMeter.cs new file mode 100644 index 00000000..6e3e67c6 --- /dev/null +++ b/Crow/src/Widgets/CircleMeter.cs @@ -0,0 +1,125 @@ +// Copyright (c) 2013-2021 Jean-Philippe Bruyère <jp_bruyere@hotmail.com> +// +// This code is licensed under the MIT license (MIT) (http://opensource.org/licenses/MIT) + +using System; +using System.ComponentModel; +using Crow.Cairo; + +namespace Crow { + +public class CircleMeter : Gauge { + #region CTOR + protected CircleMeter () {} + public CircleMeter (Interface iface, string style = null) : base (iface, style) { } + #endregion + + double startAngle, endAngle; + int lineWidth, backgroundLineWidth; + /// <summary> + /// Starting andle in degree corresponding to the minimum value + /// </summary> + [DefaultValue (0.0)] + public double StartAngle { + get => startAngle; + set { + if (startAngle == value) + return; + startAngle = value; + NotifyValueChangedAuto (startAngle); + RegisterForRedraw (); + } + } + /// <summary> + /// Ending angle in degree corresponding to the maximum value + /// </summary> + [DefaultValue (360.0)] + public double EndAngle { + get => endAngle; + set { + if (endAngle == value) + return; + endAngle = value; + NotifyValueChangedAuto (endAngle); + RegisterForRedraw (); + } + } + /// <summary> + /// Line width used to draw the value. + /// </summary> + /// <value></value> + [DefaultValue (10)] + public int LineWidth { + get => lineWidth; + set { + if (lineWidth == value) + return; + lineWidth = value; + NotifyValueChangedAuto (lineWidth); + RegisterForRedraw (); + } + } + /// <summary> + /// Line width used to draw the background arc from start to end angle + /// </summary> + [DefaultValue (10)] + public int BackgroundLineWidth { + get => backgroundLineWidth; + set { + if (backgroundLineWidth == value) + return; + backgroundLineWidth = value; + NotifyValueChangedAuto (backgroundLineWidth); + RegisterForRedraw (); + } + } + const double rad = Math.PI * 2.0 / 360.0; + protected override void onDraw (Context gr) { + DbgLogger.StartEvent (DbgEvtType.GODraw, this); + + /*Rectangle r = new Rectangle (Slot.Size); + + Background.SetAsSource (IFace, gr, r); + CairoHelpers.CairoRectangle (gr, r, CornerRadius); + gr.Fill ();*/ + + Rectangle r = ClientRectangle; + + double radius = 0.5 * (Math.Min (r.Width, r.Height) - Math.Max (backgroundLineWidth, lineWidth)); + + + double valueTot = Maximum - Minimum; + double absValue = Value - Minimum; + double valRatio = absValue / valueTot; + + double sArad = rad * (startAngle - 90); + double sErad = rad * (endAngle - 90); + + + gr.NewPath (); + + bool clockwise = startAngle < endAngle; + double valAngle = (sErad - sArad) * valRatio; + Background?.SetAsSource (IFace, gr); + gr.LineWidth = backgroundLineWidth; + if (clockwise) + gr.Arc (r.CenterD, radius, sArad, sErad); + else + gr.ArcNegative (r.CenterD, radius, sArad, sErad); + gr.Stroke (); + gr.LineWidth = lineWidth; + Foreground?.SetAsSource (IFace, gr); + if (clockwise) + gr.Arc (r.CenterD, radius, sArad, sArad + valAngle); + else + gr.ArcNegative (r.CenterD, radius, sArad, sArad + valAngle); + gr.Stroke (); + /*} else { + double valAngle = (sArad - sErad) * valRatio; + }*/ + + DbgLogger.EndEvent (DbgEvtType.GODraw); + } + + } +}
\ No newline at end of file diff --git a/Crow/src/Widgets/Gauge.cs b/Crow/src/Widgets/Gauge.cs index 5964da02..7384453e 100644 --- a/Crow/src/Widgets/Gauge.cs +++ b/Crow/src/Widgets/Gauge.cs @@ -1,8 +1,7 @@ -// Copyright (c) 2013-2020 Jean-Philippe Bruyère <jp_bruyere@hotmail.com> +// Copyright (c) 2013-2021 Jean-Philippe Bruyère <jp_bruyere@hotmail.com> // // This code is licensed under the MIT license (MIT) (http://opensource.org/licenses/MIT) - using System; using System.ComponentModel; using Crow.Cairo; @@ -18,6 +17,7 @@ namespace Crow { #region protected fields protected double actualValue, minValue, maxValue; Orientation orientation; + bool inverted; #endregion #region public properties @@ -77,6 +77,19 @@ namespace Crow { RegisterForLayouting (LayoutingType.Sizing | LayoutingType.ArrangeChildren); } } + /// <summary> + /// if true, horizontal gauge will align drawing right, and vertical on bottom. + /// </summary> + public bool Inverted { + get => inverted; + set { + if (inverted == value) + return; + inverted = value; + NotifyValueChangedAuto (inverted); + RegisterForRedraw (); + } + } #endregion protected override void onDraw (Context gr) { @@ -85,15 +98,20 @@ namespace Crow { base.onDraw (gr); Rectangle cb = ClientRectangle; + Rectangle r = cb; - if (orientation == Orientation.Horizontal) - cb.Width = (int)(cb.Width / Maximum * Value); - else - cb.Height = (int)(cb.Height / Maximum * Value); - + if (orientation == Orientation.Horizontal) { + r.Width = (int)(cb.Width / Maximum * Value); + if (inverted) + r.Left = cb.Right - r.Width; + } else { + r.Height = (int)(cb.Height / Maximum * Value); + if (inverted) + r.Top = cb.Bottom - r.Height; + } - Foreground.SetAsSource (IFace, gr, cb); - CairoHelpers.CairoRectangle (gr, cb, CornerRadius); + Foreground?.SetAsSource (IFace, gr, r); + CairoHelpers.CairoRectangle (gr, r, CornerRadius); gr.Fill (); DbgLogger.EndEvent (DbgEvtType.GODraw); diff --git a/Crow/src/Widgets/GenericStack.cs b/Crow/src/Widgets/GenericStack.cs index 3b92a2d8..29329611 100644 --- a/Crow/src/Widgets/GenericStack.cs +++ b/Crow/src/Widgets/GenericStack.cs @@ -255,5 +255,6 @@ namespace Crow { base.ClearChildren (); stretchedGO = null; } + protected override string LogName => "gs"; } } diff --git a/Crow/src/Widgets/Grid.cs b/Crow/src/Widgets/Grid.cs index 1bf74d1a..879f305c 100644 --- a/Crow/src/Widgets/Grid.cs +++ b/Crow/src/Widgets/Grid.cs @@ -132,7 +132,7 @@ namespace Crow if (idx >= Children.Count) return; Widget c = Children [idx]; - if (!c.Visible) + if (!c.IsVisible) continue; c.Slot.X = curX * (slotWidth + Spacing); c.Slot.Y = curY * (slotHeight + Spacing); diff --git a/Crow/src/Widgets/Group.cs b/Crow/src/Widgets/Group.cs index a2a58b7f..8b17b0da 100644 --- a/Crow/src/Widgets/Group.cs +++ b/Crow/src/Widgets/Group.cs @@ -250,5 +250,23 @@ namespace Crow DbgLogger.EndEvent (DbgEvtType.GOSearchTallestChild); } } + +#if DEBUG_STATS + public override long ChildCount { + get { + childrenRWLock.EnterReadLock (); + try { + long total=0; + foreach (Widget child in Children) + total += 1 + child.ChildCount; + return total; + } finally { + childrenRWLock.ExitReadLock (); + } + } + } +#endif + protected override string LogName => "grp"; + } } diff --git a/Crow/src/Widgets/GroupBase.cs b/Crow/src/Widgets/GroupBase.cs index cac017c7..7baf1ba4 100644 --- a/Crow/src/Widgets/GroupBase.cs +++ b/Crow/src/Widgets/GroupBase.cs @@ -48,8 +48,8 @@ namespace Crow #endregion bool _multiSelect = false; - ObservableList<Widget> children = new ObservableList<Widget>(); - public virtual ObservableList<Widget> Children => children; + IList<Widget> children = new ObservableList<Widget>(); + public virtual IList<Widget> Children => children; [DefaultValue(false)] public bool MultiSelect @@ -286,11 +286,10 @@ namespace Crow gr.Stroke ();*/ #endif } - DbgLogger.AddEvent (DbgEvtType.GOResetClip, this); - Clipping.Reset (); }/*else Console.WriteLine("GROUP REPAINT WITH EMPTY CLIPPING");*/ - paintCache (ctx, Slot + Parent.ClientRectangle.Position); + //paintCache (ctx, Slot + Parent.ClientRectangle.Position); + base.UpdateCache (ctx); DbgLogger.EndEvent(DbgEvtType.GOUpdateCache); } #endregion diff --git a/Crow/src/Widgets/HorizontalStack.cs b/Crow/src/Widgets/HorizontalStack.cs index b4fbea09..5e16c326 100644 --- a/Crow/src/Widgets/HorizontalStack.cs +++ b/Crow/src/Widgets/HorizontalStack.cs @@ -20,5 +20,6 @@ namespace Crow get => Orientation.Horizontal; set { base.Orientation = Orientation.Horizontal; } } + protected override string LogName => "hs"; } } diff --git a/Crow/src/Widgets/Image.cs b/Crow/src/Widgets/Image.cs index 5f8ed06e..6969541f 100644 --- a/Crow/src/Widgets/Image.cs +++ b/Crow/src/Widgets/Image.cs @@ -185,6 +185,6 @@ namespace Crow gr.Operator = Operator.Over; } } - #endregion + #endregion } } diff --git a/Crow/src/Widgets/Label.cs b/Crow/src/Widgets/Label.cs index 31127ddd..5ca6edf2 100644 --- a/Crow/src/Widgets/Label.cs +++ b/Crow/src/Widgets/Label.cs @@ -33,7 +33,7 @@ namespace Crow //TODO:change protected to private #region private and protected fields - protected string _text; + protected string _text = ""; TextAlignment _textAlignment; bool _multiline; Color selBackground; @@ -45,7 +45,7 @@ namespace Crow protected CharLocation? currentLoc = null; protected CharLocation? selectionStart = null; //selection start (row,column) - protected CharLocation? CurrentLoc { + protected virtual CharLocation? CurrentLoc { get => currentLoc; set { if (currentLoc == value) @@ -55,7 +55,7 @@ namespace Crow NotifyValueChanged ("CurrentColumn", CurrentColumn); } } - public int CurrentLine { + public virtual int CurrentLine { get => currentLoc.HasValue ? currentLoc.Value.Line : 0; set { if (currentLoc?.Line == value) @@ -64,12 +64,12 @@ namespace Crow NotifyValueChanged ("CurrentLine", CurrentLine); } } - public int CurrentColumn { + public virtual int CurrentColumn { get => currentLoc.HasValue ? currentLoc.Value.Column < 0 ? 0 : currentLoc.Value.Column : 0; set { - if (currentLoc?.Line == value) + if (CurrentColumn == value) return; - currentLoc = new CharLocation (currentLoc.Value.Line, value, currentLoc.Value.VisualCharXPosition); + currentLoc = new CharLocation (currentLoc.Value.Line, value); NotifyValueChanged ("CurrentColumn", CurrentColumn); } } @@ -302,9 +302,16 @@ namespace Crow lines.Update (_text); } /// <summary> - /// Current Selected text span. + /// Current Selected text span. May be used to set current position, or current selection. /// </summary> public TextSpan Selection { + set { + if (value.IsEmpty) + selectionStart = null; + else + selectionStart = lines.GetLocation (value.Start); + CurrentLoc = lines.GetLocation (value.End); + } get { if (CurrentLoc == null) return default; @@ -486,11 +493,7 @@ namespace Crow (int)Math.Min (Math.Max (0, Math.Floor (mouseLocalPos.Y / (fe.Ascent + fe.Descent))), lines.Count - 1) : 0; hoverLoc = new CharLocation (hoverLine, -1, mouseLocalPos.X); using (Context gr = new Context (IFace.surf)) { - gr.SelectFontFace (Font.Name, Font.Slant, Font.Wheight); - gr.SetFontSize (Font.Size); - gr.FontOptions = Interface.FontRenderingOptions; - gr.Antialias = Interface.Antialias; - + setFontForContext (gr); updateLocation (gr, ClientRectangle.Width, ref hoverLoc); } } @@ -503,15 +506,12 @@ namespace Crow return cursor; } public virtual bool DrawCursor (Context ctx, out Rectangle rect) { - if (CurrentLoc == null || !SelectionIsEmpty) { + if (CurrentLoc == null) { rect = default; return false; } if (!CurrentLoc.Value.HasVisualX) { - ctx.SelectFontFace (Font.Name, Font.Slant, Font.Wheight); - ctx.SetFontSize (Font.Size); - ctx.FontOptions = Interface.FontRenderingOptions; - ctx.Antialias = Interface.Antialias; + setFontForContext (ctx); lock (linesMutex) { if (currentLoc?.Column < 0) { updateLocation (ctx, ClientRectangle.Width, ref currentLoc); @@ -627,13 +627,7 @@ namespace Crow if (!textMeasureIsUpToDate) { using (Context gr = new Context (IFace.surf)) { - //Cairo.FontFace cf = gr.GetContextFontFace (); - - gr.SelectFontFace (Font.Name, Font.Slant, Font.Wheight); - gr.SetFontSize (Font.Size); - gr.FontOptions = Interface.FontRenderingOptions; - gr.Antialias = Interface.Antialias; - + setFontForContext (gr); measureTextBounds (gr); } } @@ -645,10 +639,7 @@ namespace Crow { base.onDraw (gr); - gr.SelectFontFace (Font.Name, Font.Slant, Font.Wheight); - gr.SetFontSize (Font.Size); - gr.FontOptions = Interface.FontRenderingOptions; - gr.Antialias = Interface.Antialias; + setFontForContext (gr); if (!textMeasureIsUpToDate) { lock (linesMutex) diff --git a/Crow/src/Widgets/Popper.cs b/Crow/src/Widgets/Popper.cs index fff2729d..2fe12df4 100644 --- a/Crow/src/Widgets/Popper.cs +++ b/Crow/src/Widgets/Popper.cs @@ -120,15 +120,29 @@ namespace Crow Rectangle r = this.ScreenCoordinates (this.Slot); if (lt == LayoutingType.X) { if (popDirection.HasFlag (Alignment.Right)) { - if (r.Right + Content.Slot.Width > tc.ClientRectangle.Right) - Content.Left = r.Left - Content.Slot.Width; - else - Content.Left = r.Right; + if (popDirection == Alignment.Right) { + if (r.Right + Content.Slot.Width > tc.ClientRectangle.Right) + Content.Left = r.Left - Content.Slot.Width; + else + Content.Left = r.Right; + } else { + if (r.Left + Content.Slot.Width > tc.ClientRectangle.Right) + Content.Left = r.Right - Content.Slot.Width; + else + Content.Left = r.Left; + } } else if (popDirection.HasFlag (Alignment.Left)) { - if (r.Left - Content.Slot.Width < tc.ClientRectangle.Left) - Content.Left = r.Right; - else - Content.Left = r.Left - Content.Slot.Width; + if (popDirection == Alignment.Left) { + if (r.Left - Content.Slot.Width < tc.ClientRectangle.Left) + Content.Left = r.Right; + else + Content.Left = r.Left - Content.Slot.Width; + } else { + if (r.Right - Content.Slot.Width < tc.ClientRectangle.Left) + Content.Left = r.Right; + else + Content.Left = r.Right - Content.Slot.Width; + } } else { if (Content.Slot.Width < tc.ClientRectangle.Width) { if (r.Left + Content.Slot.Width > tc.ClientRectangle.Right) @@ -225,6 +239,7 @@ namespace Crow public override void onMouseClick (object sender, MouseButtonEventArgs e) { IsPopped = !IsPopped; + //e.Handled = true; base.onMouseClick (sender, e); } #region IToggle implementation diff --git a/Crow/src/Widgets/PrivateContainer.cs b/Crow/src/Widgets/PrivateContainer.cs index c7daad57..c2f44816 100644 --- a/Crow/src/Widgets/PrivateContainer.cs +++ b/Crow/src/Widgets/PrivateContainer.cs @@ -209,25 +209,20 @@ namespace Crow DbgLogger.StartEvent(DbgEvtType.GOUpdateCache, this); Rectangle rb = Slot + Parent.ClientRectangle.Position; - Context gr = new Context (bmp); - if (!Clipping.IsEmpty) { - for (int i = 0; i < Clipping.NumRectangles; i++) - gr.Rectangle(Clipping.GetRectangle(i)); - gr.ClipPreserve(); - gr.Operator = Operator.Clear; - gr.Fill(); - gr.Operator = Operator.Over; + using (Context gr = new Context (bmp)) { + for (int i = 0; i < Clipping.NumRectangles; i++) + gr.Rectangle(Clipping.GetRectangle(i)); + gr.ClipPreserve(); + gr.Operator = Operator.Clear; + gr.Fill(); + gr.Operator = Operator.Over; - onDraw (gr); + onDraw (gr); + } } - - gr.Dispose (); + base.UpdateCache (ctx); - ctx.SetSource (bmp, rb.X, rb.Y); - ctx.Paint (); - DbgLogger.AddEvent (DbgEvtType.GOResetClip, this); - Clipping.Reset (); DbgLogger.EndEvent(DbgEvtType.GOUpdateCache); } #endregion @@ -249,6 +244,23 @@ namespace Crow child.Dispose (); base.Dispose (disposing); } +#if DEBUG_STATS + public override long ChildCount => child == null ? 0 : 1 + child.ChildCount; +#endif + + /*public override bool IsVisible { + get => base.IsVisible; + set { + if (value == isVisible) + return; + + base.IsVisible = value; + + if (isVisible && child != null) { + child.RegisterForRedraw(); + } + } + }*/ } } diff --git a/Crow/src/Widgets/Slider.cs b/Crow/src/Widgets/Slider.cs index dd977128..d89ae705 100644 --- a/Crow/src/Widgets/Slider.cs +++ b/Crow/src/Widgets/Slider.cs @@ -45,22 +45,12 @@ namespace Crow #region private fields int cursorSize, minimumCursorSize; Orientation _orientation; - bool holdCursor = false; + bool holdCursor, inverted; protected Widget cursor; #endregion protected double unity; - public override bool ArrangeChildren => true; - - public override bool UpdateLayout (LayoutingType layoutType) - { - if (layoutType == LayoutingType.ArrangeChildren) - computeCursorPosition (); - - return base.UpdateLayout (layoutType); - } - #region Public properties [DefaultValue (Orientation.Horizontal)] public virtual Orientation Orientation @@ -101,8 +91,31 @@ namespace Crow updateCursorWidgetProps (); } } + /// <summary> + /// if true, horizontal gauge will align drawing right, and vertical on bottom. + /// </summary> + public bool Inverted { + get => inverted; + set { + if (inverted == value) + return; + inverted = value; + NotifyValueChangedAuto (inverted); + RegisterForLayouting (LayoutingType.ArrangeChildren); + } + } + #endregion + public override bool ArrangeChildren => true; + public override bool UpdateLayout (LayoutingType layoutType) + { + if (layoutType == LayoutingType.ArrangeChildren) + computeCursorPosition (); + + return base.UpdateLayout (layoutType); + } + void updateCursorWidgetProps () { if (cursor == null) @@ -129,10 +142,16 @@ namespace Crow Rectangle r = cursor.Parent.ClientRectangle; if (_orientation == Orientation.Horizontal) { unity = (r.Width - cursorSize) / (Maximum - Minimum); - cursor.Left = r.Left + (int)((Value - Minimum) * unity); + if (inverted) + cursor.Left = r.Right - cursorSize - (int)((Value - Minimum) * unity); + else + cursor.Left = r.Left + (int)((Value - Minimum) * unity); } else { unity = (r.Height - cursorSize) / (Maximum - Minimum); - cursor.Top = r.Top + (int)((Value - Minimum) * unity); + if (inverted) + cursor.Top = r.Bottom - cursorSize - (int)((Value - Minimum) * unity); + else + cursor.Top = r.Top + (int)((Value - Minimum) * unity); } } Point mouseDownInit; @@ -145,6 +164,7 @@ namespace Crow mouseDownInit = ScreenPointToLocal (e.Position); mouseDownInitValue = Value; Rectangle cursInScreenCoord = cursor == null ? default : cursor.ScreenCoordinates (cursor.Slot); + double multiplier = inverted ? -1 : 1; if (cursInScreenCoord.ContainsOrIsEqual (e.Position)){ //Rectangle r = cursor.Parent.ClientRectangle; //if (r.Width - cursorSize > 0) { @@ -154,13 +174,13 @@ namespace Crow holdCursor = true; }else if (_orientation == Orientation.Horizontal) { if (e.Position.X < cursInScreenCoord.Left) - Value -= LargeIncrement; + Value -= LargeIncrement * multiplier; else - Value += LargeIncrement; + Value += LargeIncrement * multiplier; } else if (e.Position.Y < cursInScreenCoord.Top) - Value -= LargeIncrement; + Value -= LargeIncrement * multiplier; else - Value += LargeIncrement; + Value += LargeIncrement * multiplier; base.onMouseDown (sender, e); } @@ -180,6 +200,8 @@ namespace Crow if (r.Width - cursorSize == 0) return; double unit = (Maximum - Minimum) / (double)(r.Width - cursorSize); + if (inverted) + unit = -unit; double tmp = mouseDownInitValue + (double)m.X * unit; tmp -= tmp % SmallIncrement; Value = tmp; @@ -187,6 +209,8 @@ namespace Crow if (r.Height - cursorSize == 0) return; double unit = (Maximum - Minimum) / (double)(r.Height - cursorSize); + if (inverted) + unit = -unit; double tmp = mouseDownInitValue + (double)m.Y * unit; tmp -= tmp % SmallIncrement; Value = tmp; diff --git a/Crow/src/Widgets/Table copy.cs b/Crow/src/Widgets/Table copy.cs deleted file mode 100644 index 5aeaede8..00000000 --- a/Crow/src/Widgets/Table copy.cs +++ /dev/null @@ -1,259 +0,0 @@ -// Copyright (c) 2019-2021 Jean-Philippe Bruyère <jp_bruyere@hotmail.com> -// -// This code is licensed under the MIT license (MIT) (http://opensource.org/licenses/MIT) -using System; -using System.ComponentModel; -using System.Linq; -using Crow.Cairo; - -namespace Crow -{ - /// <summary> - /// Table column definition - /// </summary> - public class Column2 : IValueChange - { - #region IValueChange implementation - public event EventHandler<ValueChangeEventArgs> ValueChanged; - public virtual void NotifyValueChanged (string MemberName, object _value) - => ValueChanged.Raise (this, new ValueChangeEventArgs (MemberName, _value)); - #endregion - - string caption; - Measure width = Measure.Fit; - public int ComputedWidth; - public Widget LargestWidget; - - public string Caption { - get => caption; - set { - if (caption == value) - return; - caption = value; - NotifyValueChanged ("Caption", caption); - } - } - /// <summary> - /// column width, special value 'Inherit' will be used to share table width equaly among columns - /// </summary> - /// <value>The column's width.</value> - public Measure Width { - get => width; - set { - if (width == value) - return; - width = value; - NotifyValueChanged ("Width", width); - } - } - - public static Column Parse (string str) { - if (string.IsNullOrEmpty (str)) - return null; - Column c = new Column(); - string[] tmp = str.Split (','); - c.Caption = tmp[0]; - if (tmp.Length > 1) - c.Width = Measure.Parse (tmp[1]); - return c; - } - } - - - public class Table2 : VerticalStack - { - #region CTOR - public Table2 () {} - public Table2 (Interface iface, string style = null) : base (iface, style) { } - #endregion - - //int lineWidth; - ObservableList<Column> columns = new ObservableList<Column>(); - - public ObservableList<Column> Columns { - get => columns; - set { - if (columns == value) - return; - if (columns != null) { - columns.ListAdd -= Ol_AddColumn; - columns.ListAdd -= Ol_RemoveColumn; - - foreach (Column c in columns) - c.ValueChanged += column_valueChanged; - } - - columns = value; - - if (columns != null) { - columns.ListAdd += Ol_AddColumn; - columns.ListAdd += Ol_RemoveColumn; - - foreach (Column c in columns) - c.ValueChanged += column_valueChanged; - - foreach (TableRow row in Children) { - for (int i = 0; i < columns.Count && i < row.Children.Count; i++) - row.Children[i].Width = columns[i].Width; - } - } - NotifyValueChangedAuto(columns); - } - } - - void column_valueChanged (object sender, ValueChangeEventArgs e) { - switch (e.MemberName) { - case "Width": - int columnIdx = columns.IndexOf (sender as Column); - foreach (TableRow row in Children.OfType<TableRow>().Where (r => r.Children.Count > columnIdx)) - row.Children[columnIdx].Width = (Measure)e.NewValue; - break; - } - } - - public override void AddChild (Widget child) { - if (!(child is TableRow tr)) - throw new Exception ("Table widget accept only TableRow as child."); - base.AddChild (child); - - tr.Children.ListAdd += Ol_tableRow_ChildAdd; - tr.Children.ListRemove += Ol_tableRow_ChildRemove; - tr.Children.ListClear += Ol_tableRow_ChildClear; - - for (int i = 0; i < columns.Count && i < tr.Children.Count; i++) - tr.Children[i].Width = columns[i].Width; - } - public override void RemoveChild(Widget child) - { - base.RemoveChild(child); - - TableRow tr = child as TableRow; - tr.Children.ListAdd -= Ol_tableRow_ChildAdd; - tr.Children.ListRemove -= Ol_tableRow_ChildRemove; - tr.Children.ListClear -= Ol_tableRow_ChildClear; - } - void Ol_tableRow_ChildAdd (object sender, ListChangedEventArg e) - { - Widget w = e.Element as Widget; - if (e.Index < Columns.Count) - w.Width = Columns[e.Index].Width; - w.LayoutChanged += onTableRow_ChildLayoutChanges; - } - void Ol_tableRow_ChildRemove (object sender, ListChangedEventArg e) { - Widget w = e.Element as Widget; - w.LayoutChanged -= onTableRow_ChildLayoutChanges; - } - void Ol_tableRow_ChildClear (object sender, ListClearEventArg e) { - foreach (Widget w in e.Elements) - w.LayoutChanged -= onTableRow_ChildLayoutChanges; - } - void onTableRow_ChildLayoutChanges (object sender, LayoutingEventArgs arg) { - if (Columns == null) - return; - Widget g = sender as Widget; - TableRow tr = g.Parent as TableRow; - int cIdx = tr.Children.IndexOf (g); - //if (cIdx < Columns.Count && Columns.wi) - } - void Ol_AddColumn (object sender, ListChangedEventArg e) { - (e.Element as Column).ValueChanged += column_valueChanged; - foreach (TableRow row in Children) { - for (int i = e.Index; i < columns.Count && i < row.Children.Count; i++) - row.Children[i].Width = columns[i].Width; - } - - } - void Ol_RemoveColumn (object sender, ListChangedEventArg e) { - (e.Element as Column).ValueChanged -= column_valueChanged; - foreach (TableRow row in Children) { - for (int i = e.Index; i < columns.Count && i < row.Children.Count; i++) - row.Children[i].Width = columns[i].Width; - } - } - - - public override void ChildrenLayoutingConstraints(ILayoutable layoutable, ref LayoutingType layoutType) - { - //trigger layouting for width only in the first row, the other will be set at the same horizontal position and width. - if (layoutable == Children[0]) - layoutType &= (~LayoutingType.X); - else - layoutType &= (~(LayoutingType.X|LayoutingType.Width)); - } - - //overriden to prevent search for largest child, all the rows have the same total width. - public override void ComputeChildrenPositions () { - int d = 0; - childrenRWLock.EnterReadLock(); - foreach (TableRow c in Children) { - if (!c.IsVisible) - continue; - c.Slot.Y = d; - d += c.Slot.Height + Spacing; - } - childrenRWLock.ExitReadLock(); - IsDirty = true; - } -/* public override bool UpdateLayout(LayoutingType layoutType) - { - RegisteredLayoutings &= (~layoutType); - - if (layoutType == LayoutingType.Width) { - //propagate column.width to each row's children - } - return base.UpdateLayout(layoutType); - }*/ - - /*public override void OnChildLayoutChanges (object sender, LayoutingEventArgs arg) { - TableRow row = sender as TableRow; - TableRow firstRow = Children[0] as TableRow; - - if (arg.LayoutType == LayoutingType.Width) { - if (row == firstRow) { - base.OnChildLayoutChanges (sender, arg); - foreach (TableRow r in Children.Skip(1)) { - r.contentSize = firstRow.contentSize; - setChildWidth (r, firstRow.Slot.Width); - } - } - } - - base.OnChildLayoutChanges (sender, arg); - }*/ - /*protected override void onDraw (Context gr) { - DbgLogger.StartEvent (DbgEvtType.GODraw, this); - - base.onDraw (gr); - - if (Children.Count > 0) { - - Rectangle cb = ClientRectangle; - TableRow fr = Children[0] as TableRow; - - - gr.LineWidth = lineWidth; - Foreground.SetAsSource (IFace, gr, cb); - CairoHelpers.CairoRectangle (gr, cb, CornerRadius, lineWidth); - double x = 0.5 + cb.Left + fr.Margin + 0.5 * fr.Spacing + fr.Children[0].Slot.Width; - for (int i = 1; i < fr.Children.Count ; i++) - { - gr.MoveTo (x, cb.Y); - gr.LineTo (x, cb.Bottom); - x += fr.Spacing + fr.Children[i].Slot.Width ; - } - - //horizontal lines - x = 0.5 + cb.Top + 0.5 * Spacing + Children[0].Slot.Height; - for (int i = 0; i < Children.Count - 1; i++) - { - gr.MoveTo (cb.Left, x); - gr.LineTo (cb.Right, x); - x += Spacing + Children[i].Slot.Height ; - } - gr.Stroke (); - } - - DbgLogger.EndEvent (DbgEvtType.GODraw); - }*/ - } -} diff --git a/Crow/src/Widgets/Table.cs b/Crow/src/Widgets/Table.cs index 1427e9ba..a683dd78 100644 --- a/Crow/src/Widgets/Table.cs +++ b/Crow/src/Widgets/Table.cs @@ -270,7 +270,7 @@ namespace Crow int largestWidth = 0; for (int i = 1; i < Children.Count; i++) { TableRow row = Children[i] as TableRow; - if (!row.IsVisible) + if (!row.IsVisible || row.Children.Count <= i) continue; int cw = row.Children [cIdx]. measureRawSize (LayoutingType.Width); if (cw > largestWidth) { @@ -295,7 +295,7 @@ namespace Crow public override void onMouseMove(object sender, MouseMoveEventArgs e) { - if (ColumnSpacing > 0 && Columns.Count > 0) { + if (Columns != null && ColumnSpacing > 0 && Columns.Count > 0) { Point m = ScreenPointToLocal (e.Position); if (IFace.IsDown (Glfw.MouseButton.Left) && splitIndex >= 0) { int splitPos = (int)(0.5 * ColumnSpacing + m.X); diff --git a/Crow/src/Widgets/TemplatedControl.cs b/Crow/src/Widgets/TemplatedControl.cs index e971c20b..7c804651 100644 --- a/Crow/src/Widgets/TemplatedControl.cs +++ b/Crow/src/Widgets/TemplatedControl.cs @@ -45,7 +45,7 @@ namespace Crow //TODO: this property should be renamed 'TemplatePath' [DefaultValue(null)] public string Template { - get { return _template; } + get => _template; set { if (_template == value) return; @@ -89,6 +89,8 @@ namespace Crow /// <param name="gr">Backend context</param> protected override void onDraw (Context gr) { + DbgLogger.StartEvent (DbgEvtType.GODraw, this); + gr.Save (); if (ClipToClientRect) { @@ -99,7 +101,10 @@ namespace Crow if (child != null) child.Paint (gr); + gr.Restore (); + + DbgLogger.EndEvent (DbgEvtType.GODraw); } #endregion diff --git a/Crow/src/Widgets/TemplatedGroup.cs b/Crow/src/Widgets/TemplatedGroup.cs index 90c23553..601e2183 100644 --- a/Crow/src/Widgets/TemplatedGroup.cs +++ b/Crow/src/Widgets/TemplatedGroup.cs @@ -135,10 +135,10 @@ namespace Crow { } #endregion - public virtual List<Widget> Items{ + public virtual IList<Widget> Items{ get { - return isPaged ? itemsContainer?.Children.SelectMany(x => (x as Group).Children).ToList() - : itemsContainer?.Children; + return isPaged ? (IList<Widget>)itemsContainer?.Children.SelectMany(x => (x as Group).Children).ToList() + : (IList<Widget>)itemsContainer?.Children; } } @@ -263,7 +263,7 @@ namespace Crow { void Ol_ListEdit (object sender, ListChangedEventArg e) { if (this.isPaged) { throw new NotImplementedException (); - } else + } else if (e.Index<itemsContainer.Children.Count) itemsContainer.Children [e.Index].DataSource = e.Element; } diff --git a/Crow/src/Widgets/TextBox.cs b/Crow/src/Widgets/TextBox.cs index 2564129e..8bce1322 100644 --- a/Crow/src/Widgets/TextBox.cs +++ b/Crow/src/Widgets/TextBox.cs @@ -119,7 +119,7 @@ namespace Crow } } /// <summary> Mouse Wheel Scrolling multiplier </summary> - [DefaultValue (5)] + [DefaultValue (20)] public virtual int MouseWheelSpeed { get { return mouseWheelSpeed; } set { @@ -232,6 +232,23 @@ namespace Crow NotifyValueChanged ("ChildHeightRatio", Math.Min (1.0, (double)cb.Height / cachedTextSize.Height)); } } + public virtual void Cut () { + TextSpan selection = Selection; + if (selection.IsEmpty) + return; + IFace.Clipboard = SelectedText; + update (new TextChange (selection.Start, selection.Length, "")); + } + public virtual void Copy () { + TextSpan selection = Selection; + if (selection.IsEmpty) + return; + IFace.Clipboard = SelectedText; + } + public virtual void Paste () { + TextSpan selection = Selection; + update (new TextChange (selection.Start, selection.Length, IFace.Clipboard)); + } #region Keyboard handling public override void onKeyDown (object sender, KeyEventArgs e) { @@ -266,9 +283,9 @@ namespace Crow break; case Key.Insert: if (IFace.Shift) - update (new TextChange (selection.Start, selection.Length, IFace.Clipboard)); - else if (IFace.Ctrl && !selection.IsEmpty) - IFace.Clipboard = SelectedText; + Paste (); + else if (IFace.Ctrl) + Copy (); break; case Key.KeypadEnter: case Key.Enter: @@ -321,9 +338,9 @@ namespace Crow protected void update (TextChange change) { lock (linesMutex) { - Span<char> tmp = stackalloc char[Text.Length + (change.ChangedText.Length - change.Length)]; - //Console.WriteLine ($"{Text.Length,-4} {change.Start,-4} {change.Length,-4} {change.ChangedText.Length,-4} tmp:{tmp.Length,-4}"); ReadOnlySpan<char> src = Text.AsSpan (); + Span<char> tmp = stackalloc char[src.Length + (change.ChangedText.Length - change.Length)]; + //Console.WriteLine ($"{Text.Length,-4} {change.Start,-4} {change.Length,-4} {change.ChangedText.Length,-4} tmp:{tmp.Length,-4}"); src.Slice (0, change.Start).CopyTo (tmp); change.ChangedText.AsSpan ().CopyTo (tmp.Slice (change.Start)); src.Slice (change.End).CopyTo (tmp.Slice (change.Start + change.ChangedText.Length)); @@ -338,11 +355,11 @@ namespace Crow IFace.forceTextCursor = true; } - NotifyValueChanged ("Text", Text); OnTextChanged (this, new TextChangeEventArgs (change)); RegisterForGraphicUpdate (); } + protected override string LogName => "tb"; } } diff --git a/Crow/src/Widgets/VerticalStack.cs b/Crow/src/Widgets/VerticalStack.cs index ac4236b1..f760918c 100644 --- a/Crow/src/Widgets/VerticalStack.cs +++ b/Crow/src/Widgets/VerticalStack.cs @@ -19,5 +19,6 @@ namespace Crow get => Orientation.Vertical; set { base.Orientation = Orientation.Vertical; } } + protected override string LogName => "vs"; } } diff --git a/Crow/src/Widgets/Widget.cs b/Crow/src/Widgets/Widget.cs index d47675b8..42f5da83 100644 --- a/Crow/src/Widgets/Widget.cs +++ b/Crow/src/Widgets/Widget.cs @@ -29,15 +29,20 @@ namespace Crow public class Widget : ILayoutable, IValueChange, IDisposable { internal ReaderWriterLockSlim parentRWLock = new ReaderWriterLockSlim(); - #if DEBUG_LOG +#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 public int treeIndex; public int instanceIndex;//index in the GraphicObjects list public int yIndex;//absolute index in the graphic tree for debug draw public int xLevel;//x increment for debug draw - #endif - #if DESIGN_MODE +#endif +#if DEBUG_STATS + public static long TotalWidgetCreated; + public static long TotalWidgetDisposed; + public virtual long ChildCount => 0; +#endif +#if DESIGN_MODE static MethodInfo miDesignAddDefLoc = typeof(Widget).GetMethod("design_add_style_location", BindingFlags.Instance | BindingFlags.NonPublic); static MethodInfo miDesignAddValLoc = typeof(Widget).GetMethod("design_add_iml_location", @@ -133,7 +138,7 @@ namespace Crow public string DesignName { get { return GetType ().Name + design_id; } } - #endif +#endif #region IDisposable implementation protected bool disposed = false; @@ -168,6 +173,9 @@ namespace Crow Clipping?.Dispose (); bmp?.Dispose (); disposed = true; +#if DEBUG_STATS + TotalWidgetDisposed++; +#endif DbgLogger.EndEvent (DbgEvtType.Disposing); } @@ -221,6 +229,9 @@ namespace Crow /// </summary> protected Widget () { Clipping = new Region (); +#if DEBUG_STATS + TotalWidgetCreated++; +#endif #if DEBUG_LOG instanceIndex = GraphicObjects.Count; GraphicObjects.Add (this); @@ -380,12 +391,10 @@ namespace Crow /// <returns>A new rectangle with same dimension as the input one with x and y relative to the context surface</returns> /// <param name="r">A rectangle to compute the coordinate for.</param> public virtual Rectangle ContextCoordinates(Rectangle r){ - Widget go = Parent as Widget; - if (go == null) - return r + Parent.ClientRectangle.Position; - return go.CacheEnabled ? - r + Parent.ClientRectangle.Position : - Parent.ContextCoordinates (r); + return Parent is Widget w ? + w.CacheEnabled ? + r + Parent.ClientRectangle.Position : Parent.ContextCoordinates (r) + : Parent != null ? r + Parent.ClientRectangle.Position : r; } public virtual Rectangle RelativeSlot (Widget target) @@ -409,10 +418,10 @@ namespace Crow #endregion public Point ScreenPointToLocal(Point p){ Point pt = p - ScreenCoordinates (Slot).TopLeft - ClientRectangle.TopLeft; - if (pt.X < 0) + /*if (pt.X < 0) pt.X = 0; if (pt.Y < 0) - pt.Y = 0; + pt.Y = 0;*/ return pt; } @@ -497,7 +506,7 @@ namespace Crow /// If enabled, resulting bitmap of graphic object is cached /// speeding up rendering of complex object. Default is enabled. /// </summary> - [DesignCategory ("Behavior")][DefaultValue(true)] + [DesignCategory ("Behavior")][DefaultValue(false)] public virtual bool CacheEnabled { get => cacheEnabled; set { @@ -788,6 +797,7 @@ namespace Crow /// <summary> /// Boolean for enabling or not the sticky mouse mechanic /// </summary> + [DesignCategory ("Behaviour")][DefaultValue(false)] public virtual bool StickyMouseEnabled { get => stickyMouseEnabled; set { @@ -989,7 +999,7 @@ namespace Crow /// </summary> [DesignCategory ("Data")] public Type DataSourceType { - get { return dataSourceType; } + get => dataSourceType; set { dataSourceType = value; } } /// <summary> @@ -1044,8 +1054,8 @@ namespace Crow if (localDataSourceIsNull) OnDataSourceChanged (this, e); } - internal bool localDataSourceIsNull { get { return dataSource == null; } } - public bool localLogicalParentIsNull { get { return logicalParent == null; } } + internal bool localDataSourceIsNull => dataSource == null; + public bool localLogicalParentIsNull => logicalParent == null; public virtual void OnDataSourceChanged(object sender, DataSourceChangeEventArgs e){ DataSourceChanged.Raise (this, e); @@ -1062,7 +1072,7 @@ namespace Crow /// </summary> [DesignCategory ("Appearance")] public virtual string Style { - get { return style; } + get => style; set { if (value == style) return; @@ -1076,7 +1086,7 @@ namespace Crow /// Gets or sets a tooltip to show when mouse stay still over the control. /// </summary> /// <remarks> - /// By default, the tooltip container widget that will be show is defined in '#Crow.Tooltip.template' and the widget + /// By default, the tooltip container widget that will be shown is defined in '#Crow.Tooltip.template' and the widget /// tooltip string is interpreted as a single string helper message that may be a binding expression. /// If the widget Tooltip property start with a '#', the tooltip string will be interpreted as a resource path of /// a custom IML template to show, which will have its datasource set to the widget triggering the tooltip. @@ -1138,20 +1148,24 @@ namespace Crow // those files being placed in a Styles folder string styleKey = style; if (!string.IsNullOrEmpty (style)) { - if (IFace.Styling.ContainsKey (style)) { - styling.Add (IFace.Styling [style]); - } - } - if (IFace.Styling.ContainsKey (thisType.FullName)) { - styling.Add (IFace.Styling [thisType.FullName]); - if (string.IsNullOrEmpty (styleKey)) - styleKey = thisType.FullName; - } - if (IFace.Styling.ContainsKey (thisType.Name)) { - styling.Add (IFace.Styling [thisType.Name]); - if (string.IsNullOrEmpty (styleKey)) - styleKey = thisType.Name; + if (IFace.Styling.ContainsKey (style)) + styling.Add (IFace.Styling [style]); } + //check the whole type hierarchy for styling + Type styleType = thisType; + do { + if (IFace.Styling.ContainsKey (styleType.FullName)) { + styling.Add (IFace.Styling [styleType.FullName]); + /*if (string.IsNullOrEmpty (styleKey)) + styleKey = thisType.FullName;*/ + } + if (IFace.Styling.ContainsKey (styleType.Name)) { + styling.Add (IFace.Styling [styleType.Name]); + /*if (string.IsNullOrEmpty (styleKey)) + styleKey = thisType.Name;*/ + } + styleType = styleType.BaseType; + } while (styleType != null); if (string.IsNullOrEmpty (styleKey)) styleKey = thisType.FullName; @@ -1179,7 +1193,9 @@ namespace Crow if (!getDefaultEvent(ei, styling, out expression)) continue; //TODO:dynEventHandler could be cached somewhere, maybe a style instanciator class holding the styling delegate and bound to it. - foreach (string exp in CompilerServices.splitOnSemiColumnOutsideAccolades(expression)) { + foreach (string exp in expression.Split (';')) { + //foreach (string exp in CompilerServices.splitOnSemiColumnOutsideAccolades(expression)) { + string trimed = exp.Trim(); if (trimed.StartsWith ("{", StringComparison.Ordinal)){ il.Emit (OpCodes.Ldloc_0);//load this as 1st arg of event Add @@ -1458,7 +1474,8 @@ namespace Crow if (parent != null) { parent.RegisterClip (LastPaintedSlot); parent.RegisterClip (Slot); - } + }//else + //Console.WriteLine ($"clipping reg canceled (no parent): {this.ToString()}"); parentRWLock.ExitReadLock (); DbgLogger.EndEvent (DbgEvtType.GOClippingRegistration); @@ -1472,23 +1489,34 @@ 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 { Rectangle cb = ClientRectangle; Rectangle r = clip + cb.Position; - if (r.Right > cb.Right) + /*if (r.Right > cb.Right) r.Width -= r.Right - cb.Right; if (r.Bottom > cb.Bottom) - r.Height -= r.Bottom - cb.Bottom; - if (r.Width < 0 || r.Height < 0) - return; - if (cacheEnabled && !IsDirty) + 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()}"); + return; + } + if (cacheEnabled) Clipping.UnionRectangle (r); - if (Parent == null) - return; - Widget p = Parent as Widget; - if (p?.IsDirty == true && p?.CacheEnabled == true) - return; + if (Parent == null){ + //Console.WriteLine ($"clip chain aborded (no parent): {this.ToString()}"); + return; + } + /*Widget p = Parent as Widget; + if (p?.IsDirty == true && p?.CacheEnabled == true){ + Console.WriteLine ($"parent.regclip canceled p.Dirty:{p?.IsDirty} Cached:{p?.CacheEnabled}: {this.ToString()}"); + return; + }*/ Parent.RegisterClip (r + Slot.Position); } finally { DbgLogger.EndEvent (DbgEvtType.GORegisterClip); @@ -1524,6 +1552,10 @@ namespace Crow if (RegisteredLayoutings == LayoutingType.None) IFace.EnqueueForRepaint (this); } + /// <summary> + /// query a repaint, if control is cached, cache will not be updated and simply repainted. + /// if not cached, repaint will trigger the onDraw method. + /// </summary> public void RegisterForRepaint () { if (RegisteredLayoutings == LayoutingType.None && !IsDirty) IFace.EnqueueForRepaint (this); @@ -1794,6 +1826,13 @@ namespace Crow } #endregion + protected void setFontForContext (Context gr) { + gr.SelectFontFace (Font.Name, Font.Slant, Font.Wheight); + gr.SetFontSize (Font.Size); + gr.FontOptions = Interface.FontRenderingOptions; + gr.Antialias = Interface.Antialias; + } + #region Rendering /// <summary> This is the common overridable drawing routine to create new widget </summary> protected virtual void onDraw(Context gr) @@ -2134,16 +2173,14 @@ namespace Crow } } } + protected virtual string LogName => GetType().Name; public override string ToString () { string tmp =""; if (Parent != null) - tmp = Parent.ToString () + tmp; - /*#if DEBUG_LAYOUTING - return Name == "unamed" ? tmp + "." + this.GetType ().Name + GraphicObjects.IndexOf(this).ToString(): tmp + "." + Name; - #else*/ - return string.IsNullOrEmpty(Name) ? tmp + "." + this.GetType ().Name : tmp + "." + Name; + tmp = Parent.ToString () + tmp; + return string.IsNullOrEmpty(Name) ? tmp + "." + LogName : tmp + "." + Name; //#endif } /// <summary> @@ -2157,7 +2194,8 @@ namespace Crow else*/ try { - parent?.RegisterClip (ContextCoordinates(LastPaintedSlot)); + if (parent != null) + parent.RegisterClip (ContextCoordinates(LastPaintedSlot)); } catch (System.Exception e) { diff --git a/Crow/src/styling/StyleReader.cs b/Crow/src/styling/StyleReader.cs index 22be0c35..46931edf 100644 --- a/Crow/src/styling/StyleReader.cs +++ b/Crow/src/styling/StyleReader.cs @@ -162,17 +162,20 @@ namespace Crow throw new ParserException (line, column, "Unexpected end of statement", resId); ReadChar (); if (targetsClasses.Count == 0) { - //style constants override previous values. - StylingConstants[currentProperty] = token.ToString (); + //only first style constants kept. + if (!StylingConstants.ContainsKey (currentProperty)) + StylingConstants[currentProperty] = token.ToString (); curState = States.classNames; } else { foreach (string tc in targetsClasses) { if (!Styling.ContainsKey (tc)) Styling [tc] = new Style (); - Styling[tc][currentProperty] = token.ToString (); + if (!Styling[tc].ContainsKey (currentProperty)) { + Styling[tc][currentProperty] = token.ToString (); #if DESIGN_MODE - Styling [tc].Locations[currentProperty] = new FileLocation(resId, line, column - token.Length - 1, token.Length); + Styling [tc].Locations[currentProperty] = new FileLocation(resId, line, column - token.Length - 1, token.Length); #endif + } } curState = States.members; } diff --git a/Crow/test.txt b/Crow/test.txt new file mode 100644 index 00000000..fe13dfb9 --- /dev/null +++ b/Crow/test.txt @@ -0,0 +1 @@ +this is a test document
\ No newline at end of file diff --git a/Directory.Build.props b/Directory.Build.props index 41e78201..11fcc004 100644 --- a/Directory.Build.props +++ b/Directory.Build.props @@ -6,10 +6,13 @@ <Authors>Jean-Philippe Bruyère</Authors> <LangVersion>7.3</LangVersion> - <CrowVersion>0.9.4</CrowVersion> + <CrowVersion>0.9.7</CrowVersion> <CrowPackageVersion>$(CrowVersion)-beta</CrowPackageVersion> <CrowStbSharp>true</CrowStbSharp> <CrowDebugLogEnabled>false</CrowDebugLogEnabled> + <CrowDebugStatsEnabled>true</CrowDebugStatsEnabled> + <CrowDesignModeEnabled>true</CrowDesignModeEnabled> + <GlfwSharpVersion>0.2.11-beta</GlfwSharpVersion> </PropertyGroup> </Project> diff --git a/Documentation/DeviceEventRouting.md b/Documentation/DeviceEventRouting.md new file mode 100644 index 00000000..ae3bc317 --- /dev/null +++ b/Documentation/DeviceEventRouting.md @@ -0,0 +1,4 @@ + +Bubbling or not Bubbling, that the question. + + diff --git a/Samples/BasicTests/BasicTests.cs b/Samples/BasicTests/BasicTests.cs index 13bb41fe..7e704916 100644 --- a/Samples/BasicTests/BasicTests.cs +++ b/Samples/BasicTests/BasicTests.cs @@ -12,6 +12,7 @@ namespace Samples static void Main () { using (BasicTests app = new BasicTests ()) { + app.SolidBackground = false; app.Run (); } } @@ -91,8 +92,8 @@ namespace Samples #endif Load (testFiles [idx]).DataSource = this; } catch (Exception ex) { - (LoadIMLFragment ($"<Label Background='Red' Foreground='White' Height='Fit' Width='Stretched' Multiline='true' VerticalAlignment='Bottom' Margin='5' />") as OldLabel).Text = ex.ToString(); - Console.WriteLine (ex.Message + "\n" + ex.InnerException); + //(LoadIMLFragment ($"<Label Background='Red' Foreground='White' Height='Fit' Width='Stretched' Multiline='true' VerticalAlignment='Bottom' Margin='5' />") as OldLabel).Text = ex.ToString(); + Console.WriteLine (ex); //MessageBox.Show (CurrentInterface, MessageBox.Type.Error, ex.Message + "\n" + ex.InnerException.Message).Modal = true; } return false; diff --git a/Samples/DebugLogAnalyzer/src/DbgLogViewer.cs b/Samples/DebugLogAnalyzer/src/DbgLogViewer.cs index 251090ef..89cf3e0c 100644 --- a/Samples/DebugLogAnalyzer/src/DbgLogViewer.cs +++ b/Samples/DebugLogAnalyzer/src/DbgLogViewer.cs @@ -271,10 +271,7 @@ namespace Crow { base.onDraw (gr); - gr.SelectFontFace (Font.Name, Font.Slant, Font.Wheight); - gr.SetFontSize (Font.Size); - gr.FontOptions = Interface.FontRenderingOptions; - gr.Antialias = Cairo.Antialias.None; + setFontForContext (gr); if (widgets == null) return; @@ -387,10 +384,7 @@ namespace Crow } } - ctx.SelectFontFace (Font.Name, Font.Slant, Font.Wheight); - ctx.SetFontSize (Font.Size); - ctx.FontOptions = Interface.FontRenderingOptions; - ctx.Antialias = Interface.Antialias; + setFontForContext (ctx); string str = ticksToMS(hoverTick); @@ -609,8 +603,7 @@ namespace Crow using (Context gr = new Context (IFace.surf)) { double maxNameWidth = 0.0; - gr.SelectFontFace (Font.Name, Font.Slant, Font.Wheight); - gr.SetFontSize (Font.Size); + setFontForContext (gr); foreach (DbgWidgetRecord o in widgets) { double nameWidth = gr.TextExtents (o.name).Width + 5.0 * o.xLevel; diff --git a/Samples/DebugLogAnalyzer/src/DebugInterfaceWidget.cs b/Samples/DebugLogAnalyzer/src/DebugInterfaceWidget.cs index c8b27d7d..38d94f3d 100644 --- a/Samples/DebugLogAnalyzer/src/DebugInterfaceWidget.cs +++ b/Samples/DebugLogAnalyzer/src/DebugInterfaceWidget.cs @@ -427,7 +427,7 @@ namespace Crow Debugger.Break (); } } - void updateWidgetEvents (List<DbgWidgetRecord> widgets, DbgEvent evt) { + void updateWidgetEvents (IList<DbgWidgetRecord> widgets, DbgEvent evt) { if (evt is DbgWidgetEvent we) widgets.FirstOrDefault (w => w.InstanceIndex == we.InstanceIndex)?.Events.Add (we); if (evt.Events == null) diff --git a/Samples/DebugLogAnalyzer/ui/main.crow b/Samples/DebugLogAnalyzer/ui/main.crow index 5afc6c6c..28433b11 100644 --- a/Samples/DebugLogAnalyzer/ui/main.crow +++ b/Samples/DebugLogAnalyzer/ui/main.crow @@ -70,11 +70,11 @@ </HorizontalStack> <Label Background="Red" Foreground="White" Margin="5" Width="Stretched" Text="{../../../dbgIfaceWidget.CrowDebuggerErrorMessage}" IsVisible="{../../../dbgIfaceWidget.CrowDebuggerNOK}"/> - <!--<CheckBox Name="cbFile" Caption="Record to file" IsChecked="{²DebugLogToFile}" Background="Onyx"/>--> <HorizontalStack Height="Fit" Width="Stretched" IsEnabled="{../cbFile.IsChecked}" Background="Onyx" Margin="5"> <Label Text="Debug log output file:" Fit="true"/> <TextBox Text="{²../../../../dbgIfaceWidget.DebugLogFilePath}" /> </HorizontalStack> + <CheckBox Name="cbFile" Caption="Record to file" IsChecked="{²../../../dbgIfaceWidget.DebugLogToFile}" Background="Onyx"/> <EnumSelector RadioButtonStyle="CheckBox2" Template="#Dbg.EnumSelector.template" Background="Grey" Caption="Recorded Events" EnumValue="{²RecordedEvents}" BitFieldExcludeMask="255" /> @@ -97,7 +97,7 @@ <Wrapper Orientation="Vertical" Name="ItemsContainer" Margin="0" Background="{./Background}"/> </Template> <ItemTemplate> - <Button Command="{}" Height="Stretched" Width="Fit"/> + <Button Command="{}" Height="Fit" Width="Fit"/> </ItemTemplate> </Menu> </HorizontalStack> diff --git a/Samples/PerfTests/Program.cs b/Samples/PerfTests/Program.cs index cb96078b..14da072a 100644 --- a/Samples/PerfTests/Program.cs +++ b/Samples/PerfTests/Program.cs @@ -166,8 +166,8 @@ namespace PerfTests else surf = new Crow.Cairo.ImageSurface (Crow.Cairo.Format.Argb32, ClientRectangle.Width, ClientRectangle.Height); - loadStyling (); - + initDictionaries (); + loadStyling (); } protected override void Dispose (bool disposing) { diff --git a/Samples/ShowCase/ShowCase.cs b/Samples/ShowCase/ShowCase.cs index fdbe6aa3..66e1f43e 100644 --- a/Samples/ShowCase/ShowCase.cs +++ b/Samples/ShowCase/ShowCase.cs @@ -26,13 +26,13 @@ namespace ShowCase Environment.SetEnvironmentVariable ("FONTCONFIG_PATH", @"C:\Users\Jean-Philippe\source\vcpkg\installed\x64-windows\tools\fontconfig\fonts"); using (Showcase app = new Showcase ()) { + app.WindowTitle = "C.R.O.W Showcase"; + app.SetWindowIcon ("#Crow.Icons.crow.png"); //app.Theme = @"C:\Users\Jean-Philippe\source\Crow\Themes\TestTheme"; CurrentProgramInstance = app; app.Run (); } - } - - + } public Container crowContainer; Stopwatch reloadChrono = new Stopwatch (); @@ -106,15 +106,6 @@ namespace ShowCase reloadChrono.Reset (); } - public string DebugLogFilePath { - get => Configuration.Global.Get<string> (nameof (DebugLogFilePath)); - set { - if (CurrentFile == value) - return; - Configuration.Global.Set (nameof (DebugLogFilePath), value); - NotifyValueChanged (DebugLogFilePath); - } - } public override bool OnKeyDown (Key key) { diff --git a/Samples/ShowCase/ShowCase.csproj b/Samples/ShowCase/ShowCase.csproj index 70037e60..bee99267 100644 --- a/Samples/ShowCase/ShowCase.csproj +++ b/Samples/ShowCase/ShowCase.csproj @@ -3,9 +3,6 @@ <ItemGroup> <EmbeddedResource Include="ui\*.*"> <LogicalName>ShowCase.%(Filename)%(Extension)</LogicalName> - </EmbeddedResource> - </ItemGroup> - <ItemGroup> - <ProjectReference Include="$(MSBuildThisFileDirectory)\..\..\CrowDbgShared\CrowDbgShared.csproj" /> + </EmbeddedResource> </ItemGroup> </Project>
\ No newline at end of file diff --git a/Samples/ShowCase/ui/showcase.crow b/Samples/ShowCase/ui/showcase.crow index 1236b705..9e6b0cd2 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"> + <Expandable Name="exp" Caption="{Name}" MouseDoubleClick="/onClickForExpand" BubbleMouseEvent="true"> <Template> <VerticalStack> <Border CornerRadius="2" Margin="0" Height="Fit" MouseDoubleClick="./onClickForExpand" @@ -86,7 +86,7 @@ <!--<Button Style="IcoButton" Command="{CMDCut}" /> <Button Style="IcoButton" Command="{CMDCopy}" /> <Button Style="IcoButton" Command="{CMDPaste}" />--> - <Popper IsVisible="{DebugLoggingEnabled}" Fit="true"> + <Popper RootDataLevel="true" IsVisible="{DebugLoggingEnabled}" Fit="true"> <Template> <CheckBox IsChecked="{²./IsPopped}"> <Template> @@ -103,41 +103,31 @@ <Label Text="Debug log output file:" Fit="true"/> <TextBox Text="{²DebugLogFilePath}" /> </HorizontalStack> - <EnumSelector RadioButtonStyle="CheckBox2" EnumValue="{²RecordedEvents}" Width="Stretched"> + <EnumSelector RadioButtonStyle="CheckBox2" EnumValue="{²RecordedEvents}" Width="Stretched" BitFieldExcludeMask="255" + Caption="Recorded Events"> <Template> <Popper > <Template> - <CheckBox IsChecked="{²./IsPopped}"> - <Template> - <HorizontalStack Background="Onyx" Margin="5" Spacing="10"> - <Label Text="Recorded Events:" Width="Stretched"/> - <Label Background="SeaGreen" Text="{RecordedEvents}" Margin="3"/> - </HorizontalStack> - </Template> - </CheckBox> - </Template> - <Scroller Height="50%" Width="80%" Background="Jet"> - <Wrapper Name="Content" Height="Fit" VerticalAlignment="Top" /> - </Scroller> + <HorizontalStack Background="{../../Background}" Margin="5" Spacing="10"> + <Label Text="{../../../Caption}" Width="Stretched"/> + <Label Background="SeaGreen" Text="{../../../EnumValue}" Margin="3"/> + </HorizontalStack> + </Template> + <Wrapper Name="Content" Height="Fit" Width="{../PopWidth}" Background="Jet" /> </Popper> </Template> </EnumSelector> - <EnumSelector RadioButtonStyle="CheckBox2" EnumValue="{²DiscardedEvents}" Width="Stretched"> + <EnumSelector RadioButtonStyle="CheckBox2" EnumValue="{²DiscardedEvents}" Width="Stretched" BitFieldExcludeMask="255" + Caption="Discarded Events"> <Template> <Popper > <Template> - <CheckBox IsChecked="{²./IsPopped}"> - <Template> - <HorizontalStack Background="Onyx" Margin="5" Spacing="10"> - <Label Text="Discarded Events:" Width="Stretched"/> - <Label Background="SeaGreen" Text="{DiscardedEvents}" Margin="3"/> - </HorizontalStack> - </Template> - </CheckBox> - </Template> - <Scroller Height="50%" Width="80%" Background="Jet"> - <Wrapper Name="Content" Height="Fit" VerticalAlignment="Top" /> - </Scroller> + <HorizontalStack Background="{../../Background}" Margin="5" Spacing="10"> + <Label Text="{../../../Caption}" Width="Stretched"/> + <Label Background="SeaGreen" Text="{../../../EnumValue}" Margin="3"/> + </HorizontalStack> + </Template> + <Wrapper Name="Content" Height="Fit" Width="{../PopWidth}" Background="Jet" /> </Popper> </Template> </EnumSelector> diff --git a/Samples/common/samples.style b/Samples/common/samples.style index 8a43f3a0..6f78b149 100644 --- a/Samples/common/samples.style +++ b/Samples/common/samples.style @@ -88,3 +88,25 @@ suggestionsListBox { Background = "Jet"; UseLoadingThread = "false"; } +allWidgetBackground = "DarkGrey"; +allWidgetCell { + Template = "Interfaces/grpBoxUnamed.tmp"; + Width = "20%"; + Background = "${allWidgetBackground}"; + MouseEnter = "{Background=Jet}"; + MouseLeave = "{Background=${allWidgetBackground}}"; +} +allWidgetNamedCell { + Template = "Interfaces/grpBox.tmp"; + Width = "20%"; + Background = "${allWidgetBackground}"; + MouseEnter = "{Background=Onyx}"; + MouseLeave = "{Background=${allWidgetBackground}}"; +} +allWidgetCell2 { + Template = "Interfaces/grpBox2.tmp"; + Width = "20%"; +} +allWidgetHS { + Width = "20%"; +} diff --git a/Samples/common/src/Editor.cs b/Samples/common/src/Editor.cs index 7b9d5c10..7b0f1f04 100644 --- a/Samples/common/src/Editor.cs +++ b/Samples/common/src/Editor.cs @@ -32,6 +32,7 @@ namespace Crow } ListBox overlay; IList suggestions; + volatile bool disableSuggestions; public IList Suggestions { get => suggestions; set { @@ -67,7 +68,8 @@ namespace Crow //Task.Run(()=>parse()); parse(); - if (HasFocus) + + if (!disableSuggestions && HasFocus) tryGetSuggestions (); //Console.WriteLine ($"{pos}: {suggestionTok.AsString (_text)} {suggestionTok}"); @@ -78,7 +80,6 @@ namespace Crow int pos = lines.GetAbsolutePosition (CurrentLoc.Value); currentToken = source.FindTokenIncludingPosition (pos); currentNode = source.FindNodeIncludingPosition (pos); - Console.WriteLine ($"Current Token: {currentToken} Current Node: {currentNode}"); if (currentToken.Type == TokenType.ElementOpen) { @@ -96,7 +97,10 @@ namespace Crow MemberInfo mi = getCrowTypeMember ( eltTag.NameToken.Value.AsString (_text), attribNode.NameToken.Value.AsString (_text)); if (mi is PropertyInfo pi) { - if (pi.PropertyType.IsEnum) + if (pi.Name == "Style") + Suggestions = IFace.Styling.Keys + .Where (s => s.StartsWith (currentToken.AsString (_text), StringComparison.OrdinalIgnoreCase)).ToList (); + else if (pi.PropertyType.IsEnum) Suggestions = Enum.GetNames (pi.PropertyType) .Where (s => s.StartsWith (currentToken.AsString (_text), StringComparison.OrdinalIgnoreCase)).ToList (); else if (pi.PropertyType == typeof(bool)) @@ -113,6 +117,8 @@ namespace Crow MemberInfo mi = getCrowTypeMember ( eltTag.NameToken.Value.AsString (_text), attribNode.NameToken.Value.AsString (_text)); if (mi is PropertyInfo pi) { + if (pi.Name == "Style") + Suggestions = IFace.Styling.Keys.ToList (); if (pi.PropertyType.IsEnum) Suggestions = Enum.GetNames (pi.PropertyType).ToList (); else if (pi.PropertyType == typeof(bool)) @@ -125,7 +131,7 @@ namespace Crow } } } - } + } } else if (currentToken.Type != TokenType.AttributeValueClose && currentToken.Type != TokenType.EmptyElementClosing && currentToken.Type != TokenType.ClosingSign && @@ -133,8 +139,8 @@ namespace Crow if (currentToken.Type == TokenType.AttributeName) Suggestions = getAllCrowTypeMembers (eltStartTag.NameToken.Value.AsString (_text)) .Where (s => s.Name.StartsWith (currentToken.AsString (_text), StringComparison.OrdinalIgnoreCase)).ToList (); - else - Suggestions = getAllCrowTypeMembers (eltStartTag.NameToken.Value.AsString (_text)).ToList (); + //else if (currentToken.Type == TokenType.ElementName) + // Suggestions = getAllCrowTypeMembers (eltStartTag.NameToken.Value.AsString (_text)).ToList (); } else { /*SyntaxNode curNode = source.FindNodeIncludingPosition (pos); Console.WriteLine ($"Current Node: {curNode}"); @@ -221,39 +227,42 @@ namespace Crow public override void onKeyDown(object sender, KeyEventArgs e) { - if (suggestionsActive) { - switch (e.Key) { - case Key.Escape: - hideOverlay (); - return; - case Key.Left: - case Key.Right: - hideOverlay (); - break; - case Key.End: - case Key.Home: - case Key.Down: - case Key.Up: - case Key.PageDown: - case Key.PageUp: - overlay.onKeyDown (this, e); - return; - case Key.Tab: - case Key.Enter: - case Key.KeypadEnter: - completeToken (); + TextSpan selection = Selection; + + if (SelectionIsEmpty) { + if (suggestionsActive) { + switch (e.Key) { + case Key.Escape: + hideOverlay (); + return; + case Key.Left: + case Key.Right: + hideOverlay (); + break; + case Key.End: + case Key.Home: + case Key.Down: + case Key.Up: + case Key.PageDown: + case Key.PageUp: + overlay.onKeyDown (this, e); + return; + case Key.Tab: + case Key.Enter: + case Key.KeypadEnter: + completeToken (); + return; + } + } else if (e.Key == Key.Space && IFace.Ctrl) { + tryGetSuggestions (); return; } - } else if (e.Key == Key.Space && IFace.Ctrl) { - tryGetSuggestions (); - return; - } - - TextSpan selection = Selection; - if (e.Key == Key.Tab && !selection.IsEmpty) { + } else if (e.Key == Key.Tab && !selection.IsEmpty) { int lineStart = lines.GetLocation (selection.Start).Line; int lineEnd = lines.GetLocation (selection.End).Line; + disableSuggestions = true; + if (IFace.Shift) { for (int l = lineStart; l <= lineEnd; l++) { if (Text[lines[l].Start] == '\t') @@ -270,13 +279,15 @@ namespace Crow for (int l = lineStart; l <= lineEnd; l++) update (new TextChange (lines[l].Start, 0, "\t")); } + + selectionStart = new CharLocation (lineStart, 0); + CurrentLoc = new CharLocation (lineEnd, lines[lineEnd].Length); - selectionStart = new CharLocation (lineStart, 0); - CurrentLoc = new CharLocation (lineEnd, lines[lineEnd].Length); + disableSuggestions = false; return; } - base.onKeyDown(sender, e); + base.onKeyDown(sender, e); } protected override void drawContent (Context gr) { diff --git a/Samples/common/src/ImlParsing/Syntax.cs b/Samples/common/src/ImlParsing/Syntax.cs index a38e1558..92c9eec3 100644 --- a/Samples/common/src/ImlParsing/Syntax.cs +++ b/Samples/common/src/ImlParsing/Syntax.cs @@ -236,7 +236,7 @@ namespace Crow public XmlSource Source => Root.source; public bool Contains (int pos) => EndToken.HasValue ? - StartToken.Start <= pos && EndToken.Value.End > pos : false; + StartToken.Start <= pos && EndToken.Value.End >= pos : false; public void Dump (int level = 0) { Console.WriteLine ($"{new string('\t', level)}{this}"); diff --git a/Samples/common/src/ImlParsing/TokenType.cs b/Samples/common/src/ImlParsing/TokenType.cs index 3289d5ae..baf25f32 100644 --- a/Samples/common/src/ImlParsing/TokenType.cs +++ b/Samples/common/src/ImlParsing/TokenType.cs @@ -24,17 +24,17 @@ namespace Crow Punctuation = 0x0400, PI_Start = 0x0401,// '<?' PI_End = 0x0402,// '?>' - Operator = 0x0800, - EqualSign = 0x0801, - AttributeValue = 0x2000, - AttributeValueOpen = 0x2001, - AttributeValueClose = 0x2002, - Keyword = 0x1000, ElementOpen = 0x0403,// '<' EndElementOpen = 0x0404,// '</' EmptyElementClosing = 0x0405,// '/>' ClosingSign = 0x0406,// '>' DTDObjectOpen = 0x04A0,// '<!' + Operator = 0x0800, + EqualSign = 0x0801, + Keyword = 0x1000, + AttributeValue = 0x2000, + AttributeValueOpen = 0x2001, + AttributeValueClose = 0x2002, Content, } }
\ No newline at end of file diff --git a/Samples/common/src/ImlParsing/XmlSource.cs b/Samples/common/src/ImlParsing/XmlSource.cs index 0942486f..86eb1e24 100644 --- a/Samples/common/src/ImlParsing/XmlSource.cs +++ b/Samples/common/src/ImlParsing/XmlSource.cs @@ -39,7 +39,7 @@ namespace Crow } public Token FindTokenIncludingPosition (int pos) { - if (tokens == null || tokens.Length == 0) + if (pos == 0 || tokens == null || tokens.Length == 0) return default; int idx = Array.BinarySearch (tokens, 0, tokens.Length, new Token () {Start = pos}); diff --git a/Samples/common/src/SampleBase.cs b/Samples/common/src/SampleBase.cs index 0c381048..75f998cd 100644 --- a/Samples/common/src/SampleBase.cs +++ b/Samples/common/src/SampleBase.cs @@ -44,17 +44,28 @@ namespace Samples public Version CrowVersion => Assembly.GetAssembly(typeof(Widget)).GetName().Version; + static void showMsgBox (object sender) { + Widget w = sender as Widget; + Command cmd = w.DataSource as Command; + MessageBox.ShowModal(w.IFace, MessageBox.Type.Information, $"{cmd.Caption} CLICKED"); + } + #region Test values for Binding public CommandGroup Commands, AllCommands; public CommandGroup EditCommands = new CommandGroup("Edit Commands", - new Command("Edit command 1", (sender) => MessageBox.ShowModal((sender as Widget).IFace, MessageBox.Type.Information, "Edit comand 1 clicked")), - new Command("Edit command 2 a bit longer", (sender) => MessageBox.ShowModal((sender as Widget).IFace, MessageBox.Type.Information, "Edit comand 2 clicked"), null, false), - new Command("Edit command three", (sender) => MessageBox.ShowModal((sender as Widget).IFace, MessageBox.Type.Information, "Edit comand 3 clicked")) + new Command("Edit command 1", (sender) => showMsgBox (sender)), + new Command("Edit command 2 a bit longer", (sender) => showMsgBox (sender), null, false), + new Command("Edit command three", (sender) => showMsgBox (sender)), + new CommandGroup("Subedit menu", + new Command("Subedit command 1", (sender) => showMsgBox (sender)), + new Command("Subedit command 2 a bit longer", (sender) => showMsgBox (sender), null, false), + new Command("Subedit command three", (sender) => showMsgBox (sender)) + ) ); public CommandGroup FileCommands = new CommandGroup("File Commands", - new Command("File command 1", (sender) => MessageBox.ShowModal((sender as Widget).IFace, MessageBox.Type.Information, "File comand 1 clicked")), - new Command("File command 2 a bit longer", (sender) => MessageBox.ShowModal((sender as Widget).IFace, MessageBox.Type.Information, "File comand 2 clicked")), - new Command("File command three", (sender) => MessageBox.ShowModal((sender as Widget).IFace, MessageBox.Type.Information, "File comand 3 clicked")) + new Command("File command 1", (sender) => showMsgBox (sender)), + new Command("File command 2 a bit longer", (sender) => showMsgBox (sender)), + new Command("File command three", (sender) => showMsgBox (sender)) ); void initCommands() @@ -323,29 +334,38 @@ namespace Samples string curSources = ""; + bool boolVal = true; public string CurSources { - get { return curSources; } - set - { + get => curSources; + set { if (value == curSources) return; curSources = value; NotifyValueChanged(curSources); } } - bool boolVal = true; public bool BoolVal { - get { return boolVal; } - set - { + get => boolVal; + set { if (boolVal == value) return; boolVal = value; NotifyValueChanged(boolVal); } } + public Color AllWidgetBackground { + get => Configuration.Global.Get<Color> (nameof(AllWidgetBackground)); + set { + if (value == AllWidgetBackground) + return; + Configuration.Global.Set (nameof(AllWidgetBackground), value); + NotifyValueChanged (value); + } + } + + diff --git a/Samples/common/src/SampleBaseForEditor.cs b/Samples/common/src/SampleBaseForEditor.cs index 54ad8777..6c6b60b8 100644 --- a/Samples/common/src/SampleBaseForEditor.cs +++ b/Samples/common/src/SampleBaseForEditor.cs @@ -101,13 +101,23 @@ namespace Samples public bool DebugLogToFile { get => Configuration.Global.Get<bool> (nameof(DebugLogToFile)); set { - if (DebugLogToFile != value) + if (DebugLogToFile == value) return; Configuration.Global.Set (nameof(DebugLogToFile), value); NotifyValueChanged(DebugLogToFile); DbgLogger.ConsoleOutput = !value; } } + public string DebugLogFilePath { + get => Configuration.Global.Get<string> (nameof (DebugLogFilePath)); + set { + if (CurrentFile == value) + return; + Configuration.Global.Set (nameof (DebugLogFilePath), value); + NotifyValueChanged (DebugLogFilePath); + } + } + protected static void initDebugLog () { DbgLogger.IncludeEvents = DbgEvtType.None; DbgLogger.DiscardEvents = DbgEvtType.All; @@ -279,6 +289,8 @@ namespace Samples } public void goUpDirClick (object sender, MouseButtonEventArgs e) { + if (string.IsNullOrEmpty (CurrentDir)) + return; string root = Directory.GetDirectoryRoot (CurrentDir); if (CurrentDir == root) return; diff --git a/Samples/common/ui/Interfaces/Divers/2.crow b/Samples/common/ui/Interfaces/Divers/2.crow index a1896248..885c3ba0 100644 --- a/Samples/common/ui/Interfaces/Divers/2.crow +++ b/Samples/common/ui/Interfaces/Divers/2.crow @@ -1,9 +1,9 @@ <?xml version="1.0"?> -<VerticalStack Fit="true"> - <TextBox Font="droid, 20" Text="test text box" Width="Stretched"/> - <HorizontalStack Margin="5" Fit="true" MouseEnter="{Background=White}" MouseLeave="{Background=Transparent}"> - <Label Focusable="true" Text="left" Width="80" Height="30" Background="DarkBlue" TextAlignment="Left"/> - <Label Focusable="true" Text="centered" Width="80" Height="30" Background="DarkBlue" TextAlignment="Center"/> - <Label Focusable="true" Text="right" Width="80" Height="30" Background="DarkBlue" TextAlignment="Right"/> +<VerticalStack Fit="true" Spacing="0"> + <TextBox Font="droid, 20" Text="multiline text box" Width="Stretched" Multiline="true"/> + <HorizontalStack Background="DarkSlateGrey" Margin="15" Spacing="15" Fit="true" MouseEnter="{Background=Jet}" MouseLeave="{Background=Grey}"> + <TextBox Focusable="true" Text="left" Width="80" Height="30" TextAlignment="Left"/> + <TextBox Focusable="true" Text="centered" Width="80" Height="30" TextAlignment="Center"/> + <TextBox Focusable="true" Text="right" Width="80" Height="30" TextAlignment="Right"/> </HorizontalStack> </VerticalStack>
\ No newline at end of file diff --git a/Samples/common/ui/Interfaces/Divers/3.crow b/Samples/common/ui/Interfaces/Divers/3.crow deleted file mode 100644 index a1f5e95d..00000000 --- a/Samples/common/ui/Interfaces/Divers/3.crow +++ /dev/null @@ -1,377 +0,0 @@ -<?xml version="1.0"?> -<HorizontalStack Fit="true"> - <VerticalStack Fit="true" Name="vsFps" Spacing="10" > - <ProgressBar CornerRadius="5" Background="DimGrey" Margin="1" Maximum="1000" Value="{fps}" Width="200" Height="15"/> - <HorizontalStack Fit="true"> - <Label Text="Memory:" Width="50" TextAlignment="Right"/> - <Label Text="{memory}" Font="droid,12" TextAlignment="Center" - Background="vgradient|0:RoyalBlue|1:Black"/> - </HorizontalStack> - <HorizontalStack Fit="true"> - <Label Text="Update:" Width="50" TextAlignment="Right"/> - <Label Name="labUpdate" Text="{update}" Font="droid,12" Width="80" TextAlignment="Center" - Background="vgradient|0:SeaGreen|1:Black"/> - </HorizontalStack> - <HorizontalStack Fit="true"> - <Label Text="Layouting:" Width="50" TextAlignment="Right"/> - <Label Name="labLayouting" Text="{layouting}" Font="droid,12" Width="80" TextAlignment="Center" - Background="vgradient|0:SeaGreen|1:Black"/> - </HorizontalStack> - <HorizontalStack Fit="true"> - <Label Text="Drawing:" Width="50" TextAlignment="Right"/> - <Label Name="labDrawing" Text="{drawing}" Font="droid,12" Width="80" TextAlignment="Center" - Background="vgradient|0:SeaGreen|1:Black"/> - </HorizontalStack> - <HorizontalStack Fit="true"> - <Label Name="captionFps" Text="Fps:" Width="50" TextAlignment="Right"/> - <Label Name="valueFps" Text="{fps}" Font="droid , 12" Width="50" TextAlignment="Center" - Background="vgradient|0:SeaGreen|1:Black"/> - </HorizontalStack> - <HorizontalStack Fit="true"> - <Label Text="Min:" Width="50" TextAlignment="Right"/> - <Label Text="{fpsMin}" Font="droid , 12" Width="50" TextAlignment="Center" - Background="vgradient|0:SeaGreen|1:Black"/> - </HorizontalStack> - <HorizontalStack Fit="true"> - <Label Text="Max:" Width="50" TextAlignment="Right"/> - <Label Text="{fpsMax}" Font="droid , 12" Width="50" TextAlignment="Center" - Background="vgradient|0:SeaGreen|1:Black"/> - </HorizontalStack> - <HorizontalStack Fit="true"> - <Label Text="Update:" Width="50" TextAlignment="Right"/> - <Label Name="labUpdate" Text="{update}" Font="droid,12" Width="80" TextAlignment="Center" - Background="vgradient|0:SeaGreen|1:Black"/> - </HorizontalStack> - <HorizontalStack Fit="true"> - <Label Text="Layouting:" Width="50" TextAlignment="Right"/> - <Label Name="labLayouting" Text="{layouting}" Font="droid,12" Width="80" TextAlignment="Center" - Background="vgradient|0:SeaGreen|1:Black"/> - </HorizontalStack> - <HorizontalStack Fit="true"> - <Label Text="Drawing:" Width="50" TextAlignment="Right"/> - <Label Name="labDrawing" Text="{drawing}" Font="droid,12" Width="80" TextAlignment="Center" - Background="vgradient|0:SeaGreen|1:Black"/> - </HorizontalStack> - <HorizontalStack Fit="true"> - <Label Name="captionFps" Text="Fps:" Width="50" TextAlignment="Right"/> - <Label Name="valueFps" Text="{fps}" Font="droid , 12" Width="50" TextAlignment="Center" - Background="vgradient|0:SeaGreen|1:Black"/> - </HorizontalStack> - <HorizontalStack Fit="true"> - <Label Text="Min:" Width="50" TextAlignment="Right"/> - <Label Text="{fpsMin}" Font="droid , 12" Width="50" TextAlignment="Center" - Background="vgradient|0:SeaGreen|1:Black"/> - </HorizontalStack> - <HorizontalStack Fit="true"> - <Label Text="Max:" Width="50" TextAlignment="Right"/> - <Label Text="{fpsMax}" Font="droid , 12" Width="50" TextAlignment="Center" - Background="vgradient|0:SeaGreen|1:Black"/> - </HorizontalStack> - <HorizontalStack Fit="true"> - <Label Text="Update:" Width="50" TextAlignment="Right"/> - <Label Name="labUpdate" Text="{update}" Font="droid,12" Width="80" TextAlignment="Center" - Background="vgradient|0:SeaGreen|1:Black"/> - </HorizontalStack> - <HorizontalStack Fit="true"> - <Label Text="Layouting:" Width="50" TextAlignment="Right"/> - <Label Name="labLayouting" Text="{layouting}" Font="droid,12" Width="80" TextAlignment="Center" - Background="vgradient|0:SeaGreen|1:Black"/> - </HorizontalStack> - <HorizontalStack Fit="true"> - <Label Text="Drawing:" Width="50" TextAlignment="Right"/> - <Label Name="labDrawing" Text="{drawing}" Font="droid,12" Width="80" TextAlignment="Center" - Background="vgradient|0:SeaGreen|1:Black"/> - </HorizontalStack> - <HorizontalStack Fit="true"> - <Label Name="captionFps" Text="Fps:" Width="50" TextAlignment="Right"/> - <Label Name="valueFps" Text="{fps}" Font="droid , 12" Width="50" TextAlignment="Center" - Background="vgradient|0:SeaGreen|1:Black"/> - </HorizontalStack> - <HorizontalStack Fit="true"> - <Label Text="Min:" Width="50" TextAlignment="Right"/> - <Label Text="{fpsMin}" Font="droid , 12" Width="50" TextAlignment="Center" - Background="vgradient|0:SeaGreen|1:Black"/> - </HorizontalStack> - <HorizontalStack Fit="true"> - <Label Text="Max:" Width="50" TextAlignment="Right"/> - <Label Text="{fpsMax}" Font="droid , 12" Width="50" TextAlignment="Center" - Background="vgradient|0:SeaGreen|1:Black"/> - </HorizontalStack> - </VerticalStack> - <VerticalStack Fit="true" Name="vsFps" Spacing="10" > - <HorizontalStack Fit="true"> - <Label Text="Update:" Width="50" TextAlignment="Right"/> - <Label Name="labUpdate" Text="{update}" Font="droid,12" Width="80" TextAlignment="Center" - Background="vgradient|0:SeaGreen|1:Black"/> - </HorizontalStack> - <HorizontalStack Fit="true"> - <Label Text="Layouting:" Width="50" TextAlignment="Right"/> - <Label Name="labLayouting" Text="{layouting}" Font="droid,12" Width="80" TextAlignment="Center" - Background="vgradient|0:SeaGreen|1:Black"/> - </HorizontalStack> - <HorizontalStack Fit="true"> - <Label Text="Drawing:" Width="50" TextAlignment="Right"/> - <Label Name="labDrawing" Text="{drawing}" Font="droid,12" Width="80" TextAlignment="Center" - Background="vgradient|0:SeaGreen|1:Black"/> - </HorizontalStack> - <HorizontalStack Fit="true"> - <Label Name="captionFps" Text="Fps:" Width="50" TextAlignment="Right"/> - <Label Name="valueFps" Text="{fps}" Font="droid , 12" Width="50" TextAlignment="Center" - Background="vgradient|0:SeaGreen|1:Black"/> - </HorizontalStack> - <HorizontalStack Fit="true"> - <Label Text="Min:" Width="50" TextAlignment="Right"/> - <Label Text="{fpsMin}" Font="droid , 12" Width="50" TextAlignment="Center" - Background="vgradient|0:SeaGreen|1:Black"/> - </HorizontalStack> - <HorizontalStack Fit="true"> - <Label Text="Max:" Width="50" TextAlignment="Right"/> - <Label Text="{fpsMax}" Font="droid , 12" Width="50" TextAlignment="Center" - Background="vgradient|0:SeaGreen|1:Black"/> - </HorizontalStack> - <HorizontalStack Fit="true"> - <Label Text="Update:" Width="50" TextAlignment="Right"/> - <Label Name="labUpdate" Text="{update}" Font="droid,12" Width="80" TextAlignment="Center" - Background="vgradient|0:SeaGreen|1:Black"/> - </HorizontalStack> - <HorizontalStack Fit="true"> - <Label Text="Layouting:" Width="50" TextAlignment="Right"/> - <Label Name="labLayouting" Text="{layouting}" Font="droid,12" Width="80" TextAlignment="Center" - Background="vgradient|0:SeaGreen|1:Black"/> - </HorizontalStack> - <HorizontalStack Fit="true"> - <Label Text="Drawing:" Width="50" TextAlignment="Right"/> - <Label Name="labDrawing" Text="{drawing}" Font="droid,12" Width="80" TextAlignment="Center" - Background="vgradient|0:SeaGreen|1:Black"/> - </HorizontalStack> - <HorizontalStack Fit="true"> - <Label Name="captionFps" Text="Fps:" Width="50" TextAlignment="Right"/> - <Label Name="valueFps" Text="{fps}" Font="droid , 12" Width="50" TextAlignment="Center" - Background="vgradient|0:SeaGreen|1:Black"/> - </HorizontalStack> - <HorizontalStack Fit="true"> - <Label Text="Min:" Width="50" TextAlignment="Right"/> - <Label Text="{fpsMin}" Font="droid , 12" Width="50" TextAlignment="Center" - Background="vgradient|0:SeaGreen|1:Black"/> - </HorizontalStack> - <HorizontalStack Fit="true"> - <Label Text="Max:" Width="50" TextAlignment="Right"/> - <Label Text="{fpsMax}" Font="droid , 12" Width="50" TextAlignment="Center" - Background="vgradient|0:SeaGreen|1:Black"/> - </HorizontalStack> - <HorizontalStack Fit="true"> - <Label Text="Update:" Width="50" TextAlignment="Right"/> - <Label Name="labUpdate" Text="{update}" Font="droid,12" Width="80" TextAlignment="Center" - Background="vgradient|0:SeaGreen|1:Black"/> - </HorizontalStack> - <HorizontalStack Fit="true"> - <Label Text="Layouting:" Width="50" TextAlignment="Right"/> - <Label Name="labLayouting" Text="{layouting}" Font="droid,12" Width="80" TextAlignment="Center" - Background="vgradient|0:SeaGreen|1:Black"/> - </HorizontalStack> - <HorizontalStack Fit="true"> - <Label Text="Drawing:" Width="50" TextAlignment="Right"/> - <Label Name="labDrawing" Text="{drawing}" Font="droid,12" Width="80" TextAlignment="Center" - Background="vgradient|0:SeaGreen|1:Black"/> - </HorizontalStack> - <HorizontalStack Fit="true"> - <Label Name="captionFps" Text="Fps:" Width="50" TextAlignment="Right"/> - <Label Name="valueFps" Text="{fps}" Font="droid , 12" Width="50" TextAlignment="Center" - Background="vgradient|0:SeaGreen|1:Black"/> - </HorizontalStack> - <HorizontalStack Fit="true"> - <Label Text="Min:" Width="50" TextAlignment="Right"/> - <Label Text="{fpsMin}" Font="droid , 12" Width="50" TextAlignment="Center" - Background="vgradient|0:SeaGreen|1:Black"/> - </HorizontalStack> - <HorizontalStack Fit="true"> - <Label Text="Max:" Width="50" TextAlignment="Right"/> - <Label Text="{fpsMax}" Font="droid , 12" Width="50" TextAlignment="Center" - Background="vgradient|0:SeaGreen|1:Black"/> - </HorizontalStack> - </VerticalStack> - <VerticalStack Fit="true" Name="vsFps" Spacing="10" > - <HorizontalStack Fit="true"> - <Label Text="Update:" Width="50" TextAlignment="Right"/> - <Label Name="labUpdate" Text="{update}" Font="droid,12" Width="80" TextAlignment="Center" - Background="vgradient|0:SeaGreen|1:Black"/> - </HorizontalStack> - <HorizontalStack Fit="true"> - <Label Text="Layouting:" Width="50" TextAlignment="Right"/> - <Label Name="labLayouting" Text="{layouting}" Font="droid,12" Width="80" TextAlignment="Center" - Background="vgradient|0:SeaGreen|1:Black"/> - </HorizontalStack> - <HorizontalStack Fit="true"> - <Label Text="Drawing:" Width="50" TextAlignment="Right"/> - <Label Name="labDrawing" Text="{drawing}" Font="droid,12" Width="80" TextAlignment="Center" - Background="vgradient|0:SeaGreen|1:Black"/> - </HorizontalStack> - <HorizontalStack Fit="true"> - <Label Name="captionFps" Text="Fps:" Width="50" TextAlignment="Right"/> - <Label Name="valueFps" Text="{fps}" Font="droid , 12" Width="50" TextAlignment="Center" - Background="vgradient|0:SeaGreen|1:Black"/> - </HorizontalStack> - <HorizontalStack Fit="true"> - <Label Text="Min:" Width="50" TextAlignment="Right"/> - <Label Text="{fpsMin}" Font="droid , 12" Width="50" TextAlignment="Center" - Background="vgradient|0:SeaGreen|1:Black"/> - </HorizontalStack> - <HorizontalStack Fit="true"> - <Label Text="Max:" Width="50" TextAlignment="Right"/> - <Label Text="{fpsMax}" Font="droid , 12" Width="50" TextAlignment="Center" - Background="vgradient|0:SeaGreen|1:Black"/> - </HorizontalStack> - <HorizontalStack Fit="true"> - <Label Text="Update:" Width="50" TextAlignment="Right"/> - <Label Name="labUpdate" Text="{update}" Font="droid,12" Width="80" TextAlignment="Center" - Background="vgradient|0:SeaGreen|1:Black"/> - </HorizontalStack> - <HorizontalStack Fit="true"> - <Label Text="Layouting:" Width="50" TextAlignment="Right"/> - <Label Name="labLayouting" Text="{layouting}" Font="droid,12" Width="80" TextAlignment="Center" - Background="vgradient|0:SeaGreen|1:Black"/> - </HorizontalStack> - <HorizontalStack Fit="true"> - <Label Text="Drawing:" Width="50" TextAlignment="Right"/> - <Label Name="labDrawing" Text="{drawing}" Font="droid,12" Width="80" TextAlignment="Center" - Background="vgradient|0:SeaGreen|1:Black"/> - </HorizontalStack> - <HorizontalStack Fit="true"> - <Label Name="captionFps" Text="Fps:" Width="50" TextAlignment="Right"/> - <Label Name="valueFps" Text="{fps}" Font="droid , 12" Width="50" TextAlignment="Center" - Background="vgradient|0:SeaGreen|1:Black"/> - </HorizontalStack> - <HorizontalStack Fit="true"> - <Label Text="Min:" Width="50" TextAlignment="Right"/> - <Label Text="{fpsMin}" Font="droid , 12" Width="50" TextAlignment="Center" - Background="vgradient|0:SeaGreen|1:Black"/> - </HorizontalStack> - <HorizontalStack Fit="true"> - <Label Text="Max:" Width="50" TextAlignment="Right"/> - <Label Text="{fpsMax}" Font="droid , 12" Width="50" TextAlignment="Center" - Background="vgradient|0:SeaGreen|1:Black"/> - </HorizontalStack> - <HorizontalStack Fit="true"> - <Label Text="Update:" Width="50" TextAlignment="Right"/> - <Label Name="labUpdate" Text="{update}" Font="droid,12" Width="80" TextAlignment="Center" - Background="vgradient|0:SeaGreen|1:Black"/> - </HorizontalStack> - <HorizontalStack Fit="true"> - <Label Text="Layouting:" Width="50" TextAlignment="Right"/> - <Label Name="labLayouting" Text="{layouting}" Font="droid,12" Width="80" TextAlignment="Center" - Background="vgradient|0:SeaGreen|1:Black"/> - </HorizontalStack> - <HorizontalStack Fit="true"> - <Label Text="Drawing:" Width="50" TextAlignment="Right"/> - <Label Name="labDrawing" Text="{drawing}" Font="droid,12" Width="80" TextAlignment="Center" - Background="vgradient|0:SeaGreen|1:Black"/> - </HorizontalStack> - <HorizontalStack Fit="true"> - <Label Name="captionFps" Text="Fps:" Width="50" TextAlignment="Right"/> - <Label Name="valueFps" Text="{fps}" Font="droid , 12" Width="50" TextAlignment="Center" - Background="vgradient|0:SeaGreen|1:Black"/> - </HorizontalStack> - <HorizontalStack Fit="true"> - <Label Text="Min:" Width="50" TextAlignment="Right"/> - <Label Text="{fpsMin}" Font="droid , 12" Width="50" TextAlignment="Center" - Background="vgradient|0:SeaGreen|1:Black"/> - </HorizontalStack> - <HorizontalStack Fit="true"> - <Label Text="Max:" Width="50" TextAlignment="Right"/> - <Label Text="{fpsMax}" Font="droid , 12" Width="50" TextAlignment="Center" - Background="vgradient|0:SeaGreen|1:Black"/> - </HorizontalStack> - </VerticalStack> - <VerticalStack Fit="true" Name="vsFps" Spacing="10" > - <HorizontalStack Fit="true"> - <Label Text="Update:" Width="50" TextAlignment="Right"/> - <Label Name="labUpdate" Text="{update}" Font="droid,12" Width="80" TextAlignment="Center" - Background="vgradient|0:SeaGreen|1:Black"/> - </HorizontalStack> - <HorizontalStack Fit="true"> - <Label Text="Layouting:" Width="50" TextAlignment="Right"/> - <Label Name="labLayouting" Text="{layouting}" Font="droid,12" Width="80" TextAlignment="Center" - Background="vgradient|0:SeaGreen|1:Black"/> - </HorizontalStack> - <HorizontalStack Fit="true"> - <Label Text="Drawing:" Width="50" TextAlignment="Right"/> - <Label Name="labDrawing" Text="{drawing}" Font="droid,12" Width="80" TextAlignment="Center" - Background="vgradient|0:SeaGreen|1:Black"/> - </HorizontalStack> - <HorizontalStack Fit="true"> - <Label Name="captionFps" Text="Fps:" Width="50" TextAlignment="Right"/> - <Label Name="valueFps" Text="{fps}" Font="droid , 12" Width="50" TextAlignment="Center" - Background="vgradient|0:SeaGreen|1:Black"/> - </HorizontalStack> - <HorizontalStack Fit="true"> - <Label Text="Min:" Width="50" TextAlignment="Right"/> - <Label Text="{fpsMin}" Font="droid , 12" Width="50" TextAlignment="Center" - Background="vgradient|0:SeaGreen|1:Black"/> - </HorizontalStack> - <HorizontalStack Fit="true"> - <Label Text="Max:" Width="50" TextAlignment="Right"/> - <Label Text="{fpsMax}" Font="droid , 12" Width="50" TextAlignment="Center" - Background="vgradient|0:SeaGreen|1:Black"/> - </HorizontalStack> - <HorizontalStack Fit="true"> - <Label Text="Update:" Width="50" TextAlignment="Right"/> - <Label Name="labUpdate" Text="{update}" Font="droid,12" Width="80" TextAlignment="Center" - Background="vgradient|0:SeaGreen|1:Black"/> - </HorizontalStack> - <HorizontalStack Fit="true"> - <Label Text="Layouting:" Width="50" TextAlignment="Right"/> - <Label Name="labLayouting" Text="{layouting}" Font="droid,12" Width="80" TextAlignment="Center" - Background="vgradient|0:SeaGreen|1:Black"/> - </HorizontalStack> - <HorizontalStack Fit="true"> - <Label Text="Drawing:" Width="50" TextAlignment="Right"/> - <Label Name="labDrawing" Text="{drawing}" Font="droid,12" Width="80" TextAlignment="Center" - Background="vgradient|0:SeaGreen|1:Black"/> - </HorizontalStack> - <HorizontalStack Fit="true"> - <Label Name="captionFps" Text="Fps:" Width="50" TextAlignment="Right"/> - <Label Name="valueFps" Text="{fps}" Font="droid , 12" Width="50" TextAlignment="Center" - Background="vgradient|0:SeaGreen|1:Black"/> - </HorizontalStack> - <HorizontalStack Fit="true"> - <Label Text="Min:" Width="50" TextAlignment="Right"/> - <Label Text="{fpsMin}" Font="droid , 12" Width="50" TextAlignment="Center" - Background="vgradient|0:SeaGreen|1:Black"/> - </HorizontalStack> - <HorizontalStack Fit="true"> - <Label Text="Max:" Width="50" TextAlignment="Right"/> - <Label Text="{fpsMax}" Font="droid , 12" Width="50" TextAlignment="Center" - Background="vgradient|0:SeaGreen|1:Black"/> - </HorizontalStack> - <HorizontalStack Fit="true"> - <Label Text="Update:" Width="50" TextAlignment="Right"/> - <Label Name="labUpdate" Text="{update}" Font="droid,12" Width="80" TextAlignment="Center" - Background="vgradient|0:SeaGreen|1:Black"/> - </HorizontalStack> - <HorizontalStack Fit="true"> - <Label Text="Layouting:" Width="50" TextAlignment="Right"/> - <Label Name="labLayouting" Text="{layouting}" Font="droid,12" Width="80" TextAlignment="Center" - Background="vgradient|0:SeaGreen|1:Black"/> - </HorizontalStack> - <HorizontalStack Fit="true"> - <Label Text="Drawing:" Width="50" TextAlignment="Right"/> - <Label Name="labDrawing" Text="{drawing}" Font="droid,12" Width="80" TextAlignment="Center" - Background="vgradient|0:SeaGreen|1:Black"/> - </HorizontalStack> - <HorizontalStack Fit="true"> - <Label Name="captionFps" Text="Fps:" Width="50" TextAlignment="Right"/> - <Label Name="valueFps" Text="{fps}" Font="droid , 12" Width="50" TextAlignment="Center" - Background="vgradient|0:SeaGreen|1:Black"/> - </HorizontalStack> - <HorizontalStack Fit="true"> - <Label Text="Min:" Width="50" TextAlignment="Right"/> - <Label Text="{fpsMin}" Font="droid , 12" Width="50" TextAlignment="Center" - Background="vgradient|0:SeaGreen|1:Black"/> - </HorizontalStack> - <HorizontalStack Fit="true"> - <Label Text="Max:" Width="50" TextAlignment="Right"/> - <Label Text="{fpsMax}" Font="droid , 12" Width="50" TextAlignment="Center" - Background="vgradient|0:SeaGreen|1:Black"/> - </HorizontalStack> - </VerticalStack> -</HorizontalStack>
\ No newline at end of file diff --git a/Samples/common/ui/Interfaces/Divers/5.crow b/Samples/common/ui/Interfaces/Divers/5.crow deleted file mode 100644 index 7e3df064..00000000 --- a/Samples/common/ui/Interfaces/Divers/5.crow +++ /dev/null @@ -1,64 +0,0 @@ -<?xml version="1.0"?> -<HorizontalStack Fit="true" Margin="5"> - <VerticalStack Fit="true" Margin="2" Spacing="2"> - <TextRun Text="text run test"/> -<!-- <Label Text="label test"/> - <TextBox Text="text box test"/> - <Button Caption="test button"/>--> -<!-- <CheckBox Caption="test checkbox"/> - <RadioButton Caption="test radiobutton"/> - <ComboBox/> - <Popper Caption="test popper"> - <Label Text="label test"/> - </Popper> - <Expandable Caption="test expandable"> - <Label Text="label test"/> - </Expandable> - <Border > - <Label Text="border test" Margin="3"/> - </Border> - <GroupBox Caption="Group box" > - <Label Text="border test" Margin="3"/> - </GroupBox> - <Container Fit="true" Background="DimGrey" Margin="3"> - <Widget Width="20" Height="20" Background="LightGrey"/> - </Container>--> -<!-- <ProgressBar Height="10" Width="150" Background="DimGrey" Value="50" /> - <Slider Value="5" Width="150" Height="10"/> - <ScrollBar Orientation="Horizontal" Maximum="100" Value="50" Height="16" Width="150"/> - <Spinner Value="100"/>--> - </VerticalStack> -<!-- <VerticalStack Width="150" Height="Fit" Margin="2" Spacing="2"> - <TextRun Text="text run test" Width="Stretched"/> - <Label Text="label test" Width="Stretched"/> - <TextBox Text="text box test" Width="Stretched"/> - <Button Caption="test button" Width="Stretched"/> - <CheckBox Caption="test checkbox" Width="Stretched"/> - <RadioButton Caption="test radiobutton" Width="Stretched"/> - <ComboBox Width="Stretched"/> - <Popper Caption="test popper" Width="Stretched"> - <Label Text="label test"/> - </Popper> - <Expandable Caption="test expandable" Width="Stretched"> - <Label Text="label test"/> - </Expandable> - <Border Width="Stretched"> - <Label Text="border test" Margin="3"/> - </Border> - <GroupBox Caption="Group box" Width="Stretched"> - <Label Text="border test" Margin="3"/> - </GroupBox> - <Container Height="Fit" Width="Stretched" Background="DimGrey" Margin="3"> - <Widget Width="20" Height="20" Background="LightGrey"/> - </Container> - <ProgressBar Height="10" Width="Stretched" Background="DimGrey" Value="50" /> - <Slider Value="5" Width="Stretched" Height="10"/> - <ScrollBar Orientation="Horizontal" Maximum="100" Value="50" Height="16" Width="Stretched"/> - <Spinner Value="100" Width="Stretched"/> - </VerticalStack>--> -</HorizontalStack> -<!--<HorizontalStack Fit="true" Background="RoyalBlue" Margin="5"> - <Widget Background="Red" Width="30" Height="20"/> - <Spinner Maximum="10000000000" SmallIncrement="10" Value="0"/> - <Widget Background="Green" Width="30" Height="20"/> -</HorizontalStack>-->
\ No newline at end of file diff --git a/Samples/common/ui/Interfaces/Divers/6.crow b/Samples/common/ui/Interfaces/Divers/6.crow deleted file mode 100644 index f537a71d..00000000 --- a/Samples/common/ui/Interfaces/Divers/6.crow +++ /dev/null @@ -1,6 +0,0 @@ -<?xml version="1.0"?> -<VerticalStack Fit="true" Background="DimGrey" Margin="5"> -<!-- <RadioButton/>--> - <Label Text="a" Width="Stretched" Background="Red"/> - <Label Text="{fps}" HorizontalAlignment="Right" Background="LimeGreen"/> -</VerticalStack> diff --git a/Samples/common/ui/Interfaces/Divers/chess.crow b/Samples/common/ui/Interfaces/Divers/chess.crow deleted file mode 100644 index 30b86d46..00000000 --- a/Samples/common/ui/Interfaces/Divers/chess.crow +++ /dev/null @@ -1,19 +0,0 @@ -<?xml version="1.0"?> -<HorizontalStack Height="Fit" Background="vgradient|0:Grey|0.3:Jet|0.7:Jet|1:Black" VerticalAlignment="Bottom" Margin="10"> - <CheckBox Caption="Hint" IsChecked="{²EnableHint}"/> - <Button Caption="Undo" MouseClick="onUndoClick"/> - <Button Caption="N" MouseClick="onNewGameClick"/> - <Button Caption="Options" MouseClick="onOptionsClick"/> - <Widget Width="Stretched" Height="1"/> - <Button Caption="Quit" MouseClick="onQuitClick"/> - <VerticalStack Style="hsStatus" > - <Label Style="labStatus" Text="State:"/> - <Label Style="labStatus2" Text="{CurrentState}" /> - </VerticalStack > - <VerticalStack Style="hsStatus" > - <Label Style="labStatus" Text="Hover:"/> - <Label Style="labStatus2" Text="{SelCell}"/> - </VerticalStack> - <Image Width="30" Height="20" Path="#Crow.Icons.IconAlerte.svg" Visible="{StockfishNotFound}"/> - <Label Text="Stockfish not found" Font="droid bold, 10" Visible="{StockfishNotFound}"/> -</HorizontalStack> diff --git a/Samples/common/ui/Interfaces/Divers/circleMeter.crow b/Samples/common/ui/Interfaces/Divers/circleMeter.crow new file mode 100644 index 00000000..07c9d6e5 --- /dev/null +++ b/Samples/common/ui/Interfaces/Divers/circleMeter.crow @@ -0,0 +1,18 @@ +<VerticalStack Background="DarkGrey" Margin="10"> + <Wrapper Height="Fit"> + <Spinner Template="#ui.spinner.template" Caption="Min" Value="{²../../sld.Minimum}" Width="Fit"/> + <Spinner Template="#ui.spinner.template" Caption="Max" Value="{²../../sld.Maximum}" Width="Fit"/> + <Spinner Template="#ui.spinner.template" Caption="Value" Value="{²../../sld.Value}" + Minimum="{../../sld.Minimum}" Maximum="{../../sld.Maximum}" Width="Fit"/> + <Spinner Name="sa" Template="#ui.spinner.template" Caption="Start Angle" Value="{²../../cm.StartAngle}" Width="Fit" Maximum="360"/> + <Spinner Name="ea" Template="#ui.spinner.template" Caption="End Angle" Value="{²../../cm.EndAngle}" Width="Fit" Maximum="360"/> + <Spinner Template="#ui.spinner.template" Caption="Backline width" Value="{²../../cm.BackgroundLineWidth}" Width="Fit" Minimum="1"/> + <Spinner Template="#ui.spinner.template" Caption="Line width" Value="{²../../cm.LineWidth}" Width="Fit" Minimum="1"/> + </Wrapper> + <Slider Name="sld" Background="Onyx" Value="30"/> + <Group Background="DimGrey"> + <CircleMeter Name="cm" Background="Onyx" Foreground="RoyalBlue" Margin="20" + Value="{../../sld.Value}" Minimum="{../../sld.Minimum}" Maximum="{../../sld.Maximum}"/> + <Label Text="{../cm.Value}" Font="consola bold, 40" /> + </Group> +</VerticalStack>
\ No newline at end of file diff --git a/Samples/common/ui/Interfaces/Divers/colorPicker.crow b/Samples/common/ui/Interfaces/Divers/colorPicker.crow index f7e9a0bc..dc4a6abe 100644 --- a/Samples/common/ui/Interfaces/Divers/colorPicker.crow +++ b/Samples/common/ui/Interfaces/Divers/colorPicker.crow @@ -2,6 +2,6 @@ <VerticalStack> <ColorPicker CurrentColor="{²../go.Background}" Name="colorPicker" Background="DimGrey" Width="250" /> <Widget Name="go" Width="100" Height="60" Background="DarkBlue"/> - <Widget Name="go" Width="100" Height="60" Background="{../colorPicker.CurrentColor}"/> + <Widget Width="100" Height="60" Background="{../colorPicker.CurrentColor}"/> <Label Text="{../colorPicker.CurrentColor}"/> </VerticalStack>
\ No newline at end of file diff --git a/Samples/common/ui/Interfaces/Divers/colorPicker2.crow b/Samples/common/ui/Interfaces/Divers/colorPicker2.crow index da1a8830..95d00ec6 100644 --- a/Samples/common/ui/Interfaces/Divers/colorPicker2.crow +++ b/Samples/common/ui/Interfaces/Divers/colorPicker2.crow @@ -1,7 +1,7 @@ <?xml version="1.0"?> <VerticalStack> - <ColorPicker CurrentColor="{²../go.Background}" Name="colorPicker" Background="DimGrey" Margin="5" Width="300" Template="#ui.ColorPicker.template" /> <Widget Name="go" Width="100" Height="60" Background="DarkBlue"/> - <Widget Name="go" Width="100" Height="60" Background="{../colorPicker.CurrentColor}"/> + <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="#ui.ColorPicker.template" /> </VerticalStack>
\ No newline at end of file diff --git a/Samples/common/ui/Interfaces/Divers/gauge2.crow b/Samples/common/ui/Interfaces/Divers/gauge2.crow new file mode 100644 index 00000000..c5b94cab --- /dev/null +++ b/Samples/common/ui/Interfaces/Divers/gauge2.crow @@ -0,0 +1,16 @@ +<HorizontalStack Margin="20" Background="Jet"> + <VerticalStack Width="Fit" Background="DarkSlateGrey" Margin="10" Height="Fit"> + <HorizontalStack Height="Fit" Spacing="10"> + <Label Text="Value:"/> + <Label Text="{../../slider.Value}" Background="Onyx" Margin="1" Width="40" TextAlignment="Right"/> + </HorizontalStack> + <Slider Name="slider" Height="10" Width="200" Background="DarkGrey" + Minimum="0" Maximum="100" Value="50" Inverted="{../cb.IsChecked}"/> + <CheckBox Name="cb" Caption="Inverted" /> + </VerticalStack> + <Gauge Height="20" Width="200" Foreground="RoyalBlue" Background="DarkGrey" Margin="2" Value="{../slider.Value}" + Inverted="{../cb.IsChecked}" /> + <Gauge Height="200" Width="20" Foreground="RoyalBlue" Background="DarkGrey" Margin="2" Value="{../slider.Value}" + Inverted="{../cb.IsChecked}" Orientation="Vertical" /> + +</HorizontalStack>
\ No newline at end of file diff --git a/Samples/common/ui/Interfaces/Divers/progress.crow b/Samples/common/ui/Interfaces/Divers/progress.crow index b4086cd6..761a04c4 100644 --- a/Samples/common/ui/Interfaces/Divers/progress.crow +++ b/Samples/common/ui/Interfaces/Divers/progress.crow @@ -4,7 +4,7 @@ <Group> <Gauge Background="DarkGrey" Foreground="RoyalBlue" Height="Stretched" Orientation="{./Orientation}" Minimum="{./Minimum}" Maximum="{./Maximum}" Value="{./Value}"/> - <Label Foreground="White" Text="{ProgressMessage}" Width="Stretched" Margin="3" Background="Transparent" Height="Fit"/> + <Label Foreground="White" Text="{./Caption}" Width="Stretched" Margin="3" Background="Transparent" Height="Fit"/> </Group> </Template> </ProgressBar> diff --git a/Samples/common/ui/Interfaces/Divers/temp.crow b/Samples/common/ui/Interfaces/Divers/temp.crow deleted file mode 100644 index 633bd600..00000000 --- a/Samples/common/ui/Interfaces/Divers/temp.crow +++ /dev/null @@ -1,4 +0,0 @@ -<VerticalStack> - <Label Text='Hello World' Background='MediumSeaGreen' Margin='10'/> - <CheckBox I -</VerticalStack>
\ No newline at end of file diff --git a/Samples/common/ui/Interfaces/Divers/test1.1.crow b/Samples/common/ui/Interfaces/Divers/test1.1.crow deleted file mode 100644 index 052c872c..00000000 --- a/Samples/common/ui/Interfaces/Divers/test1.1.crow +++ /dev/null @@ -1,15 +0,0 @@ -<?xml version="1.0"?> -<Group Name="TopGroup" Width="500" Height="400" Margin="5" - Focusable="True" Background="Yellow"> - <Group Name="InnerGroup" Width="Fit" Height="Fit" Margin="50" - VerticalAlignment="Top" HorizontalAlignment="Left" - Focusable="True" Background="Green"> - <Image VerticalAlignment="Bottom" - Name="PhaseOverlay1" Width="100" Height="100" Path="#Crow.Icons.crow.svg" Background="Red"/> - <Image Top="100" - Name="PhaseOverlay2" Width="100" Height="100" Path="#Crow.Icons.crow.svg" Background="Red"/> - </Group> - <Image VerticalAlignment="Center" HorizontalAlignment="Right" - Name="PhaseOverlay0" Width="100" Height="100" Path="#Crow.Icons.crow.svg" Background="Red"/> - -</Group>
\ No newline at end of file diff --git a/Samples/common/ui/Interfaces/Divers/test1.2.crow b/Samples/common/ui/Interfaces/Divers/test1.2.crow deleted file mode 100644 index 00fb7d22..00000000 --- a/Samples/common/ui/Interfaces/Divers/test1.2.crow +++ /dev/null @@ -1,20 +0,0 @@ -<?xml version="1.0"?> -<Container Background="Green" Height="400" Width="400"> -<VerticalStack Margin="10" Background="DarkBlue" Height="Fit" Width="Stretched"> - <Label Text="label11" Width="Stretched"/> - <Label Text="label21"/> - <HorizontalStack Width="Fit" Height="Fit" Margin="5" - Focusable="True" Background="Blue"> - <Label Text="label12"/> - <Label Text="label22"/> - <Label Text="label32"/> - <Label Text="label42"/> - <Label Text="label52"/> - </HorizontalStack> - <Label Text="label33" Background="Green" Width="Stretched"/> - <Button/> - <Label Text="label43"/> - <Label Text="label53"/> - -</VerticalStack> -</Container>
\ No newline at end of file diff --git a/Samples/common/ui/Interfaces/Divers/test1.crow b/Samples/common/ui/Interfaces/Divers/test1.crow deleted file mode 100644 index b3c58fa8..00000000 --- a/Samples/common/ui/Interfaces/Divers/test1.crow +++ /dev/null @@ -1,9 +0,0 @@ -<?xml version="1.0"?> -<Container Name="TopContainer" Width="400" Height="350" - Margin="20" Focusable="True" Background="Yellow"> - <Container Name="MiddleContainer" Width="50%" Height="Stretched" - Margin="20" Focusable="True" Background="Green"> - <Image VerticalAlignment="Bottom" - Name="PhaseOverlay" Width="100" Height="100" Path="#Crow.Icons.crow.svg" Background="Red"/> - </Container> -</Container>
\ No newline at end of file diff --git a/Samples/common/ui/Interfaces/Divers/testCtxMenu.crow b/Samples/common/ui/Interfaces/Divers/testCtxMenu.crow index 5fd6072a..1c37ee84 100644 --- a/Samples/common/ui/Interfaces/Divers/testCtxMenu.crow +++ b/Samples/common/ui/Interfaces/Divers/testCtxMenu.crow @@ -1,4 +1,4 @@ <?xml version="1.0"?> <Widget Margin="10" Width="50%" Height="50%" Focusable="true" Background="hgradient|0:Red|0.25:Blue|0.5:Green|0.75:Yellow|1:Red" - MinimumSize="50,50" ContextCommands="{Commands}"/>
\ No newline at end of file + MinimumSize="50,50" ContextCommands="{AllCommands}"/>
\ No newline at end of file diff --git a/Samples/common/ui/Interfaces/Divers/testPopUpdate.crow b/Samples/common/ui/Interfaces/Divers/testPopUpdate.crow new file mode 100644 index 00000000..84610531 --- /dev/null +++ b/Samples/common/ui/Interfaces/Divers/testPopUpdate.crow @@ -0,0 +1,12 @@ +<Popper Background='MediumSeaGreen' Margin='0' Fit="true"> + <Template> + <Label/> + </Template> + <Border Name="bd" Background="Grey" Width="200" Height="100"> + <Container Name="ct"> + <Label Fit="true" + MouseDown="{Background=Yellow}" + MouseUp="{Background=Transparent}"/> + </Container> + </Border> +</Popper>
\ No newline at end of file diff --git a/Samples/common/ui/Interfaces/Divers/testSlider.crow b/Samples/common/ui/Interfaces/Divers/testSlider.crow index a2fb0862..d7050000 100644 --- a/Samples/common/ui/Interfaces/Divers/testSlider.crow +++ b/Samples/common/ui/Interfaces/Divers/testSlider.crow @@ -1,59 +1,65 @@ <?xml version="1.0"?> <HorizontalStack Margin="50"> + <CheckBox Name="inverted" Background="DarkSlateGrey" Caption="Inverted" Width="Fit" Foreground="Black"/> + <VerticalStack Spacing="10" Width="50%"> - <Slider Background="DarkGrey" Height="20" Width="Stretched"/> - <Slider Background="RoyalBlue" Height="50" Width="Stretched" CursorSize="50"> + <Slider Background="DarkGrey" Height="20" Width="Stretched" Inverted="{../../inverted.IsChecked}"/> + <Slider Background="RoyalBlue" Height="50" Width="Stretched" CursorSize="50" Inverted="{../../inverted.IsChecked}"> <Template> <Group Background="DarkGrey" > - <Gauge Height="50%" Background="RoyalBlue" Value="{./Value}" Maximum="{./Maximum}" Minimum="{Minimum}" Orientation="{./Orientation}"/> + <Gauge Height="50%" Background="Onyx" Value="{./Value}" Maximum="{./Maximum}" Minimum="{Minimum}" Orientation="{./Orientation}" + Inverted="{./Inverted}"/> <Container Name="Cursor" Background="White" > <Label Text="{./Value}" Foreground="Black"/> </Container> </Group> </Template> </Slider> - <Slider Background="Transparent" Margin="2" Height="10" Width="Stretched"/> - <Slider Background="Transparent" CursorSize="10" Height="12" > + <Slider Background="Transparent" Margin="2" Height="10" Width="Stretched" Inverted="{../../inverted.IsChecked}"/> + <Slider Background="Transparent" CursorSize="10" Height="12" Inverted="{../../inverted.IsChecked}"> <Template> <Group Background="DarkGrey" > - <Gauge Height="50%" Background="RoyalBlue" Value="{./Value}" Maximum="{./Maximum}" Minimum="{Minimum}" Orientation="{./Orientation}"/> + <Gauge Height="50%" Background="Onyx" Value="{./Value}" Maximum="{./Maximum}" Minimum="{Minimum}" Orientation="{./Orientation}" + Inverted="{./Inverted}"/> <Widget Name="Cursor" Background="White" /> </Group> </Template> </Slider> - <Slider Height="10" Width="Stretched" /> + <Slider Height="10" Width="Stretched" Inverted="{../../inverted.IsChecked}" /> - <Slider ClipToClientRect='false' Background="DarkGrey" CursorSize="50" Height="12" CornerRadius="5" /> - <Slider ClipToClientRect='false' CacheEnabled='false' Background="Transparent" CursorSize="20" Height="12" Width="Stretched" /> + <Slider ClipToClientRect='false' Background="DarkGrey" CursorSize="50" Height="12" CornerRadius="5" Inverted="{../../inverted.IsChecked}" /> + <Slider ClipToClientRect='false' CacheEnabled='false' Background="Transparent" CursorSize="20" Height="12" Width="Stretched" Inverted="{../../inverted.IsChecked}" /> </VerticalStack> <HorizontalStack Spacing="10" > - <Slider Orientation="Vertical" Width="20" Height="Stretched"/> - <Slider Orientation="Vertical" Width="50" Height="Stretched" Background="RoyalBlue" CursorSize="50"> + <Slider Orientation="Vertical" Width="20" Height="Stretched" Inverted="{../../inverted.IsChecked}"/> + <Slider Orientation="Vertical" Width="50" Height="Stretched" Background="RoyalBlue" CursorSize="50" Inverted="{../../inverted.IsChecked}"> <Template> <Group Background="DarkGrey" > - <Gauge Width="50%" Background="RoyalBlue" Value="{./Value}" Maximum="{./Maximum}" Minimum="{Minimum}" Orientation="{./Orientation}"/> + <Gauge Width="50%" Background="Onyx" Value="{./Value}" Maximum="{./Maximum}" Minimum="{Minimum}" Orientation="{./Orientation}" + Inverted="{./Inverted}"/> <Container Name="Cursor" Background="White" > <Label Text="{./Value}" Foreground="Black"/> </Container> </Group> </Template> </Slider> - <Slider Orientation="Vertical" Width="10" Height="Stretched" Background="Transparent" Margin="2" /> - <Slider Orientation="Vertical" Width="12" Height="Stretched" Background="Transparent" CursorSize="10" > + <Slider Orientation="Vertical" Width="10" Height="Stretched" Background="Transparent" Margin="2" Inverted="{../../inverted.IsChecked}"/> + <Slider Orientation="Vertical" Width="12" Height="Stretched" Background="Transparent" CursorSize="10" Inverted="{../../inverted.IsChecked}"> <Template> <Group Background="DarkGrey" > - <Gauge Width="50%" Background="RoyalBlue" Value="{./Value}" Maximum="{./Maximum}" Minimum="{Minimum}" Orientation="{./Orientation}"/> + <Gauge Width="50%" Background="Onyx" Value="{./Value}" Maximum="{./Maximum}" Minimum="{Minimum}" Orientation="{./Orientation}" + Inverted="{./Inverted}"/> <Widget Name="Cursor" Background="White" /> </Group> </Template> </Slider> - <Slider Width="10" /> + <Slider Width="10" Orientation="Vertical" Inverted="{../../inverted.IsChecked}"/> - <Slider Width="12" Height="Stretched" Orientation="Vertical" ClipToClientRect='false' Background="DarkGrey" CursorSize="50" CornerRadius="5" /> - <Slider Width="12" Height="Stretched" Orientation="Vertical" ClipToClientRect='false' CacheEnabled='false' Background="Transparent" CursorSize="20" /> + <Slider Width="12" Height="Stretched" Orientation="Vertical" ClipToClientRect='false' Background="DarkGrey" CursorSize="50" CornerRadius="5" Inverted="{../../inverted.IsChecked}"/> + <Slider Width="12" Height="Stretched" Orientation="Vertical" ClipToClientRect='false' CacheEnabled='false' Background="Transparent" CursorSize="20" Inverted="{../../inverted.IsChecked}"/> </HorizontalStack> </HorizontalStack>
\ No newline at end of file diff --git a/Samples/common/ui/Interfaces/Divers/test_stack.crow b/Samples/common/ui/Interfaces/Divers/test_stack.crow deleted file mode 100644 index 044fd7f0..00000000 --- a/Samples/common/ui/Interfaces/Divers/test_stack.crow +++ /dev/null @@ -1,25 +0,0 @@ -<?xml version="1.0"?> -<VerticalStack Background="DarkBlue" Height="300" Width="200"> -<!-- <Label Text="label11" Width="Stretched" Background="Green"/> - <Label Text="label21"/>--> - <HorizontalStack Width="Fit" Height="Fit" Margin="5" - Focusable="True" Background="Blue"> - - <Label Text="label12"/> - <VerticalStack Background="Red" Fit="true"> - <Label Text="label99"/> - <Label Text="label999"/> - </VerticalStack> - <Label Text="label22"/> -<!-- <Label Text="label32"/> - <Label Text="label42"/> - <Label Text="label52"/>--> - </HorizontalStack> -<!-- <Label Text="label33" Background="Green" Width="Stretched"/>--> -<!-- <Label Text="label43"/>--> -<!-- <Border Margin="10"> - <Label Text="label53" Background="Red" Height="Stretched" CornerRadius="10"/> - </Border>--> - <Label Text="label43"/> - <Label Text="label43"/> -</VerticalStack> diff --git a/Samples/common/ui/Interfaces/Experimental/allWidgets.crow b/Samples/common/ui/Interfaces/Experimental/allWidgets.crow new file mode 100644 index 00000000..4b659db8 --- /dev/null +++ b/Samples/common/ui/Interfaces/Experimental/allWidgets.crow @@ -0,0 +1,99 @@ +<TabView Background="DimGrey"> + <VerticalStack Name="Base" Background="Black" Margin="1" > + <HorizontalStack > + <GroupBox Style="allWidgetCell" Caption="Label" > + <Label/> + </GroupBox> + <GroupBox Style="allWidgetCell" Caption="TextBox"> + <TextBox/> + </GroupBox> + <GroupBox Style="allWidgetCell" Caption="Button"> + <Button/> + </GroupBox> + <GroupBox Style="allWidgetCell" Caption="CheckBox" > + <CheckBox/> + </GroupBox> + <GroupBox Style="allWidgetCell" Caption="RadioButton"> + <RadioButton/> + </GroupBox> + </HorizontalStack> + <HorizontalStack Height="25%" > + <GroupBox Style="allWidgetCell" Caption="Expandable"> + <Expandable/> + </GroupBox> + <GroupBox Style="allWidgetCell" Caption="Popper"> + <Popper/> + </GroupBox> + <GroupBox Style="allWidgetCell" Caption="Popper"> + <Menu> + <MenuItem Width="Fit" Caption="menu1"> + <MenuItem Caption="test"/> + <MenuItem Caption="test un peu plus long"/> + <MenuItem Caption="test2"/> + </MenuItem> + <MenuItem Width="Fit" Caption="menu2"> + <MenuItem Caption="test menu2"/> + <MenuItem Caption="test menu2 un peu plus long"/> + <MenuItem Caption="test2 menu2" /> + </MenuItem> + <MenuItem Width="Fit" Caption="menu3"/> + </Menu> + </GroupBox> + <GroupBox Style="allWidgetCell" Caption="ComboBox"> + <DirectoryView /> + </GroupBox> + </HorizontalStack> + <HorizontalStack Height="25%" > + <GroupBox Style="allWidgetNamedCell" Caption="Spinner" > + <Spinner/> + </GroupBox> + <GroupBox Style="allWidgetNamedCell" Caption="Slider"> + <Slider/> + </GroupBox> + <GroupBox Style="allWidgetNamedCell" Caption="ListBox"> + <ListBox Data="{TestList}" Height="60%" Width="80%"/> + </GroupBox> + <GroupBox Style="allWidgetNamedCell" Caption="ComboBox"> + <ComboBox Data="{TestList}"/> + </GroupBox> + </HorizontalStack> + <HorizontalStack Height="25%" > + <GroupBox Style="allWidgetNamedCell" Caption="Border"> + <Border Height="50%" Width="80%"/> + </GroupBox> + <GroupBox Style="allWidgetCell" Caption="GroupBox"> + <GroupBox Height="50%" Width="80%"/> + </GroupBox> + <GroupBox Style="allWidgetNamedCell" Caption="ProgressBar"> + <ProgressBar Value="40" /> + </GroupBox> + <GroupBox Style="allWidgetNamedCell" Caption="Vertical ScrollBar"> + <ScrollBar Height="80%" Maximum="10" /> + </GroupBox> + <GroupBox Style="allWidgetNamedCell" Caption="Horizontal ScrollBar"> + <ScrollBar Style="HScrollBar" Width="80%" Maximum="10" /> + </GroupBox> + </HorizontalStack> + </VerticalStack> + <HorizontalStack Name="Advanced" Background="DarkGrey" IsVisible="false"> + <VerticalStack Width="50%" > + <GroupBox Style="allWidgetNamedCell" Height="50%" Width="Stretched" Caption="MesageBox"> + <MessageBox Height="80%" Width="80%"/> + </GroupBox> + <GroupBox Style="allWidgetNamedCell" Height="Stretched" Width="Stretched" Caption="FileDialog"> + <ColorPicker Height="80%" Width="80%"/> + </GroupBox> + </VerticalStack> + <GroupBox Style="allWidgetNamedCell" Width="Stretched" Caption="FileDialog"> + <FileDialog Height="80%" Width="80%"/> + </GroupBox> + </HorizontalStack> + <HorizontalStack Name="windows" Background="DarkGrey" IsVisible="false"> + <GroupBox Style="allWidgetNamedCell" Caption="Window" Width="50%" > + <Window Width="80%" Height="80%" VerticalAlignment="Center" HorizontalAlignment="Center"/> + </GroupBox> + <GroupBox Style="allWidgetNamedCell" Caption="DockWindow" Width="50%" > + <DockWindow Width="80%" Height="80%" VerticalAlignment="Center" HorizontalAlignment="Center"/> + </GroupBox> + </HorizontalStack> +</TabView>
\ No newline at end of file diff --git a/Samples/common/ui/Interfaces/Experimental/allWidgets2.crow b/Samples/common/ui/Interfaces/Experimental/allWidgets2.crow new file mode 100644 index 00000000..f805a3d4 --- /dev/null +++ b/Samples/common/ui/Interfaces/Experimental/allWidgets2.crow @@ -0,0 +1,114 @@ +<VerticalStack Name="Base" Background="{AllWidgetBackground}" Margin="1" > + <HorizontalStack Height="15%"> + <GroupBox Style="allWidgetCell2" Caption="Label" > + <Label/> + </GroupBox> + <GroupBox Style="allWidgetCell2" Caption="TextBox"> + <TextBox/> + </GroupBox> + <GroupBox Style="allWidgetCell2" Caption="Button"> + <Button /> + </GroupBox> + <GroupBox Style="allWidgetCell2" Caption="CheckBox" > + <CheckBox /> + </GroupBox> + <GroupBox Style="allWidgetCell2" Caption="RadioButton"> + <RadioButton/> + </GroupBox> + </HorizontalStack> + <HorizontalStack Height="15%"> + <GroupBox Style="allWidgetCell2" Caption="Spinner" > + <Spinner/> + </GroupBox> + <GroupBox Style="allWidgetCell2" Caption="Slider"> + <Slider/> + </GroupBox> + <GroupBox Style="allWidgetCell2" Caption="ProgressBar"> + <ProgressBar Value="40" /> + </GroupBox> + </HorizontalStack> + <HorizontalStack Height="20%" > + <GroupBox Style="allWidgetCell2" Caption="Border"> + <Border > + <Label/> + </Border> + </GroupBox> + <GroupBox Style="allWidgetCell2" Caption="GroupBox"> + <GroupBox > + <Label/> + </GroupBox> + </GroupBox> + <GroupBox Style="allWidgetCell2" Caption="Container"> + <Container> + <Label/> + </Container> + </GroupBox> + <GroupBox Style="allWidgetCell2" Caption="VerticalStack"> + <VerticalStack> + <Label/> + <Label/> + <Label/> + </VerticalStack> + </GroupBox> + <GroupBox Style="allWidgetCell2" Caption="HorizontalStack"> + <HorizontalStack> + <Label/> + <Label/> + <Label/> + </HorizontalStack> + </GroupBox> + </HorizontalStack> + <HorizontalStack Height="20%" > + <GroupBox Style="allWidgetCell2" Caption="Expandable"> + <Expandable> + <Label/> + </Expandable> + </GroupBox> + <GroupBox Style="allWidgetCell2" Caption="Popper"> + <Popper> + <Label/> + </Popper> + </GroupBox> + <GroupBox Style="allWidgetCell2" Caption="ListBox"> + <ListBox Data="{TestList}" /> + </GroupBox> + <GroupBox Style="allWidgetCell2" Caption="ComboBox"> + <ComboBox Data="{TestList}"/> + </GroupBox> + <GroupBox Style="allWidgetCell2" Caption="ColorPicker"> + <ColorPicker Template="Interfaces/colorPicker.tmp" CurrentColor="{²AllWidgetBackground}"/> + </GroupBox> + </HorizontalStack> + <HorizontalStack Height="25%" > + <GroupBox Style="allWidgetCell2" Caption="Vertical ScrollBar"> + <ScrollBar Maximum="10" /> + </GroupBox> + <GroupBox Style="allWidgetCell2" Caption="Horizontal ScrollBar"> + <ScrollBar Style="HScrollBar" Maximum="10" /> + </GroupBox> + <GroupBox Style="allWidgetCell2" Caption="TabView"> + <TabView > + <Widget Name="tab1" Background="Grey"/> + <Widget Name="tab2" Background="DarkSlateGrey" IsVisible="false"/> + <Widget Name="tab3" Background="DarkRed" IsVisible="false"/> + </TabView > + </GroupBox> + <GroupBox Style="allWidgetCell2" Caption="Table"> + <Table Columns="Column1,Fit;Column2,Fit;Column3,Stretched" > + <TableRow Height="Fit" > + <Label/> + <Label/> + <Label/> + </TableRow> + <TableRow Height="Fit" > + <Label/> + <Label/> + <Label/> + </TableRow> + <TableRow Height="Fit" > + <Label/> + </TableRow> + </Table> + </GroupBox> + </HorizontalStack> +</VerticalStack> diff --git a/Samples/common/ui/Interfaces/Experimental/multiColorPick2.crow b/Samples/common/ui/Interfaces/Experimental/multiColorPick2.crow index 0d3c04e7..5d6e2364 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"/> + <ColorPicker Name="HSV" CurrentColor="{²../../../CurrentColor}" Background="Onyx" BubbleMouseEvent="false"/> <ColorPicker IsVisible="false" Name="Names" CurrentColor="{²../../../CurrentColor}" Height="Stretched" Background="Onyx"> <Template> <ListBox Width="Stretched" Data="{./AvailableColors}" SelectedItemChanged="./onSelectedItemChanged"> @@ -28,7 +28,7 @@ </ListBox> </Template> </ColorPicker> - </TabView> + </TabView> </Popper> </Template> </ColorPicker> diff --git a/Samples/common/ui/Interfaces/Experimental/popperTest.crow b/Samples/common/ui/Interfaces/Experimental/popperTest.crow new file mode 100644 index 00000000..c0106c17 --- /dev/null +++ b/Samples/common/ui/Interfaces/Experimental/popperTest.crow @@ -0,0 +1,2 @@ + +<Label Background="RebeccaPurple"/>
\ No newline at end of file diff --git a/Samples/common/ui/Interfaces/Experimental/tabviewWithScrollTabName.crow b/Samples/common/ui/Interfaces/Experimental/tabviewWithScrollTabName.crow new file mode 100644 index 00000000..4b29646e --- /dev/null +++ b/Samples/common/ui/Interfaces/Experimental/tabviewWithScrollTabName.crow @@ -0,0 +1,40 @@ +<TabView Orientation="Horizontal"> + <Template> + <GenericStack Orientation="{./OppositeOrientation}" Spacing="0" Background="{./Background}"> + <ListBox Data="{./Items}" Height="Fit" HorizontalAlignment="Left" VerticalAlignment="Top" SelectedItem="{²./SelectedItem}"> + <Template> + <VerticalStack Spacing="0" > + <Scroller Name="ItemsScroller" > + <GenericStack Orientation="{../../../../../Orientation}" Width="Fit" Name="ItemsContainer" HorizontalAlignment="Left"/> + </Scroller> + <ScrollBar Orientation="Horizontal" Foreground="RoyalBlue" Height="6" Width="Stretched" CornerRadius="3" + Value="{²../ItemsScroller.ScrollX}" + LargeIncrement="{../ItemsScroller.PageWidth}" SmallIncrement="1" + CursorRatio="{../ItemsScroller.ChildWidthRatio}" Maximum="{../ItemsScroller.MaxScrollX}"> + <Template> + <Container Margin="1" Background="{./Background}"> + <Widget Name="Cursor" Background="{./Foreground}" CornerRadius="{./CornerRadius}"/> + </Container> + </Template> + </ScrollBar> + </VerticalStack> + </Template> + <ItemTemplate> + <ListItem Fit="true" Background="${InactiveTabItem}" IsSelected="{IsVisible}" Margin="5" + Selected="{.DataSource.Visible='true'};{Background=.DataSource.Background}" + Unselected="{.DataSource.Visible='false'};{Background=${InactiveTabItem}}"> + <Label Text="{Name}" Width="200" /> + </ListItem> + </ItemTemplate> + </ListBox> + <Group Name="ItemsContainer" /> + </GenericStack> + </Template> + <GroupBox Name="item 1" Caption="item 1" IsVisible="true" Background="Violet"/> + <GroupBox Name="item 2" Caption="item 2" IsVisible="false" Background="CornflowerBlue"/> + <GroupBox Name="item 3" Caption="item 3" IsVisible="false" Background="Red"/> + <GroupBox Name="item 4" Caption="item 4" IsVisible="false" Background="Green"/> + <GroupBox Name="item 5" Caption="item 5" IsVisible="false" Background="Brown"/> + <GroupBox Name="item 6" Caption="item 6" IsVisible="false" Background="RoyalBlue"/> + <GroupBox Name="item 7" Caption="item 7" IsVisible="false" Background="Yellow"/> +</TabView>
\ No newline at end of file diff --git a/Samples/common/ui/Interfaces/Experimental/testButton.crow b/Samples/common/ui/Interfaces/Experimental/testButton.crow new file mode 100644 index 00000000..a1b9fd5f --- /dev/null +++ b/Samples/common/ui/Interfaces/Experimental/testButton.crow @@ -0,0 +1 @@ +<Button Caption='Hello World' />
\ No newline at end of file diff --git a/Samples/common/ui/Interfaces/Experimental/testColorPickerTemplate.crow b/Samples/common/ui/Interfaces/Experimental/testColorPickerTemplate.crow new file mode 100644 index 00000000..7c7ebe13 --- /dev/null +++ b/Samples/common/ui/Interfaces/Experimental/testColorPickerTemplate.crow @@ -0,0 +1,3 @@ +<VerticalStack Height="Fit" Background="DarkBlue"> + <ColorPicker Template="Interfaces/colorPicker.tmp" Background="Red"/> +</VerticalStack>
\ No newline at end of file diff --git a/Samples/common/ui/Interfaces/Experimental/testScroll.crow b/Samples/common/ui/Interfaces/Experimental/testScroll.crow new file mode 100644 index 00000000..8316a5ce --- /dev/null +++ b/Samples/common/ui/Interfaces/Experimental/testScroll.crow @@ -0,0 +1,12 @@ +<Button Width="100" Height="200"> + <Template> +<VerticalStack > + <Scroller Name="ItemsScroller" Background="Red" Width="Stretched"> + <Label Text='Hello World and another part of text to test scrolling' Background='MediumSeaGreen' Margin='0' Fit="true" HorizontalAlignment="Left"/> + </Scroller> + <ScrollBar Style="HScrollBar" Value="{²../ItemsScroller.ScrollX}" + LargeIncrement="{../ItemsScroller.PageWidth}" SmallIncrement="1" + CursorRatio="{../ItemsScroller.ChildWidthRatio}" Maximum="{../ItemsScroller.MaxScrollX}"/> +</VerticalStack> + </Template> +</Button>
\ No newline at end of file diff --git a/Samples/common/ui/Interfaces/Experimental/testTypeViewer.goml b/Samples/common/ui/Interfaces/Experimental/testTypeViewer.goml deleted file mode 100644 index caa454fc..00000000 --- a/Samples/common/ui/Interfaces/Experimental/testTypeViewer.goml +++ /dev/null @@ -1,10 +0,0 @@ -<?xml version="1.0"?> - - <VerticalStack Height="Fit" Width="250" Name="hstack" Margin="0" Spacing="0"> - <Border Height="Fit" Width="Stretched" BorderWidth="2" CornerRadius="10" Background="SteelBlue"> - <Label Name="labName" Text="{Name}" Width="Stretched" Height="Fit" Margin="3"/> - </Border> - <ListBox Data="{Members}" Width="Stretched" Height="400" ItemTemplate="Interfaces/tmpMembers.goml" Focusable="true"> - - </ListBox> - </VerticalStack> diff --git a/Samples/common/ui/Interfaces/TemplatedContainer/0.crow b/Samples/common/ui/Interfaces/TemplatedContainer/0.crow deleted file mode 100644 index 5b267402..00000000 --- a/Samples/common/ui/Interfaces/TemplatedContainer/0.crow +++ /dev/null @@ -1,13 +0,0 @@ -<?xml version="1.0"?> -<Expandable Fit="true" Caption="Test expandable" Background="DimGrey"> - <VerticalStack Margin="5" > - <CheckBox Name="chk1" /> - <CheckBox Name="chk2" IsChecked="true"/> - <CheckBox Name="chk3" /> - <CheckBox Name="chk4" /> - <HorizontalStack Fit="true" Margin="2" Background="SeaGreen"> - <Label Name="captionFps" Text="Fps:" Width="30" TextAlignment="Right"/> - <Label Name="valueFps" Text="{fps}" Font="droid , 12" Width="Fit" TextAlignment="Center" Background="SeaGreen"/> - </HorizontalStack> - </VerticalStack> -</Expandable> diff --git a/Samples/common/ui/Interfaces/TemplatedContainer/6.crow b/Samples/common/ui/Interfaces/TemplatedContainer/6.crow deleted file mode 100644 index 641d58f9..00000000 --- a/Samples/common/ui/Interfaces/TemplatedContainer/6.crow +++ /dev/null @@ -1,21 +0,0 @@ -<Expandable Width="Stretched" Background="Grey"> - <Expandable Width="Stretched" Background="LightBlue"> - <Expandable Width="Stretched" Background="Green"> - <Expandable Width="Stretched" Background="LimeGreen"> - <Expandable Width="Stretched" Background="DimGrey"> - <Expandable Width="Stretched" Background="Yellow"> - <Expandable Width="Stretched" Background="SeaGreen"> - <Expandable Width="Stretched" Background="Blue"> - <Expandable Width="Stretched" Background="RoyalBlue"> - <Expandable Width="Stretched" Background="Green"> - <Label Background="Red" Text="{fps}"/> - </Expandable> - </Expandable> - </Expandable> - </Expandable> - </Expandable> - </Expandable> - </Expandable> - </Expandable> - </Expandable> - </Expandable>
\ No newline at end of file diff --git a/Samples/common/ui/Interfaces/TemplatedGroup/menu0.crow b/Samples/common/ui/Interfaces/TemplatedGroup/menu0.crow index 0465c644..1d157431 100644 --- a/Samples/common/ui/Interfaces/TemplatedGroup/menu0.crow +++ b/Samples/common/ui/Interfaces/TemplatedGroup/menu0.crow @@ -1,18 +1,10 @@ <?xml version="1.0"?> <Menu Data="{AllCommands}"> - <ItemTemplate DataType="Crow.Command"> - <Button Command="{}"> - <Template> - <Label Text="{./Caption}" Width="Stretched" Height="Stretched" Margin="3" - MouseEnter="{Background=${ControlHighlight}}" - MouseLeave="{Background=Transparent}"/> - </Template> - </Button> - </ItemTemplate> + <ItemTemplate DataType="Crow.Command" Path="Interfaces/menuCommand.itmp"/> <ItemTemplate DataType="Crow.CommandGroup" > <MenuItem Data="{Commands}" Width="Fit" IsEnabled="{CanExecute}"> <Template> - <Popper PopDirection="Bottom" Caption="{Caption}" + <Popper PopDirection="Bottom" Caption="{Caption}" Width="Fit" MouseEnter="{Background=${ControlHighlight}}" MouseLeave="{Background=Transparent}"> <Template> @@ -22,15 +14,7 @@ <VerticalStack Name="ItemsContainer" Fit="true" Background="Jet"/> </Popper> </Template> - <ItemTemplate DataType="Crow.Command"> - <Button Command="{}" Width="Stretched"> - <Template> - <Label Text="{./Caption}" Width="Stretched" Height="Stretched" Margin="3" - - MouseEnter="{Background=${ControlHighlight}}" - MouseLeave="{Background=Transparent}"/> - </Template> - </Button> </ItemTemplate> + <ItemTemplate DataType="Crow.Command" Path="Interfaces/menuCommand.itmp"/> <ItemTemplate DataType="Crow.CommandGroup" > <MenuItem Data="{Commands}" Width="Stretched" IsEnabled="{CanExecute}"> <Template> @@ -46,15 +30,7 @@ </Border> </Popper> </Template> - <ItemTemplate DataType="Crow.Command"> - <Button Command="{}" Width="Stretched"> - <Template> - <Label Text="{./Caption}" Width="Stretched" Height="Stretched" Margin="3" - MouseEnter="{Background=${ControlHighlight}}" - MouseLeave="{Background=Transparent}"/> - </Template> - </Button> - </ItemTemplate> + <ItemTemplate DataType="Crow.Command" Path="Interfaces/menuCommand.itmp"/> </MenuItem> </ItemTemplate> </MenuItem> diff --git a/Samples/common/ui/Interfaces/TemplatedGroup/menu1.crow b/Samples/common/ui/Interfaces/TemplatedGroup/menu1.crow new file mode 100644 index 00000000..e8f95115 --- /dev/null +++ b/Samples/common/ui/Interfaces/TemplatedGroup/menu1.crow @@ -0,0 +1,20 @@ +<?xml version="1.0"?> +<Menu Data="{AllCommands}"> + <ItemTemplate DataType="Crow.Command" Path="Interfaces/menuCommand.itmp"/> + <ItemTemplate DataType="Crow.CommandGroup" > + <MenuItem Data="{Commands}" Width="Fit" IsEnabled="{CanExecute}" + ItemTemplate="Interfaces/menuItem.itmp"> + <Template> + <Popper PopDirection="Bottom" Caption="{Caption}" Width="Fit" + MouseEnter="{Background=${ControlHighlight}}" + MouseLeave="{Background=Transparent}"> + <Template> + <Label Text="{./Caption}" Width="Stretched" Height="Fit" Margin="3" + Background="{./Background}"/> + </Template> + <VerticalStack Name="ItemsContainer" Fit="true" Background="Jet"/> + </Popper> + </Template> + </MenuItem> + </ItemTemplate> +</Menu>
\ No newline at end of file diff --git a/Samples/common/ui/Interfaces/TemplatedGroup/menu2.crow b/Samples/common/ui/Interfaces/TemplatedGroup/menu2.crow new file mode 100644 index 00000000..0a62cf8c --- /dev/null +++ b/Samples/common/ui/Interfaces/TemplatedGroup/menu2.crow @@ -0,0 +1,10 @@ +<?xml version="1.0"?> +<Menu Data="{AllCommands}" > + <ItemTemplate DataType="Crow.Command" Path="Interfaces/menuCommand.itmp"/> + <ItemTemplate DataType="Crow.CommandGroup" > + <MenuItem Data="{Commands}" Width="Fit" IsEnabled="{CanExecute}" + Template="Interfaces/menuItem.template" + ItemTemplate="Interfaces/menuItem.itmp"> + </MenuItem> + </ItemTemplate> +</Menu>
\ No newline at end of file diff --git a/Samples/common/ui/Interfaces/TemplatedGroup/menu3.crow b/Samples/common/ui/Interfaces/TemplatedGroup/menu3.crow new file mode 100644 index 00000000..d58c9653 --- /dev/null +++ b/Samples/common/ui/Interfaces/TemplatedGroup/menu3.crow @@ -0,0 +1,34 @@ +<?xml version="1.0"?> +<Menu Data="{AllCommands}" > + <ItemTemplate DataType="Crow.Command" Path="Interfaces/menuCommand.itmp"/> + <ItemTemplate DataType="Crow.CommandGroup" > + <MenuItem Data="{Commands}" Width="Fit" IsEnabled="{CanExecute}"> + <Template> + <Popper PopDirection="Bottom" Caption="{Caption}" Width="Fit" IsPopped="{²./IsOpened}" + MouseEnter="{Background=${ControlHighlight}}" + MouseLeave="{Background=Transparent}"> + <Template> + <Label Text="{./Caption}" Width="Stretched" Height="Fit" Margin="3" + Background="{./Background}"/> + </Template> + <VerticalStack Margin="0" Name="ItemsContainer" Fit="true" Background="Jet"/> + </Popper> + </Template> + <ItemTemplate DataType="Crow.Command" Path="#Crow.MenuButton.template"/> + <ItemTemplate DataType="Crow.CommandGroup" Data="Commands"> + <Popper PopDirection="Right" Caption="{Caption}" IsEnabled="{CanExecute}" Width="Stretched" + PopWidth="{./PopWidth}" PopHeight="{./PopHeight}" + MouseEnter="{Background=${ControlHighlight}}" + MouseLeave="{Background=Transparent}"> + <Template> + <HorizontalStack Background="{./Background}" Width="Stretched" Height="Stretched" Margin="3"> + <Label Text="{./Caption}" Width="Fit" Height="Stretched"/> + <Label Text="..."/> + </HorizontalStack> + </Template> + <VerticalStack Margin="0" Name="ItemsContainer" Width="{../PopWidth}" Height="{../PopHeight}" Background="${MenuBackground}"/> + </Popper> + </ItemTemplate> + </MenuItem> + </ItemTemplate> +</Menu>
\ No newline at end of file diff --git a/Samples/common/ui/Interfaces/Wrapper/1.1.crow b/Samples/common/ui/Interfaces/Wrapper/1.1.crow index 6afbff21..29658b77 100644 --- a/Samples/common/ui/Interfaces/Wrapper/1.1.crow +++ b/Samples/common/ui/Interfaces/Wrapper/1.1.crow @@ -1,6 +1,6 @@ <?xml version="1.0"?> -<Window Caption="Vertical Wrapper" Width="50%" Height="90%"> - <Wrapper Orientation="Vertical" Height="Stretched" Width="Fit" Margin="5" Background="MediumSeaGreen" Spacing="1" > +<Window Caption="Vertical Wrapper" Width="50%" Height="Fit"> + <Wrapper Orientation="Vertical" Height="Stretched" Width="Stretched" Margin="5" Background="MediumSeaGreen" Spacing="2" > <Widget Width="50" Height="50" Background="SeaGreen"/> <Widget Width="50" Height="50" Background="SeaGreen"/> <Widget Width="50" Height="50" Background="SeaGreen"/> diff --git a/Samples/common/ui/Interfaces/Wrapper/1.crow b/Samples/common/ui/Interfaces/Wrapper/1.crow index 58c79eea..ed0d6419 100644 --- a/Samples/common/ui/Interfaces/Wrapper/1.crow +++ b/Samples/common/ui/Interfaces/Wrapper/1.crow @@ -1,6 +1,6 @@ <?xml version="1.0"?> -<Window Caption="Vertical Wrapper" Width="50%" Height="50%"> - <Wrapper Orientation="Vertical" Height="Fit" Width="Fit" Margin="5" Background="MediumSeaGreen" Spacing="1" > +<Window Caption="Vertical Wrapper" Width="50%" Height="Fit"> + <Wrapper Orientation="Vertical" Height="Stretched" Width="Stretched" Margin="5" Background="MediumSeaGreen" Spacing="2" > <Widget Width="50" Height="50" Background="SeaGreen"/> <Widget Width="50" Height="50" Background="SeaGreen"/> <Widget Width="50" Height="50" Background="SeaGreen"/> diff --git a/Samples/common/ui/Interfaces/colorPicker.tmp b/Samples/common/ui/Interfaces/colorPicker.tmp new file mode 100644 index 00000000..085e17ad --- /dev/null +++ b/Samples/common/ui/Interfaces/colorPicker.tmp @@ -0,0 +1,29 @@ +<Popper Margin="0" Caption="{./CurrentColor}" Background="{./Background}" > + <Template> + <HorizontalStack Margin="3" Spacing="3" Background="{./Background}"> + <Border Width="18" Height="12" CornerRadius="3" + Background="{../../../CurrentColor}"> + </Border> + <Label Width="Stretched" Text="{./Caption}" /> + </HorizontalStack> + </Template>/> + <TabView MinimumSize="{../MinimumPopupSize}" Width="200" Height="200" > + <ColorPicker Name="HSV" CurrentColor="{²../../../CurrentColor}" Background="Onyx" BubbleMouseEvent="false"/> + <ColorPicker IsVisible="false" Name="Names" CurrentColor="{²../../../CurrentColor}" Height="Stretched" Background="Onyx"> + <Template> + <ListBox Width="Stretched" Data="{./AvailableColors}" SelectedItemChanged="./onSelectedItemChanged"> + <Template> + <Scroller Name="scroller1" Margin="5" ClipToClientRect="true" Background="Onyx"> + <Wrapper Name="ItemsContainer" Height="Fit" VerticalAlignment="Top"/> + </Scroller> + </Template> + <ItemTemplate> + <Border Width="16" Height="16" Background="{}" Foreground="Transparent" Tooltip="{}" + MouseEnter="{Foreground=Black}" + MouseLeave="{Foreground=Transparent}"/> + </ItemTemplate> + </ListBox> + </Template> + </ColorPicker> + </TabView> +</Popper>
\ No newline at end of file diff --git a/Samples/common/ui/Interfaces/grpBox.tmp b/Samples/common/ui/Interfaces/grpBox.tmp new file mode 100644 index 00000000..54504129 --- /dev/null +++ b/Samples/common/ui/Interfaces/grpBox.tmp @@ -0,0 +1,5 @@ +<Group Background="{./Background}"> + <Container Name="Content" Margin="0" MinimumSize="70,10"/> + <Label Font="sans, 10" Foreground="DarkGrey" Text="{./Caption}" VerticalAlignment="Top" HorizontalAlignment="Left" Margin="4"/> + <Label Font="sans, 10" Foreground="White" Text="{./Caption}" VerticalAlignment="Top" HorizontalAlignment="Left" Margin="2"/> +</Group> diff --git a/Samples/common/ui/Interfaces/grpBox2.tmp b/Samples/common/ui/Interfaces/grpBox2.tmp new file mode 100644 index 00000000..0fa98922 --- /dev/null +++ b/Samples/common/ui/Interfaces/grpBox2.tmp @@ -0,0 +1,10 @@ +<VerticalStack Margin="2" Background="Transparent" + MouseEnter = "{Background=DarkGrey};{lab.Foreground=SkyBlue}" + MouseLeave = "{Background=Transparent};{lab.Foreground=DarkGrey}"> + <!--<Group Height="Fit"> + <Label Font="sans, 10" Foreground="DarkGrey" Text="{./Caption}" VerticalAlignment="Top" HorizontalAlignment="Left" Margin="4"/> + <Label Font="sans, 10" Foreground="White" Text="{./Caption}" VerticalAlignment="Top" HorizontalAlignment="Left" Margin="2"/> + </Group>--> + <Label Name="lab" Font="sans, 9" Foreground="DarkGrey" Text="{./Caption}" Margin="1"/> + <Container Name="Content" Margin="5" Background="{AllWidgetBackground}"/> +</VerticalStack> diff --git a/Samples/common/ui/Interfaces/grpBoxUnamed.tmp b/Samples/common/ui/Interfaces/grpBoxUnamed.tmp new file mode 100644 index 00000000..8ea9ad98 --- /dev/null +++ b/Samples/common/ui/Interfaces/grpBoxUnamed.tmp @@ -0,0 +1 @@ +<Container Background="{./Background}" Name="Content" Margin="0" MinimumSize="70,10"/> diff --git a/Samples/common/ui/Interfaces/menuCommand.itmp b/Samples/common/ui/Interfaces/menuCommand.itmp new file mode 100644 index 00000000..abc3ff2c --- /dev/null +++ b/Samples/common/ui/Interfaces/menuCommand.itmp @@ -0,0 +1,8 @@ +<?xml version="1.0"?> +<Button Command="{}" Width="Stretched"> + <Template> + <Label Text="{./Caption}" Width="Stretched" Height="Stretched" Margin="3" + MouseEnter="{Background=${ControlHighlight}}" + MouseLeave="{Background=Transparent}"/> + </Template> +</Button> diff --git a/Samples/common/ui/Interfaces/menuItem.itmp b/Samples/common/ui/Interfaces/menuItem.itmp new file mode 100644 index 00000000..04bc10a6 --- /dev/null +++ b/Samples/common/ui/Interfaces/menuItem.itmp @@ -0,0 +1,13 @@ +<?xml version="1.0"?> +<ItemTemplate DataType="Crow.Command" Path="Interfaces/menuCommand.itmp"/> +<ItemTemplate DataType="Crow.CommandGroup" Data="Commands"> + <Popper PopDirection="Right" Caption="{Caption}" IsEnabled="{CanExecute}" Width="Stretched" + MouseEnter="{Background=${ControlHighlight}}" + MouseLeave="{Background=Transparent}"> + <Template> + <Label Text="{./Caption}" Width="Stretched" Height="Stretched" Margin="3" + Background="{./Background}"/> + </Template> + <VerticalStack Margin="0" Name="ItemsContainer" Fit="true" Background="Jet"/> + </Popper> +</ItemTemplate> diff --git a/Samples/common/ui/Interfaces/menuItem.template b/Samples/common/ui/Interfaces/menuItem.template new file mode 100644 index 00000000..1735e34b --- /dev/null +++ b/Samples/common/ui/Interfaces/menuItem.template @@ -0,0 +1,12 @@ +<?xml version="1.0"?> +<Popper PopDirection="Bottom" Caption="{Caption}" Width="Stretched" IsPopped="{²./IsOpened}" + MouseEnter="{Background=${ControlHighlight}}" + MouseLeave="{Background=Transparent}"> + <Template> + <Label Text="{./Caption}" Width="Stretched" Height="Fit" Margin="3" + Background="{./Background}"/> + </Template> + <VerticalStack Margin="0" Name="ItemsContainer" Fit="true" Background="Jet"/> +</Popper> + + diff --git a/Samples/common/ui/templates/ColorPicker.template b/Samples/common/ui/templates/ColorPicker.template index b7c0ce4b..085e17ad 100644 --- a/Samples/common/ui/templates/ColorPicker.template +++ b/Samples/common/ui/templates/ColorPicker.template @@ -1,5 +1,4 @@ -<?xml version="1.0"?> -<Popper Margin="0" Caption="{./CurrentColor}" Background="{./Background}" > +<Popper Margin="0" Caption="{./CurrentColor}" Background="{./Background}" > <Template> <HorizontalStack Margin="3" Spacing="3" Background="{./Background}"> <Border Width="18" Height="12" CornerRadius="3" @@ -7,9 +6,9 @@ </Border> <Label Width="Stretched" Text="{./Caption}" /> </HorizontalStack> - </Template> + </Template>/> <TabView MinimumSize="{../MinimumPopupSize}" Width="200" Height="200" > - <ColorPicker Name="HSV" CurrentColor="{²../../../CurrentColor}" Background="Onyx"/> + <ColorPicker Name="HSV" CurrentColor="{²../../../CurrentColor}" Background="Onyx" BubbleMouseEvent="false"/> <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/perfMsr.crow b/Samples/common/ui/templates/perfMsr.crow index 06f7ae3c..9f8a77f8 100644 --- a/Samples/common/ui/templates/perfMsr.crow +++ b/Samples/common/ui/templates/perfMsr.crow @@ -1,6 +1,6 @@ -<?xml version="1.0"?> +<?xml version="1.0"?> - <VerticalStack Spacing="1" Height="Fit" Width="Stretched"> + <VerticalStack Spacing="1" Height="Fit" Width="Stretched" Background="DarkGrey"> <HorizontalStack Background="DarkSlateGrey"> <Label Text="{Name}" Width="Stretched" Font="doid bold, 10" Margin="2"/> <Button Caption="Reset" MouseClick="onResetClick" Height="Fit"/> diff --git a/Samples/common/ui/templates/spinner.template b/Samples/common/ui/templates/spinner.template new file mode 100644 index 00000000..a9313358 --- /dev/null +++ b/Samples/common/ui/templates/spinner.template @@ -0,0 +1,18 @@ +<?xml version="1.0" ?> +<Border Style="ControlBorder" Background="{./Background}" CornerRadius="{./CornerRadius}" Margin="1"> + <VerticalStack Spacing="0"> + <HorizontalStack Spacing="4"> + <Label Text="{./Caption}" Style="ControlCaption" Margin="2"/> + <TextBox Style="ControlEditableText" Foreground="{./Foreground}" Font="{./Font}" Width="Stretched" Margin="2" + Text="{²./Value}" TextAlignment="Right" Background="Jet" /> + <VerticalStack Width="16" Height="Stretched" Spacing="1" Margin="1"> + <Shape KeepProportions="false" Margin="0" Style="ArrowBut" Height="50%" MouseDown="./onUp" Size="10,10" Path="M 4.5,0.5 L 9.5,9.5 L 0.5,9.5 Z F"/> + <Shape KeepProportions="false" Margin="0" Style="ArrowBut" Height="50%" MouseDown="./onDown" Size="10,10" Path="M 0.5,0.5 L 9.5,0.5 L 4.5,9.5 Z F"/> + </VerticalStack> + </HorizontalStack> + <Slider Background="Onyx" Foreground="Grey" Height="6" Value="{²./Value}" Minimum="{./Minimum}" Maximum="{./Maximum}" + Width = "Stretched" + MouseEnter="{Foreground=${ControlHighlight}}" + MouseLeave="{Foreground=Grey}" /> + </VerticalStack> +</Border> |