]> O.S.I.I.S - jp/crow.git/commitdiff
enumSelector for bitfields, CommandBase abstract class, numericControl onUp/down...
authorJean-Philippe Bruyère <jp_bruyere@hotmail.com>
Mon, 29 Mar 2021 10:18:38 +0000 (12:18 +0200)
committerJean-Philippe Bruyère <jp_bruyere@hotmail.com>
Mon, 29 Mar 2021 10:18:38 +0000 (12:18 +0200)
25 files changed:
Crow/Default.style
Crow/Templates/NumericControl.template [new file with mode: 0644]
Crow/Templates/TabView.template
Crow/src/Command.cs
Crow/src/Widgets/Button.cs
Crow/src/Widgets/CheckBox.cs
Crow/src/Widgets/DockStack.cs
Crow/src/Widgets/DockWindow.cs
Crow/src/Widgets/EnumSelector.cs
Crow/src/Widgets/Expandable.cs
Crow/src/Widgets/GenericStack.cs
Crow/src/Widgets/MenuItem.cs
Crow/src/Widgets/NumericControl.cs
Crow/src/Widgets/Slider.cs
Crow/src/Widgets/Spinner.cs
Crow/src/Widgets/TemplatedGroup.cs
Samples/BasicTests/BasicTests.cs
Samples/ShowCase/ShowCase.cs
Samples/ShowCase/ui/DebugLog.crow [new file with mode: 0644]
Samples/ShowCase/ui/ShowCase.style
Samples/ShowCase/ui/showcase.crow
Samples/common/SampleBase.cs
Samples/common/ui/Interfaces/Experimental/menu.crow [new file with mode: 0644]
Samples/common/ui/Interfaces/Experimental/spinner.crow [new file with mode: 0644]
Samples/common/ui/Interfaces/Experimental/tabviewTest.crow

index 0e442eb61c01b290ba5afc9d370206e7ab6e1017..9833be47892d43ffeb17ac52448191002547e50a 100644 (file)
@@ -1,11 +1,12 @@
 ControlBackground = "Transparent";
+ControlForeground = "Grey";
+ControlHighlight = "RoyalBlue";
 ControlBorderColor = "DimGrey";
 ControlBorderWidth = "1";
-ControlCaptionColor = "LightGrey";
 ControlCaptionHoverColor = "White";
 ControlCornerRadius = "0";
 ControlInsideMargin = "1";
-ControlHighlight = "RoyalBlue";
+
 IconSize = "11";
 IconMargin = "1";
 ToggleIconSize = "16";
@@ -47,12 +48,12 @@ ControlBorder {
        Margin = "${ControlInsideMargin}";
 }
 ControlCaption {
-       Foreground  = "${ControlCaptionColor}";
+       Foreground  = "${ControlForeground}";
        MouseEnter      = "{Foreground=${ControlCaptionHoverColor}}";
-       MouseLeave      = "{Foreground=${ControlCaptionColor}}";
+       MouseLeave      = "{Foreground=${ControlForeground}}";
 }
 ControlEditableText {
-       Foreground      = "${ControlCaptionColor}";
+       Foreground      = "${ControlForeground}";
        Background      = "Transparent";
        MinimumSize     = "40,10";
        Margin          = "1";
@@ -104,7 +105,7 @@ MenuItem {
        Width = "Stretched";
        Height = "Fit";
        Background = "${MenuBackground}";       
-       Foreground = "${ControlCaptionColor}";
+       Foreground = "${ControlForeground}";
        MouseEnter = "{Background=${ControlHighlight}}";
        MouseLeave = "{Background=${MenuBackground}}";
        //SelectionBackground = "${ControlHighlight}";
@@ -238,16 +239,12 @@ CheckBoxAlt {
 }
 
 ArrowBut {
-       MouseRepeat="true";     
-       //Focusable="true";
+       MouseRepeat="true";             
        
        Foreground="Grey";
        Background="Transparent";
-       
-       //MouseUp="{Background=Transparent}";
-       //MouseDown="{Background=Grey}";
-       
-       MouseEnter="{Foreground=CornflowerBlue}";
+               
+       MouseEnter="{Foreground=${ControlHighlight}}";
        MouseLeave="{Foreground=Grey}";
        
        Margin="2";
diff --git a/Crow/Templates/NumericControl.template b/Crow/Templates/NumericControl.template
new file mode 100644 (file)
index 0000000..b3d87f8
--- /dev/null
@@ -0,0 +1,11 @@
+<?xml version="1.0"?>
+<Border Style="ControlBorder" Background="{./Background}" CornerRadius="{./CornerRadius}">
+       <HorizontalStack Spacing="1">
+               <TextBox Style="ControlEditableText" Foreground="{./Foreground}" Font="{./Font}" Width="Stretched"
+                       Text="{²./Value}" TextAlignment="Right" />
+               <VerticalStack Width="16" Height="Stretched" Spacing="0" Margin="0">
+                       <Shape KeepProportions="false" Margin="1" 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="1" 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>
+</Border>
\ No newline at end of file
index af4eae07a40352a220337c7f23d056462c880913..cfe1a701189bd09b4081e5c0abf22d8141cfa615 100644 (file)
@@ -1,6 +1,6 @@
 <?xml version="1.0"?>
 <VerticalStack Spacing="0" > 
-       <ListBox Data="{./Items}" Fit="true" HorizontalAlignment="Left" VerticalAlignment="Top"> 
+       <ListBox Data="{./Items}" Fit="true" HorizontalAlignment="Left" VerticalAlignment="Top" SelectedItem="{²./SelectedItem}"
                <Template>
                        <HorizontalStack Name="ItemsContainer" Background="{./Background}" />
                </Template>
@@ -12,6 +12,6 @@
                        </ListItem>
                </ItemTemplate>
        </ListBox>
-       <Group Name="ItemsContainer" Background="Grey" Margin="10"/>
+       <Group Name="ItemsContainer" Background="Grey"/>
 </VerticalStack>
 
index 6c225030c18ad2151ba23484930588100a961e9f..34d48c4f1696ce3c5d14c52366ac02d83a913817 100644 (file)
@@ -1,23 +1,40 @@
-// Copyright (c) 2013-2020  Jean-Philippe Bruyère <jp_bruyere@hotmail.com>
+using System.Runtime.InteropServices.ComTypes;
+// Copyright (c) 2013-2020  Jean-Philippe Bruyère <jp_bruyere@hotmail.com>
 //
 // This code is licensed under the MIT license (MIT) (http://opensource.org/licenses/MIT)
 
 using System;
 using System.ComponentModel;
 using System.Threading.Tasks;
+using System.Collections;
 
 namespace Crow {
-       public class CommandGroup : ObservableList<Command>, IValueChange
-       {
-               string caption;
-               string icon;
+       public abstract class CommandBase : 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
+               
+               #region CTOR
+               protected CommandBase() {}
+               protected CommandBase (string _caption, string _icon)
+               {
+                       caption = _caption;                     
+                       icon = _icon;
+               }
+               #endregion
+               
+               string caption, icon;
 
                /// <summary>
                /// label to display in the bound control
                /// </summary>
-               [DefaultValue ("Unamed Command Group")]
+               [DefaultValue("Unamed Command")]
                public virtual string Caption {
-                       get { return caption; }
+                       get => caption;
                        set {
                                if (caption == value)
                                        return;
@@ -30,7 +47,7 @@ namespace Crow {
                /// Icon to display in the bound control
                /// </summary>          
                public string Icon {
-                       get { return icon; }
+                       get => icon;
                        set {
                                if (icon == value)
                                        return;
@@ -38,26 +55,33 @@ namespace Crow {
                                NotifyValueChanged ("Icon", icon);
                        }
                }
+               internal virtual void raiseAllValuesChanged() {         
+                       NotifyValueChanged ("Icon", icon);
+                       NotifyValueChanged ("Caption", caption);
+               }
+       }
+       public class CommandGroup : CommandBase, IEnumerable
+       {
+               public ObservableList<CommandBase> Commands = new ObservableList<CommandBase>();
 
                public CommandGroup () { }
-               public CommandGroup (params Command[] commands) {
-                       AddRange (commands);
+               public CommandGroup (string caption, string icon, params CommandBase[] commands) :
+                       base (caption, icon) {
+                       Commands.AddRange (commands);
                }
+               public CommandGroup (params CommandBase[] commands) {
+                       Commands.AddRange (commands);
+               }
+
+               public IEnumerator GetEnumerator() => Commands.GetEnumerator ();
        }
 
 
        /// <summary>
        /// helper class to bind in one step icon, caption, action, and validity tests to a controls 
        /// </summary>
-       public class Command : IValueChange
+       public class Command : CommandBase
        {
-               #region IValueChange implementation
-               public event EventHandler<ValueChangeEventArgs> ValueChanged;
-               public virtual void NotifyValueChanged(string MemberName, object _value)
-               {
-                       ValueChanged.Raise(this, new ValueChangeEventArgs(MemberName, _value));
-               }
-               #endregion
 
                #region CTOR
                public Command () {}
@@ -69,15 +93,18 @@ namespace Crow {
                {
                        execute = _executeAction;
                }
+               public Command (string caption, Action executeAction, string icon = null, bool _canExecute = true)
+                       :base (caption, icon)
+               {                                       
+                       execute = executeAction;
+                       canExecute = _canExecute;
+               }
+               
                #endregion
 
-               Action execute;
-
-               string caption;
-               string icon;
+               Action execute;         
                bool canExecute = true;
-
-               #region Public properties
+               
                /// <summary>
                /// if true, action defined in this command may be executed,
                /// </summary>
@@ -90,50 +117,21 @@ namespace Crow {
                                canExecute = value;
                                NotifyValueChanged ("CanExecute", canExecute);
                        }
-               }
-
-               /// <summary>
-               /// label to display in the bound control
-               /// </summary>
-               [DefaultValue("Unamed Command")]
-               public virtual string Caption {
-                       get { return caption; }
-                       set {
-                               if (caption == value)
-                                       return;
-                               caption = value;
-                               NotifyValueChanged ("Caption", caption);
-
-                       }
-               }
-               /// <summary>
-               /// Icon to display in the bound control
-               /// </summary>          
-               public string Icon {
-                       get { return icon; }
-                       set {
-                               if (icon == value)
-                                       return;
-                               icon = value;
-                               NotifyValueChanged ("Icon", icon);
-                       }
-               }
-               #endregion
+               }               
 
                /// <summary>
                /// trigger the execution of the command
                /// </summary>
-               public void Execute(){
+               public virtual void Execute(){
                        if (execute != null && CanExecute){
                                Task task = new Task(execute);
                                task.Start();
                        }
                }
-               internal void raiseAllValuesChanged(){
+               internal override void raiseAllValuesChanged()
+               {
+                       base.raiseAllValuesChanged();
                        NotifyValueChanged ("CanExecute", CanExecute);
-                       NotifyValueChanged ("Icon", icon);
-                       NotifyValueChanged ("Caption", caption);
                }
-
        }
 }
index b7b9326b97475fd19a1ce267dd55cc4ec955f6cb..35dcee00a7354ee78673dd759f68863002a1f335 100644 (file)
@@ -41,7 +41,7 @@ namespace Crow
 
                [DefaultValue (null)]
                public virtual Command Command {
-                       get { return command; }
+                       get => command;
                        set {
                                if (command == value)
                                        return;
@@ -64,7 +64,7 @@ namespace Crow
 
                [DefaultValue ("#Crow.Icons.crow.svg")]
                public string Icon {
-                       get { return Command == null ? icon : Command.Icon; ; }
+                       get => Command == null ? icon : Command.Icon;
                        set {
                                if (icon == value)
                                        return;
@@ -74,19 +74,19 @@ namespace Crow
                        }
                }
                public override bool IsEnabled {
-                       get { return Command == null ? base.IsEnabled : Command.CanExecute; }
-                       set { base.IsEnabled = value; }
+                       get => Command == null ? base.IsEnabled : Command.CanExecute;
+                       set => base.IsEnabled = value;
                }
 
                public override string Caption {
-                       get { return Command == null ? base.Caption : Command.Caption; }
-                       set { base.Caption = value; }
+                       get => Command == null ? base.Caption : Command.Caption;
+                       set => base.Caption = value;
                }
 
                [DefaultValue (false)]
                public bool IsPressed
                {
-                       get { return isPressed; }
+                       get => isPressed;
                        set
                        {
                                if (isPressed == value)
index cd0297f7a728d07c38151f80fb1e859309894175..ccd1ee756f62aa163d2638c77e89d7af24ce4e0a 100644 (file)
@@ -26,7 +26,7 @@ namespace Crow
                [DefaultValue(false)]
                public bool IsChecked
                {
-                       get { return isChecked; }
+                       get => isChecked;
                        set
                        {
                                if (isChecked == value)
index 5645e3745019f22072d701f6735c0c51cd911e2a..b5c05ecef7341b745db17ff02c48164c1414f7a1 100644 (file)
@@ -397,6 +397,7 @@ namespace Crow
                                        dw.DockingPosition = FastEnum.Parse<Alignment> (getConfAttrib (conf, ref i));
                                        dw.savedSlot = Rectangle.Parse (getConfAttrib (conf, ref i));
                                        dw.wasResizable = Boolean.Parse (getConfAttrib (conf, ref i));
+                                       dw.Resizable = false;
 
                                        dw.IsDocked = true;
                                        dw.DataSource = dataSource;
index 72a22a75631ad7aaeb0014500f91f96141269a72..200f2f12fb74e83128a37ef29002fd099a129581 100644 (file)
@@ -1,4 +1,4 @@
-// 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)
 
index 7e0fd476593a20dc29677a34d2fde99c02b1cff1..c30c79a42bb22a0c64b5b34a9adec6f68942ce35 100644 (file)
@@ -1,4 +1,6 @@
-// Copyright (c) 2019  Bruyère Jean-Philippe jp_bruyere@hotmail.com
+using System.Linq;
+using System.Xml.Linq;
+// Copyright (c) 2019  Bruyère Jean-Philippe jp_bruyere@hotmail.com
 //
 // This code is licensed under the MIT license (MIT) (http://opensource.org/licenses/MIT)
 
@@ -36,8 +38,8 @@ namespace Crow
                #region private fields
                Enum enumValue;
                Type enumType;
-               string rbStyle, iconsPrefix, iconsExtension;
-               IML.Instantiator radioButtonITor;
+               bool enumTypeIsBitsfield;
+               string rbStyle, iconsPrefix, iconsExtension;            
                #endregion
 
                #region public properties
@@ -73,8 +75,7 @@ namespace Crow
                        set {
                                if (rbStyle == value)
                                        return;
-                               rbStyle = value;
-                               radioButtonITor = null;
+                               rbStyle = value;                                
                                forceRefresh ();
                                NotifyValueChangedAuto (rbStyle);
                        }
@@ -84,36 +85,91 @@ namespace Crow
                /// </summary>
                [DefaultValue(null)]
                public virtual Enum EnumValue {
-                       get { return enumValue; }
+                       get => enumValue;
                        set {
                                if (enumValue == value)
                                        return;
 
-                               enumValue = value;
-                               if (radioButtonITor == null)
-                                       radioButtonITor = IFace.CreateITorFromIMLFragment ($"<RadioButton Style='{rbStyle}'/>");
+                               enumValue = value;                                                                      
 
                                if (enumValue != null) {
+
                                        if (enumType != enumValue.GetType ()) {
                                                enumValueContainer.ClearChildren ();
-                                               enumType = enumValue.GetType ();
-                                               foreach (string en in enumType.GetEnumNames ()) {
-
-                                                       RadioButton rb = radioButtonITor.CreateInstance<RadioButton> ();
-                                                       rb.Caption = en;
-                                                       rb.LogicalParent = this;
-                                                       rb.Tag = $"{iconsPrefix}{en}{IconsExtension}";
-                                                       if (enumValue.ToString () == en)
-                                                               rb.IsChecked = true;
-                                                       rb.Checked += (sender, e) => (((RadioButton)sender).LogicalParent as EnumSelector).EnumValue = (Enum)Enum.Parse (enumType, (sender as RadioButton).Caption);
-                                                       enumValueContainer.AddChild (rb);
+                                               enumType = enumValue.GetType ();                                                
+                                                                                               
+                                               enumTypeIsBitsfield = enumType.CustomAttributes.Any (ca => ca.AttributeType == typeof(FlagsAttribute));
+
+                                               if (enumTypeIsBitsfield) {
+                                                       IML.Instantiator iTor = IFace.CreateITorFromIMLFragment ($"<CheckBox Style='{rbStyle}'/>");
+                                                       UInt32 currentValue = Convert.ToUInt32 (EnumValue);
+
+                                                       foreach (Enum en in enumType.GetEnumValues()) {
+                                                               CheckBox rb = iTor.CreateInstance<CheckBox> ();
+                                                               rb.Caption = en.ToString();
+                                                               rb.LogicalParent = this;
+                                                               rb.Tag = $"{iconsPrefix}{en}{IconsExtension}";
+
+                                                               UInt32 eni = Convert.ToUInt32 (en);
+                                                               rb.Tooltip = $"0x{eni:x8}";
+                                                               if (eni == 0) {
+                                                                       rb.IsChecked = currentValue == 0;
+                                                                       rb.Checked += (sender, e) => EnumValue = (Enum)Enum.ToObject(enumType, 0);                                                                              
+                                                               } else {                                                                
+                                                                       rb.IsChecked = currentValue == 0 ? false : EnumValue.HasFlag (en);
+                                                                       rb.Checked += onChecked;
+                                                                       rb.Unchecked += onUnchecked;
+                                                               }
+                                                               /*rb.Checked += (sender, e) => (((CheckBox)sender).LogicalParent as EnumSelector).EnumValue = (Enum)(object)
+                                                                                       (Convert.ToUInt32 ((((CheckBox)sender).LogicalParent as EnumSelector).EnumValue) | Convert.ToUInt32 (en));                                              
+                                                               rb.Unchecked += (sender, e) => (((CheckBox)sender).LogicalParent as EnumSelector).EnumValue = (Enum)(object)
+                                                                                       (Convert.ToUInt32 ((((CheckBox)sender).LogicalParent as EnumSelector).EnumValue) & ~Convert.ToUInt32 (en));                                             */
+
+                                                               enumValueContainer.AddChild (rb);
+                                                       }
+
+                                               } else {
+                                                       IML.Instantiator iTor = IFace.CreateITorFromIMLFragment ($"<RadioButton Style='{rbStyle}'/>");
+                                                       foreach (var en in enumType.GetEnumValues ()) {
+                                                               RadioButton rb = iTor.CreateInstance<RadioButton> ();
+                                                               rb.Caption = en.ToString();
+                                                               rb.LogicalParent = this;
+                                                               rb.Tag = $"{iconsPrefix}{en}{IconsExtension}";
+                                                               if (enumValue == en)
+                                                                       rb.IsChecked = true;                                                            
+                                                               rb.Checked += (sender, e) => (((RadioButton)sender).LogicalParent as EnumSelector).EnumValue = (Enum)en;
+                                                               enumValueContainer.AddChild (rb);
+                                                       }
                                                }
+                                                       
+
 
+                                       } else if (enumTypeIsBitsfield) {
+                                               UInt32 currentValue = Convert.ToUInt32 (EnumValue);
+                                               if (currentValue == 0) {
+                                                       foreach (CheckBox rb in enumValueContainer.Children) {
+                                                               Enum en = (Enum)Enum.Parse(enumType, rb.Caption);
+                                                               UInt32 eni = Convert.ToUInt32 (en);
+                                                               if (eni == 0)
+                                                                       rb.IsChecked = true;
+                                                               else
+                                                                       rb.IsChecked = false;
+                                                       }
+                                               } else {
+                                                       foreach (CheckBox rb in enumValueContainer.Children) {
+                                                               Enum en = (Enum)Enum.Parse(enumType, rb.Caption);
+                                                               UInt32 eni = Convert.ToUInt32 (en);
+                                                               if (eni == 0)
+                                                                       rb.IsChecked = false;
+                                                               else
+                                                                       rb.IsChecked = EnumValue.HasFlag (en);
+                                                       }
+                                               }
                                        } else {
                                                foreach (RadioButton rb in enumValueContainer.Children) {
                                                        if (rb.Caption == enumValue.ToString ())
                                                                rb.IsChecked = true;
-                                                       else if (rb.IsChecked)
+                                                       else
                                                                rb.IsChecked = false;
                                                }
                                        }
@@ -126,6 +182,19 @@ namespace Crow
                }
                #endregion
 
+               void onChecked (object sender, EventArgs e) {                   
+                       Enum en =(Enum)Enum.Parse (enumType, (sender as CheckBox).Caption);
+                       UInt32 newVal = Convert.ToUInt32 (en);
+                       if (newVal == 0)
+                               EnumValue = (Enum)Enum.ToObject(enumType, 0);                    
+                       else
+                               EnumValue = (Enum)Enum.ToObject(enumType, newVal | Convert.ToUInt32 (EnumValue));                        
+               }
+               void onUnchecked (object sender, EventArgs e) {                 
+                       Enum en =(Enum)Enum.Parse (enumType, (sender as CheckBox).Caption);
+                       EnumValue = (Enum)Enum.ToObject(enumType, Convert.ToUInt32 (EnumValue) & ~Convert.ToUInt32 (en));                        
+               }
+
                //force refresh to use new template if values are already displayed
                void forceRefresh ()
                {
index 4cb0a2b4c5c714692b80579b0f1b059550d69402..e656d7711eb672b582723594a3b1ce7b716dbe3c 100644 (file)
@@ -93,14 +93,14 @@ namespace Crow
                public virtual void onExpand(object sender, EventArgs e)
                {
                        if (_contentContainer != null)
-                               _contentContainer.Visible = true;
+                               _contentContainer.IsVisible = true;
 
                        Expand.Raise (this, e);
                }
                public virtual void onCollapse(object sender, EventArgs e)
                {
                        if (_contentContainer != null)
-                               _contentContainer.Visible = false;
+                               _contentContainer.IsVisible = false;
 
                        Collapse.Raise (this, e);
                }
index 44b871339744531e9563632ce8bebd8e5c619138..b2fbe650a3cf1ac9e06406d075ceff7c2d11d6a6 100644 (file)
@@ -56,7 +56,7 @@ namespace Crow {
                                layoutType &= (~LayoutingType.Y);
                }
                public override int measureRawSize (LayoutingType lt) {
-                       int totSpace = Math.Max (0, Spacing * (Children.Count (c => c.Visible) - 1));
+                       int totSpace = Math.Max (0, Spacing * (Children.Count (c => c.IsVisible) - 1));
                        if (lt == LayoutingType.Width) {
                                if (Orientation == Orientation.Horizontal)
                                        return contentSize.Width + totSpace + 2 * Margin;
@@ -69,14 +69,14 @@ namespace Crow {
                        int d = 0;
                        if (Orientation == Orientation.Horizontal) {
                                foreach (Widget c in Children) {
-                                       if (!c.Visible)
+                                       if (!c.IsVisible)
                                                continue;
                                        c.Slot.X = d;
                                        d += c.Slot.Width + Spacing;
                                }
                        } else {
                                foreach (Widget c in Children) {
-                                       if (!c.Visible)
+                                       if (!c.IsVisible)
                                                continue;
                                        c.Slot.Y = d;
                                        d += c.Slot.Height + Spacing;
index 62a00cb69f93f080cd270ea4253bc95e70ee8845..b9b9d1f31484b61d3f9cf2cf003260f087f65201 100644 (file)
@@ -64,17 +64,17 @@ namespace Crow
                }
                
                public override bool IsEnabled {
-                       get { return Command == null ? base.IsEnabled : Command.CanExecute; }
-                       set { base.IsEnabled = value; }
+                       get => Command == null ? base.IsEnabled : Command.CanExecute;
+                       set => base.IsEnabled = value;
                }
                
                public override string Caption {
-                       get { return Command == null ? base.Caption : Command.Caption; }
-                       set { base.Caption = value; }
+                       get => Command == null ? base.Caption : Command.Caption;
+                       set => base.Caption = value;
                }
                
                public string Icon {
-                       get { return Command == null ? icon : Command.Icon;; }
+                       get => Command == null ? icon : Command.Icon;
                        set {
                                if (icon == value)
                                        return;
@@ -85,7 +85,7 @@ namespace Crow
                }
                [DefaultValue("Fit")]
                public virtual Measure PopWidth {
-                       get { return popWidth; }
+                       get => popWidth;
                        set {
                                if (popWidth == value)
                                        return;
@@ -95,7 +95,7 @@ namespace Crow
                }
                [DefaultValue("Fit")]
                public virtual Measure PopHeight {
-                       get { return popHeight; }
+                       get => popHeight;
                        set {
                                if (popHeight == value)
                                        return;
@@ -121,8 +121,7 @@ namespace Crow
                protected virtual void onOpen (object sender, EventArgs e){
                        Open.Raise (this, null);
                }
-               protected virtual void onClose (object sender, EventArgs e){
-                       System.Diagnostics.Debug.WriteLine ("close: " + this.ToString());
+               protected virtual void onClose (object sender, EventArgs e){                    
                        Close.Raise (this, null);
                }
                public override bool MouseIsIn (Point m)
index 80c685878e5649d49956601124f4edcc4955effd..df8fa17d016de544adb0e60a72979f59cac6bd45 100644 (file)
@@ -23,7 +23,7 @@ namespace Crow {
                [DefaultValue(2)]
                public int Decimals
                {
-                       get { return decimals; }
+                       get => decimals;
                        set
                        {
                                if (value == decimals)
@@ -35,7 +35,7 @@ namespace Crow {
                }
                [DefaultValue(0.0)]
                public virtual double Minimum {
-                       get { return minValue; }
+                       get => minValue;
                        set {
                                if (minValue == value)
                                        return;
@@ -48,7 +48,7 @@ namespace Crow {
                [DefaultValue(100.0)]
                public virtual double Maximum
                {
-                       get { return maxValue; }
+                       get => maxValue;
                        set {
                                if (maxValue == value)
                                        return;
@@ -61,7 +61,7 @@ namespace Crow {
                [DefaultValue(1.0)]
                public virtual double SmallIncrement
                {
-                       get { return smallStep; }
+                       get => smallStep;
                        set {
                                if (smallStep == value)
                                        return;
@@ -74,7 +74,7 @@ namespace Crow {
                [DefaultValue(5.0)]
                public virtual double LargeIncrement
                {
-                       get { return bigStep; }
+                       get => bigStep;
                        set {
                                if (bigStep == value)
                                        return;
@@ -87,7 +87,7 @@ namespace Crow {
                [DefaultValue(0.0)]
                public virtual double Value
                {
-                       get { return actualValue; }
+                       get => actualValue;
                        set
                        {
                                if (value == actualValue)
@@ -110,6 +110,21 @@ namespace Crow {
 
                protected virtual void registerUpdate ()
                        => RegisterForRedraw ();
+               
+               protected virtual void onUp (object sender, MouseButtonEventArgs e)
+               {
+                       if (IFace.Ctrl)
+                               Value += SmallIncrement;
+                       else
+                               Value += LargeIncrement;
+               }
+               protected virtual void onDown (object sender, MouseButtonEventArgs e)
+               {
+                       if (IFace.Ctrl)
+                               Value -= SmallIncrement;
+                       else
+                               Value -= LargeIncrement;
+               }
        }
 }
 
index 0d825526d6c8512f8a4a2a34dd6434cde640e7f0..b99fadfd1e8542b229f6e97625b4596cb79a38f8 100644 (file)
@@ -31,7 +31,7 @@ namespace Crow
                }
 
                protected virtual void HandleCursorContainerLayoutChanged (object sender, LayoutingEventArgs e)
-               {
+               {                       
                        computeCursorPosition ();
                }
                #endregion
@@ -119,13 +119,13 @@ namespace Crow
                }
                void computeCursorPosition ()
         {
-                       if (cursor == null)
+                       if (cursor?.Parent == null)
                                return;
                        if (Maximum <= Minimum) {
-                               cursor.Visible = false;
+                               cursor.IsVisible = false;
                                return;
                        }
-                       cursor.Visible = true;
+                       cursor.IsVisible = true;
             Rectangle r = cursor.Parent.ClientRectangle;
                        if (_orientation == Orientation.Horizontal) {
                                unity = (r.Width - cursorSize) / (Maximum - Minimum);
index 8126f8d5c8957206e4452fad5f282a339676829a..fdff9ac8430e837ef52cc545b5bcd9b05127b146 100644 (file)
@@ -14,27 +14,6 @@ namespace Crow
                protected Spinner() {}
                public Spinner (Interface iface, string style = null) : base (iface, style) { }
                #endregion
-
-               public override void onMouseClick (object sender, MouseButtonEventArgs e)
-               {
-                       e.Handled = true;
-                       base.onMouseClick (sender, e);
-               }
-               void onUp (object sender, MouseButtonEventArgs e)
-               {
-                       if (IFace.Ctrl)
-                               Value += SmallIncrement;
-                       else
-                               Value += LargeIncrement;
-               }
-               void onDown (object sender, MouseButtonEventArgs e)
-               {
-                       if (IFace.Ctrl)
-                               Value -= SmallIncrement;
-                       else
-                               Value -= LargeIncrement;
-               }
-
        }
 }
 
index cfa6cd1c8e1bbf37678e035bef8fdcbbbdd6d939..37d560f339dc5e66e0d2dbcad7984874b1a7708a 100644 (file)
@@ -483,6 +483,8 @@ namespace Crow {
                //void expandable_expandevent (object sender, EventHandler )
                void Li_Selected (object sender, EventArgs e)
                {
+                       if (sender == selectedItemContainer)
+                               return;
                        if (selectedItemContainer is ISelectable li)
                                li.IsSelected = false;
                        selectedItemContainer = sender as Widget;
index dcf38db412f22d4a3a3d91361199a53cc8ce9dba..656c05a37e7727dc3dedb17fa8a05feec552a44d 100644 (file)
@@ -19,10 +19,10 @@ namespace tests
                protected override void OnInitialized ()
                {
                        Commands = new List<Crow.Command> (new Crow.Command [] {
-                               new Crow.Command(new Action(() => command1())) { Caption = "command1"},
-                               new Crow.Command(new Action(() => command2())) { Caption = "command2"},
-                               new Crow.Command(new Action(() => command3())) { Caption = "command3"},
-                               new Crow.Command(new Action(() => command4())) { Caption = "command4"},
+                               new Crow.Command("command1", new Action(() => Console.WriteLine ("command1 triggered"))),
+                               new Crow.Command("command2", new Action(() => Console.WriteLine ("command2 triggered"))),
+                               new Crow.Command("command3", new Action(() => Console.WriteLine ("command3 triggered"))),
+                               new Crow.Command("command4", new Action(() => Console.WriteLine ("command4 triggered"))),
                        });
 
                        // += KeyboardKeyDown1;
@@ -103,21 +103,5 @@ namespace tests
                void OnLoadList (object sender, MouseButtonEventArgs e) => TestList =
                        null; //Color.ColorDic.Values.OrderBy (c => c.Hue).ToList ();
 
-               void command1 ()
-               {
-                       Console.WriteLine ("command1 triggered");
-               }
-               void command2 ()
-               {
-                       Console.WriteLine ("command2 triggered");
-               }
-               void command3 ()
-               {
-                       Console.WriteLine ("command3 triggered");
-               }
-               void command4 ()
-               {
-                       Console.WriteLine ("command4 triggered");
-               }
        }
 }
index 0628695fbdd252eaaad244d93cc95287cbc58254..699e84ff10e53fac1c2a5a0035243bc612e2c03f 100644 (file)
@@ -20,8 +20,9 @@ namespace ShowCase
        {
                static void Main ()
                {
-                       DbgLogger.IncludeEvents = DbgEvtType.Widget;
-                       DbgLogger.DiscardEvents = DbgEvtType.Focus | DbgEvtType.IFace;                  
+                       DbgLogger.IncludeEvents = DbgEvtType.None;
+                       DbgLogger.DiscardEvents = DbgEvtType.Focus | DbgEvtType.IFace;  
+                       DbgLogger.ConsoleOutput = false;                
 
                        Environment.SetEnvironmentVariable ("FONTCONFIG_PATH", @"C:\Users\Jean-Philippe\source\vcpkg\installed\x64-windows\tools\fontconfig\fonts");
 
@@ -31,6 +32,7 @@ namespace ShowCase
                        }
                }
 
+
                public Container crowContainer;
 
                public string CurrentDir {
@@ -127,15 +129,15 @@ namespace ShowCase
                
                void initCommands ()
                {
-                       CMDNew = new Command (new Action (onNewFile)) { Caption = "New", Icon = "#Icons.blank-file.svg", CanExecute = true };                   
-                       CMDSave = new Command (new Action (onSave)) { Caption = "Save", Icon = "#Icons.save.svg", CanExecute = false };
-                       CMDSaveAs = new Command (new Action (onSaveAs)) { Caption = "Save As...", Icon = "#Icons.save.svg", CanExecute = true };
-                       CMDQuit = new Command (new Action (() => base.Quit ())) { Caption = "Quit", Icon = "#Icons.exit.svg", CanExecute = true };
-                       CMDUndo = new Command (new Action (undo)) { Caption = "Undo", Icon = "#Icons.undo.svg", CanExecute = false };
-                       CMDRedo = new Command (new Action (redo)) { Caption = "Redo", Icon = "#Icons.redo.svg", CanExecute = false };
-                       CMDCut = new Command (new Action (() => cut ())) { Caption = "Cut", Icon = "#Icons.scissors.svg", CanExecute = false };
-                       CMDCopy = new Command (new Action (() => copy ())) { Caption = "Copy", Icon = "#Icons.copy-file.svg", CanExecute = false };
-                       CMDPaste = new Command (new Action (() => paste ())) { Caption = "Paste", Icon = "#Icons.paste-on-document.svg", CanExecute = false };
+                       CMDNew  = new Command ("New", new Action (onNewFile), "#Icons.blank-file.svg");                 
+                       CMDSave = new Command ("Save", new Action (onSave), "#Icons.save.svg", false);
+                       CMDSaveAs = new Command ("Save As...", new Action (onSaveAs), "#Icons.save.svg");
+                       CMDQuit = new Command ("Quit", new Action (() => base.Quit ()), "#Icons.exit.svg");
+                       CMDUndo = new Command ("Undo", new Action (undo),"#Icons.undo.svg", false);
+                       CMDRedo = new Command ("Redo", new Action (redo),"#Icons.redo.svg", false);
+                       CMDCut  = new Command ("Cut", new Action (() => cut ()), "#Icons.scissors.svg", false);
+                       CMDCopy = new Command ("Copy", new Action (() => copy ()), "#Icons.copy-file.svg", false);
+                       CMDPaste= new Command ("Paste", new Action (() => paste ()), "#Icons.paste-on-document.svg", false);
 
                }
                void onNewFile () {
@@ -345,5 +347,48 @@ namespace ShowCase
                        reloadChrono.Reset ();
                }
 
+               DbgEvtType recordedEvents, discardedEvents;
+               public DbgEvtType RecordedEvents {
+                       get => recordedEvents;
+                       set {
+                               if (recordedEvents == value)
+                                       return;
+                               recordedEvents = value;
+                               NotifyValueChanged(recordedEvents);
+                       }
+               }
+               public DbgEvtType DiscardedEvents {
+                       get => discardedEvents;
+                       set {
+                               if (discardedEvents == value)
+                                       return;
+                               discardedEvents = value;
+                               NotifyValueChanged(discardedEvents);
+                       }
+               }
+               
+        public override bool OnKeyDown (Key key) {
+
+            switch (key) {
+            case Key.F5:
+                Load ("#ShowCase.DebugLog.crow").DataSource = this;
+                return true;
+            case Key.F6:
+                               if (DbgLogger.IncludeEvents == recordedEvents) {
+                                       DbgLogger.IncludeEvents = DbgEvtType.None;
+                                       DbgLogger.DiscardEvents = DbgEvtType.All;
+                               } else {
+                                       DbgLogger.IncludeEvents = recordedEvents;
+                                       DbgLogger.DiscardEvents = discardedEvents;
+                               }
+                return true;
+            case Key.F2:
+                if (IsKeyDown (Key.LeftShift))
+                    DbgLogger.Reset ();
+                DbgLogger.Save (this);
+                return true;
+            }
+            return base.OnKeyDown (key);
+        }
     }
 }
\ No newline at end of file
diff --git a/Samples/ShowCase/ui/DebugLog.crow b/Samples/ShowCase/ui/DebugLog.crow
new file mode 100644 (file)
index 0000000..db9528b
--- /dev/null
@@ -0,0 +1,5 @@
+<?xml version="1.0"?>
+<Window Caption="Debug Log"  Background="0.1,0.1,0.1,0.8">
+       <ListBox Data="{DebugEvents}">
+       </ListBox>
+</Window>
\ No newline at end of file
index 0d688507dcb292d7f904a4769a92ce9b4e31a9e2..ce7572ab7e83815fe5cedc7189948956bd4d1254 100644 (file)
@@ -1,4 +1,7 @@
 IcoButton {
        Template = "#ShowCase.Button.template";
        Background = "Onyx";
+}
+CheckBox2 {
+       Width = "200";
 }
\ No newline at end of file
index 3d589b3db20fc9dfec6c6e3fb0de9077a2857c32..c1ecbaac0e5ebb1f52429c44535f9c7f01235270 100644 (file)
                                <Button Style="IcoButton" Command="{CMDNew}" />
                                <Button Style="IcoButton" Command="{CMDSave}" />
                                <Button Style="IcoButton" Command="{CMDSaveAs}" />
-                               <Button Style="IcoButton" Command="{CMDUndo}" />
+                               <!--<Button Style="IcoButton" Command="{CMDUndo}" />
                                <Button Style="IcoButton" Command="{CMDRedo}" />
                                <Button Style="IcoButton" Command="{CMDCut}" />
                                <Button Style="IcoButton" Command="{CMDCopy}" />
-                               <Button Style="IcoButton" Command="{CMDPaste}" />
+                               <Button Style="IcoButton" Command="{CMDPaste}" />-->
+                               <EnumSelector RadioButtonStyle="CheckBox2" Caption="Recorded Events" EnumValue="{²RecordedEvents}">
+                                       <Template>
+                                               <Popper Caption="{./Caption}">
+                                                       <Scroller Height="50%" Width="80%" Background="Jet">
+                                                               <Wrapper Name="Content" Height="Fit" VerticalAlignment="Top" />                                                 
+                                                       </Scroller>
+                                               </Popper>
+                                       </Template>
+                               </EnumSelector>
+                               <Label Text="{RecordedEvents}"/>
+                               <!--<EnumSelector EnumValue="{²DiscardedEvents}"/>-->
                                <Widget Width="Stretched"/>
                                <Label Text="Line:" Foreground="Grey"/>
                                <Label Text="{../../tb.CurrentLine}"  Margin="2"/>
index 71fb65f1c361aa24e12fde716f52175a2b3227de..79e018d0e87ba8fd564b90981f4d2e1d7e1fbd82 100644 (file)
@@ -35,7 +35,10 @@ namespace Crow
         public Version CrowVersion => Assembly.GetAssembly (typeof (Widget)).GetName ().Version;
 
         #region Test values for Binding
-        public List<Command> Commands;
+        public CommandGroup Commands;
+        public CommandGroup EditCommands = new CommandGroup(
+            new Command("command 1", () => Console.WriteLine("command1 pressed")));
+
         public int intValue = 500;
         VerticalAlignment currentVAlign;
 
@@ -262,14 +265,16 @@ namespace Crow
             }
         }
 
+
+
         #endregion
 
         protected override void OnInitialized () {
-            Commands = new List<Command> {
-                new Command(() => MessageBox.ShowModal(this, MessageBox.Type.Information, "context menu 1 clicked")) { Caption = "Action 1" },
-                new Command(() => MessageBox.ShowModal(this, MessageBox.Type.Information, "context menu 2 clicked")) { Caption = "Action 2" },
-                new Command(() => MessageBox.ShowModal(this, MessageBox.Type.Information, "context menu 3 clicked")) { Caption = "Action 3" }
-            };
+            Commands = new CommandGroup (
+                new Command("Action 1", () => MessageBox.ShowModal(this, MessageBox.Type.Information, "context menu 1 clicked")),
+                new Command("Action 2", () => MessageBox.ShowModal(this, MessageBox.Type.Information, "context menu 2 clicked")),
+                new Command("Action 3", () => MessageBox.ShowModal(this, MessageBox.Type.Information, "context menu 3 clicked"))
+            );
             base.OnInitialized ();
         }
 
diff --git a/Samples/common/ui/Interfaces/Experimental/menu.crow b/Samples/common/ui/Interfaces/Experimental/menu.crow
new file mode 100644 (file)
index 0000000..19db194
--- /dev/null
@@ -0,0 +1,3 @@
+<Menu>
+       <MenuItem Data="{EditsCommands}"/>
+</Menu>
\ No newline at end of file
diff --git a/Samples/common/ui/Interfaces/Experimental/spinner.crow b/Samples/common/ui/Interfaces/Experimental/spinner.crow
new file mode 100644 (file)
index 0000000..ac32e78
--- /dev/null
@@ -0,0 +1,21 @@
+<NumericControl Value="50" Height="Fit" Width="200" Background="DarkGrey">
+       <Template>
+               <Border Style="ControlBorder" Background="{./Background}" CornerRadius="{./CornerRadius}" Margin="0">
+                       <VerticalStack Spacing="0">
+
+                               <HorizontalStack Spacing="5">
+                                       <Label Text="{./Caption}" Style="ControlCaption" Margin="3"/>
+                                       <TextBox Style="ControlEditableText" Foreground="{./Foreground}" Font="{./Font}" Width="Stretched" Margin="3"
+                                               Text="{²./Value}" TextAlignment="Right" Background="Jet" />
+                                       <VerticalStack Width="16" Height="Stretched" Spacing="1" Margin="2">
+                                               <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="8" Value="{²./Value}"
+                                       MouseEnter="{Foreground=${ControlHighlight}}" 
+                                       MouseLeave="{Foreground=Grey}" />
+                       </VerticalStack>
+               </Border>
+       </Template>
+</NumericControl>
\ No newline at end of file
index f874a2c6e2c9b6f9b4f1480220c299d789be055f..b876ab7f6dd290a8d6f1aa15596570432b7c6791 100644 (file)
@@ -7,8 +7,9 @@
                                                <HorizontalStack Name="ItemsContainer" Background="{./Background}"/>
                                        </Template>
                                        <ItemTemplate>
-                                               <ListItem Width="Fit" Background="Transparent" IsSelected="{IsVisible}"
-                                                               Selected="{.DataSource.Visible='true'};{Background=CornflowerBlue}"
+                                               <ListItem Width="Fit" Background="Transparent" IsSelected="{²IsVisible}"
+                                                               Tooltip="{GetType}"
+                                                               Selected="{DataSource.Visible='true'};{Background=CornflowerBlue}"
                                                                Unselected="{.DataSource.Visible='false'};{Background=Transparent}"> 
                                                        <Label Text="{Caption}" Margin="5" />
                                                </ListItem>
                                <Group Name="ItemsContainer"/>
                        </VerticalStack>
                </Template>
-               <GroupBox Caption="item 1" IsVisible="false" Background="CornflowerBlue"/>
-               <GroupBox Caption="item 2" IsVisible="true" Background="CornflowerBlue"/>
+               <GroupBox Caption="item 1" IsVisible="true" Background="CornflowerBlue">
+                       <Label Text="{Caption}"/>
+               </GroupBox>
+               <GroupBox Caption="item 2" IsVisible="false" Background="CornflowerBlue"/>
                <GroupBox Caption="item 3" IsVisible="false" Background="CornflowerBlue"/>
        </ListBox>
        <Label DataSource="{../lb.SelectedItem}" Text="{Caption}"/>